Java LinkedList – Java中的LinkedList

时间:2020-02-23 14:36:32  来源:igfitidea点击:

Java LinkedList是List和Deque接口的实现。
它是常用的List实现类之一。

它扩展了AbstractSequentialList并实现了List和Deque接口。
它是一个有序的集合,并支持重复的元素。
它按插入顺序存储元素。
它支持添加空元素。
它支持基于索引的操作。

Java LinkedList

在本节中,我们将讨论有关Java LinkedList的一些要点:

  • Java LinkedList类是Java Collections Framework的成员。

  • 它是List和Deque接口的实现。

  • 在内部,它是使用双链表数据结构实现的。

  • 它支持重复元素。

  • 它按插入顺序存储或者维护其元素。

  • 我们可以添加任意数量的null元素。

  • 它没有同步,这意味着它不是线程安全的。

  • 我们可以使用Collections.synchronizedList()方法创建一个同步的LinkedList。

  • 在Java应用程序中,我们可以将其用作列表,堆栈或者队列。

  • 它没有实现RandomAccess接口。
    因此,我们只能按顺序访问元素。
    它不支持随机访问元素。

  • 当我们尝试从LinkedList访问元素时,根据该元素的可用位置从LinkedList的开头或者结尾开始搜索该元素。

  • 我们可以使用ListIterator来迭代LinkedList元素。

  • 从Java SE 8开始,我们可以将LinkedList转换为Stream,反之亦然。

  • Java SE 9将添加一些工厂方法来创建不可变的LinkedList。

Java LinkedList类图

众所周知,Java LinkedList是List实现类之一。
它还实现了双端队列。
如下面的类图中所示,它并不直接从AbstractList类扩展。
它扩展了AbstractSequentialList类。

Java LinkedList列表方法

在本节中,我们将讨论一些有用且经常使用的Java LinkedList方法。

以下方法是从List或者Collection接口继承的:

  • int size():获取列表中元素的数量。

  • boolean isEmpty():检查列表是否为空。

  • boolean contains(Object o):如果此列表包含指定的元素,则返回true。

  • Iterator iterator():按正确的顺序返回对该列表中的元素进行迭代的迭代器。

  • Object [] toArray():返回一个数组,其中包含此列表中所有元素的正确顺序。

  • boolean add(E e):将指定的元素追加到此列表的末尾。

  • boolean remove(Object o):从此列表中删除第一次出现的指定元素。

  • boolean keepAll(Collection c):仅保留此列表中指定集合中包含的元素。

  • void clear():从列表中删除所有元素。

  • E get(int index):返回列表中指定位置的元素。

  • E set(int index,E element):将列表中指定位置的元素替换为指定的元素。

  • ListIterator listIterator():返回列表中元素上的列表迭代器。

  • List subList(int fromIndex,int toIndex):返回此列表中指定的fromIndex(包括)和toIndex(不包括)之间的视图。
    返回列表由该列表支持,因此返回列表中的非结构性更改会反映在此列表中,反之亦然。

Java LinkedList双端队列方法

以下方法特定于从Deque接口继承的LinkedList类:

  • void addFirst(E e):在此列表的开头插入指定的元素。

  • addLast(E e):将指定的元素插入此列表的末尾。

  • E getFirst():检索但不删除此列表的第一个元素。
    此方法与peekFirst的不同之处仅在于,如果此列表为空,它将引发异常。

  • E getLast():检索但不删除此列表的最后一个元素。
    此方法与peekLast的不同之处仅在于,如果此列表为空,它将引发异常。

  • E remvoeFirst():从此列表中删除并返回第一个元素。

  • E removeLast():从列表中删除并返回最后一个元素。

  • boolean offerFirst(E e):将指定的元素插入此列表的前面。

  • boolean offerLast(E e):在此列表的末尾插入指定的元素。

  • E pollFirst():检索并删除此列表的第一个元素;如果此列表为空,则返回null。

  • E pollLast():检索并删除此列表的最后一个元素;如果此列表为空,则返回null。

  • E peekFirst():检索但不删除此列表的第一个元素,如果此列表为空,则返回null。

  • E peekLast():检索但不删除此列表的最后一个元素,如果此列表为空,则返回null。

Java LinkedList基本示例

在本节中,我们将讨论有关Java LinkedList的基本示例。
我们将在接下来的部分中探索一些更有用的操作。

例:

import java.util.LinkedList;
import java.util.List;

public class LinkedListDemo 
{
public static void main(String[] args) 
{
	List names = new LinkedList();
	names.add("Rams");
	names.add("Posa");
	names.add("Chinni");
      names.add(2011);
			
	System.out.println("LinkedList content: " + names);
	System.out.println("LinkedList size: " + names.size());
}
}

输出:

LinkedList content: [Rams, Posa, Chinni, 2011]
LinkedList size: 4

其中我们创建了一个LinkedList对象,并添加了4个项目。
正如我们所讨论的,LinkedList.size()方法用于获取列表中的元素数。

注意:-不使用泛型,Java LinkedList支持异构元素。
但是,不建议使用没有泛型的集合。
让我们通过一个简单的示例在下一部分中探讨Java泛型的优点和用法。

Java LinkedList泛型

在本节中,我们将讨论如何在Java LinkedList中使用泛型。
众所周知,Java泛型对于编写类型安全编程和在编译时进行更强的类型检查很有用。
它们对于消除铸造开销也很有用。

例:

import java.util.LinkedList;
import java.util.List;

public class LinkedListGenericsDemo
{
public static void main(String[] args) 
{
	List<String> names = new LinkedList<>();
	names.add("Rams");
	names.add("Posa");
	names.add("Chinni");
      //We cannot add other than Strings
      //names.add(2011);
			
	System.out.println("LinkedList content: " + names);
	System.out.println("LinkedList size: " + names.size());
}
}

