List
是 java.util
包下的一个接口,它是 Java 集合框架中 Collection
接口的一个子接口,用于表示有序、可重复元素的集合。
以下是 List 集合的主要特点:
get(index)
用于获取指定索引处的元素,set(index, element)
用于替换指定索引处的元素,add(index, element)
用于在指定索引处插入元素。ArrayList
和 LinkedList
。
ArrayList
:基于动态数组实现,支持高效的随机访问(通过索引),但在插入和删除元素时(尤其是当插入或删除操作发生在列表中间时),可能会导致大量的元素移动,性能较低。LinkedList
:基于双向链表实现,插入和删除操作(尤其是在列表中间)的效率较高,但随机访问(通过索引)性能较差,因为它需要从头节点或者尾节点开始沿着链表遍历。ArrayList
和 LinkedList
默认是非线程安全的。如果需要线程安全的 List,可以使用 Collections.synchronizedList(List list)
方法对原 List 进行包装,或者使用 CopyOnWriteArrayList
类。List集合接口(java.util.List
)除了继承自java.util.Collection
接口的所有方法之外,还提供了一些特有的方法,用于处理有序且可重复元素的列表。
以下是List集合特有的一些方法及其详细讲解和代码示例:
void add(int index, E element)
:在此集合的指定位置插入一个元素。它会将指定位置之后的所有元素向后移动一位。// 创建一个 List 集合
List<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add(1,"Mango"); // 在索引1的位置插入"Mango"
System.out.println(list); // 输出: [Apple, Mango, Banana]
E get(int index)
:根据索引获取列表中的元素。// 创建一个 List 集合
List<String> list = new ArrayList<>(Arrays.asList("Apple", "Banana", "Mango", "Orange", "Pear"));
// 根据索引获取集合元素
System.out.println("索引为3的元素: "+list.get(3)); // 输出: 索引为3的元素: Orange
E set(int index, E element)
:替换列表中指定索引位置的元素。// 创建一个 List 集合
List<String> list = new ArrayList<>(Arrays.asList("Apple", "Banana", "Mango", "Orange", "Pear"));
// 设置索引1的元素为"Peach"
list.set(1,"Peach");
System.out.println(list); // 输出: [Apple, Peach, Mango, Orange, Pear]
E remove(int index)
:移除并返回列表中指定索引位置的元素。// 创建一个 List 集合
List<String> list = new ArrayList<>(Arrays.asList("Apple", "Banana", "Mango", "Orange", "Pear"));
// 移除指定索引的元素
String remove = list.remove(1);
System.out.println(remove); // 输出: Banana
System.out.println(list); // 输出: [Apple, Mango, Orange, Pear]
int indexOf(Object o)
:获取指定元素在列表中首次出现的索引,如果列表中不包含该元素则返回 -1
。// 创建一个 List 集合
List<String> list = new ArrayList<>(Arrays.asList("Apple", "Banana", "Mango", "Orange", "Pear"));
// 获取"Mango"在集合中的索引
int cherryIndex = list.indexOf("Mango");// 若列表不含"Mango",则输出-1
System.out.println(cherryIndex); // 输出:2
int lastIndexOf(Object o)
:获取指定元素在列表中最后一次出现的索引,如果列表中不包含该元素则返回 -1
。// 创建一个 List 集合
List<String> list = new ArrayList<>(Arrays.asList("Apple", "Banana", "Mango", "Orange", "Pear","Banana"));
// 获取"Banana"在集合中最后一次出现的索引
int cherryIndex = list.lastIndexOf("Banana");// 若集合中不含"Banana",则输出-1
System.out.println(cherryIndex); // 输出:5
List subList(int fromIndex, int toIndex)
:获取原列表的部分视图,而不是创建一个新的列表副本。这个方法返回一个新的 List
对象,它包含了原列表从 fromIndex
(包含)到 toIndex
(不包含)位置的元素。这里的索引遵循 Java 数组索引规则,即从 0 开始计数。
fromIndex
:起始索引,从0开始,包含此索引位置的元素。toIndex
:结束索引,不包含此索引位置的元素。List
视图。需要注意的是,这个返回的列表是原列表的一个动态视图,也就是说,当你修改原列表或子列表时,两者的内容都会相应地改变。// 创建一个 List 集合
List<String> list = new ArrayList<>(Arrays.asList("Apple", "Banana", "Mango", "Orange", "Pear","Banana"));
// 获取 list 集合从索引1到索引3的子列表
List<String> subList = list.subList(1, 4);
// 输出原列表
System.out.println("list: " + list);// list: [Apple, Banana, Mango, Orange, Pear, Banana]
// 输出子列表
System.out.println("subList: " + subList);// subList: [Banana, Mango, Orange]
List 集合的实现类主要包括以下几个:
java.util.Vector
是早期JDK版本中提供的线程安全的动态数组实现,其功能与ArrayList相似,但由于线程安全的开销,其性能略低于ArrayList。从Java 1.2版本开始,推荐使用Collections类的synchronizedList方法来创建线程安全的ArrayList替代Vector。java.util.Stack
类实际上是继承自 Vector,它提供栈(后进先出,LIFO)的特性,但现代Java编程实践中,通常建议使用 Deque
接口的实现类,如 ArrayDeque
来代替 Stack。java.util.ArrayList
是 Java 集合框架中 List 接口的一个重要实现类,它基于动态数组实现,允许高效地随机访问元素,并且可以自动调整数组大小以适应元素数量的变化。O(n)
。示例代码:
List<String> list = new ArrayList<>();
list.add("Apple");
list.add(0, "Banana"); // 在索引0处插入元素
String firstElement = list.get(0); // 获取第一个元素
java.util.LinkedList
是 Java 集合框架中 List
接口的一个实现类,它采用链表数据结构进行存储,允许元素的高效插入和删除操作。LinkedList
继承了 AbstractSequentialList
类,并实现了 Deque
, List
, Queue
, Cloneable
, Serializable
接口,因此它具备了很多额外的特有方法,这些方法主要与链表结构的特性相符,包括在链表首尾插入和删除元素,以及找到前驱和后继节点等。示例代码:
List<String> list = new LinkedList<>();
LinkedList
特有的方法在链表头部操作:
void addFirst(E e)
:在链表的开头添加元素。// 创建一个 LinkedList 集合
LinkedList<String> linkedList = new LinkedList<>();
// 在链表开头添加元素
linkedList.addFirst("Apple");
linkedList.addFirst("Banana");
System.out.println(linkedList);// 输出: [Banana, Apple]
void addLast(E e)
:在链表的末尾添加元素,这个方法虽然不是 LinkedList
独有的,但对于链表实现来说很有意义。// 创建一个 LinkedList 集合
LinkedList<String> list = new LinkedList<>();
// 在末尾添加元素
list.addLast("Apple");
list.addLast("Banana");
System.out.println(list); // 输出: [Apple, Banana]
E getFirst()
:返回链表的第一个元素,但不删除。// 创建一个 LinkedList 集合
LinkedList<String> list = new LinkedList<>(Arrays.asList("Apple", "Banana", "Mango", "Orange", "Pear","Banana"));
// 获取第一个元素
String first = list.getFirst();
System.out.println(first);// 输出: Apple
E getLast()
:返回链表的最后一个元素,但不删除。// 创建一个 LinkedList 集合
LinkedList<String> list = new LinkedList<>(Arrays.asList("Apple", "Banana", "Mango", "Orange", "Pear","Banana"));
// 获取最后一个元素
String last = list.getLast();
System.out.println(last);// 输出: Banana
E removeFirst()
:删除并返回链表的第一个元素。// 创建一个 LinkedList 集合
LinkedList<String> list = new LinkedList<>(Arrays.asList("Apple", "Banana", "Mango", "Orange", "Pear","Banana"));
// 删除并返回第一个元素
String removeFirst = list.removeFirst();
System.out.println(removeFirst); // 输出: Apple
System.out.println(list); // 输出: [Banana, Mango, Orange, Pear, Banana]
E removeLast()
:删除并返回链表的最后一个元素。// 创建一个 LinkedList 集合
LinkedList<String> list = new LinkedList<>(Arrays.asList("Apple", "Banana", "Mango", "Orange", "Pear","Banana"));
// 删除并返回最后一个元素
String removeLast = list.removeLast();
System.out.println(removeLast);// 输出: Banana
System.out.println(list); // 输出: [Apple, Banana, Mango, Orange, Pear]
与 Deque 接口兼容的方法:
void push(E e)
:将元素推入此列表的开头(相当于 addFirst(e)
,用法完全相同)。E pop()
:从此列表中移除并返回第一个元素(相当于 removeFirst()
,用法完全相同)。