JAVA 集合框架(二) List集合详解和常用方法

Listjava.util 包下的一个接口,它是 Java 集合框架中 Collection 接口的一个子接口,用于表示有序、可重复元素的集合。

以下是 List 集合的主要特点:

  • 有序性:List 集合中的元素是有序的,这意味着元素的插入顺序决定了它们在集合中的位置。可以通过索引(index)访问集合中的元素,索引从零开始。
  • 可重复性:List 集合允许存储重复的元素,即同一个对象可以多次添加到 List 中。
  • 索引访问 :List 提供了类似于数组的索引访问方法,如 get(index) 用于获取指定索引处的元素,set(index, element) 用于替换指定索引处的元素,add(index, element) 用于在指定索引处插入元素。
  • 方法丰富:List 接口中定义了许多方法,如添加、删除、查找、替换、插入、迭代等操作。
  • 主要实现类 :Java 中有两个主要的 List 实现类,分别是 ArrayListLinkedList
    • ArrayList:基于动态数组实现,支持高效的随机访问(通过索引),但在插入和删除元素时(尤其是当插入或删除操作发生在列表中间时),可能会导致大量的元素移动,性能较低。
    • LinkedList:基于双向链表实现,插入和删除操作(尤其是在列表中间)的效率较高,但随机访问(通过索引)性能较差,因为它需要从头节点或者尾节点开始沿着链表遍历。
  • 线程安全性 :Java 标准库提供的 List 实现类如 ArrayListLinkedList 默认是非线程安全的。如果需要线程安全的 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(),用法完全相同)。
相关推荐
2401_8543910812 分钟前
城镇住房保障:SpringBoot系统功能概览
java·spring boot·后端
hummhumm13 分钟前
Oracle 第29章:Oracle数据库未来展望
java·开发语言·数据库·python·sql·oracle·database
wainyz23 分钟前
Java NIO操作
java·开发语言·nio
工业3D_大熊28 分钟前
【虚拟仿真】CEETRON SDK在船舶流体与结构仿真中的应用解读
java·python·科技·信息可视化·c#·制造·虚拟现实
lzb_kkk37 分钟前
【JavaEE】JUC的常见类
java·开发语言·java-ee
我不是李.杨1 小时前
Windows10/11开启卓越性能模式 windows开启卓越性能电源模式 工作电脑开启卓越性能模式 电脑开启性能模式
windows·电脑
爬山算法1 小时前
Maven(28)如何使用Maven进行依赖解析?
java·maven
2401_857439691 小时前
SpringBoot框架在资产管理中的应用
java·spring boot·后端
怀旧6661 小时前
spring boot 项目配置https服务
java·spring boot·后端·学习·个人开发·1024程序员节
李老头探索1 小时前
Java面试之Java中实现多线程有几种方法
java·开发语言·面试