输出:

LinkedList content: [Rams, Posa, Chinni]
LinkedList size: 3

其中我们使用泛型创建了一个LinkedList对象,并添加了3个项目。
当我们尝试为LinkedList添加一个Number时,它将引发编译时错误。

Java数组到LinkedList

在本节中,我们将探讨如何将Java数组转换为LinkedList对象。
我们可以通过多种方式来实现,但是在这里我只给出了一种方法。

例:

import java.util.LinkedList;
import java.util.List;

public class JavaArrayToLinkedListDemo 
{
	public static void main(String[] args) 
	{
		Integer[] numbers = {1,2,3,4,5};
		List<Integer> numbersList = new LinkedList<>();
		for(Integer s : numbers){
			numbersList.add(s);
		}
		System.out.println(numbersList);
	}
}

输出:

[1, 2, 3, 4, 5]

Java LinkedList到数组

在本节中,我们将探讨如何将Java LinkedList转换为数组。
我们可以通过多种方式来实现,但是在这里我只给出了一种方法。

例:

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

public class LinkedListToJavaArrayDemo 
{
	public static void main(String[] args) 
	{		
		List<Integer> numbersList = new LinkedList<>();
		numbersList.add(1);
		numbersList.add(2);
		numbersList.add(3);
		numbersList.add(4);
		numbersList.add(5);
		Integer[] numbers = new Integer[numbersList.size()];
		
		numbers = numbersList.toArray(numbers);
		System.out.println(Arrays.toString(numbers));

	}
}

输出:

[1, 2, 3, 4, 5]

Java LinkedList实时用例

在本节中,我们将讨论在Java应用程序中使用LinkedList的最佳情况和最坏情况。

最佳用例方案:

  • 当我们经常使用的操作是在List的中间添加或者删除元素时,LinkedList是最好的使用类。

为什么?因为我们不需要做更多的工作来在列表中间添加或者删除元素。
请参阅"如何在J Java LinkedList中插入?"部分以详细了解它。

最坏的用例场景:

  • 当我们经常使用的操作是从列表中检索元素时,LinkedList是最糟糕的选择。

为什么?由于LinkedList仅支持顺序访问,因此不支持随机访问。
请参阅"删除如何在J Java LinkedList中工作?"部分以详细了解它。

注意:-LinkedList实现列表,双端队列,可克隆和可序列化。
但是它没有实现RandomAccess接口。

Java LinkedList的内部表示

众所周知,内部Java LinkedList是使用双链表实现的。
因此,Java LinkedList将其元素表示为节点。
每个节点分为3部分,如下所示。

在此,每个节点都用于特定目的。

  • 左侧节点部分用于指向LinkedList中的上一个节点(或者元素)。

  • 右侧节点部分用于指向LinkedList中的下一个节点(或者元素)。

  • 中心节点部分用于存储实际数据。

注意:-在JVM中,LinkedList不会按连续顺序存储其元素。
它将元素存储在任何可用空间中,并通过左右节点部分将它们相互连接,如下图所示。

Java LinkedList中插入如何工作?

在上一节中,我们已经看到LinkedList如何将其元素存储为Nodes。
在本节中,我们将讨论Java LinkedList的插入操作如何在内部工作。

  • 让我们假设我们的初始LinkedList具有以下数据。

  • 在此LinkedList上执行以下插入操作

linkedList.add(2,54);

其中我们尝试执行插入操作以在索引2处添加值为" 54"的新元素。

  • 更新的LinkedList如下所示。

删除如何在Java LinkedList中工作?

在上一节中,我们已经看到LinkedList在内部执行插入操作的方式。
在本节中,我们将讨论Java LinkedList的Deletion操作在内部如何工作。

  • 让我们假设我们的初始LinkedList具有以下数据。

  • 在此LinkedList上执行以下插入操作

linkedList.remove(3);

其中我们尝试执行删除操作以删除索引3处可用的元素。

  • 更新的LinkedList如下所示。

Java LinkedList双端队列操作

其中我们将探讨LinkedList对象如何作为双端队列。
我们使用这些操作来实现队列或者堆栈。
在我的后续文章中,我们将深入讨论堆栈或者队列的工作方式。

例:

import java.util.LinkedList;
import java.util.LinkedList;
import java.util.Deque;

public class LinkedListDequeOperationsDemo 
{
public static void main(String[] args) 
{
	Deque names = new LinkedList();
	names.add(2);
	names.addFirst(1);
	names.addLast(3);
	names.addFirst(0);
	names.addLast(4);
			
	System.out.println("LinkedList content: " + names);
	System.out.println("LinkedList size: " + names.size());
	names.removeFirst();
	names.removeLast();
	
	System.out.println("LinkedList content: " + names);
	System.out.println("LinkedList size: " + names.size());	
}
}

输出:

LinkedList content: [0, 1, 2, 3, 4]
LinkedList size: 5
LinkedList content: [1, 2, 3]
LinkedList size: 3

Java SE 8:要发送的Java LinkedList

其中我们将探讨如何将LinkedList对象转换为Java SE 8 Stream概念。

例:

import java.util.LinkedList;
import java.util.List;

public class LinkedListToStreamDemo 
{
public static void main(String[] args) 
{		
	List<Integer> numbersList = new LinkedList<>();
	numbersList.add(1);
	numbersList.add(2);
	numbersList.add(3);
	numbersList.add(4);
	numbersList.add(5);
		
	//convert List to stream
	numbersList.stream().forEach(System.out::println);
}
}

输出:

1
2
3
4
5

Java SE 9链表

在Java SE 9中,Oracle Corp将添加一些有用的实用程序方法来创建不可变列表。