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