Java集合List详解(带脑图)

允许重复元素,有序。常见的实现类有 ArrayListLinkedListVector

ArrayList

ArrayList 是在 Java 编程中常用的集合类之一,它提供了便捷的数组操作,并在动态性、灵活性和性能方面取得了平衡。如果需要频繁在中间插入和删除元素,或者需要在多线程环境中使用,可能需要考虑其他集合实现。

特点

1.动态大小: ArrayList 的大小是动态可变的,可以根据需要自动增加或缩小。这与 Vector 相似,但相对于 LinkedList,它的随机访问效率更高。

2.随机访问高效: 由于 ArrayList 基于动态数组实现,可以通过索引直接访问元素,因此在需要频繁随机访问元素的场景下,ArrayList 的性能通常优于 LinkedList

3.适用于大部分场景: 在大多数情况下,ArrayList 是一个通用、高效的集合类。它适用于存储和随机访问元素,但不适用于在中间或开头频繁插入和删除元素的情况。

4.非同步: ArrayList 不是线程安全的,不支持多线程并发操作。如果需要在多线程环境中使用,可以考虑使用 Vector(这个比较落后了,所以就不提了) 或使用 Collections.synchronizedList 方法包装 ArrayList

使用方法

首先先引用,然后初始化。

java 复制代码
import java.util.ArrayList;//引入ArrayList类

public class Test01 {
    ArrayList<String> objectName = new ArrayList<>();//初始化
}

objectName:对象名。

ArrayList<String>:这<>里面的是泛型数据类型,用于设置 objectName 的数据类型,只能为引用数据类型。

一点示范

java 复制代码
import java.util.ArrayList;//引入ArrayList类

public class Test01 {
    public static void main(String[] args) {
        ArrayList<String> objectName = new ArrayList<>();//初始化
        objectName.add("Changsha");//add()
        System.out.println(objectName);
        objectName.add("Shenyang");
        System.out.println(objectName);
        objectName.set(0,"Shanghai");//set()
        System.out.println(objectName);
        System.out.println(objectName.get(1));//get()
        objectName.remove(1);//remove()
        System.out.println(objectName);
    }
}

运行结果

用法表格

|----|---------------------------------------------------------------------------------------------------|------------------------------|
| 1 | add() | 将元素插入到指定位置的 arraylist 中 |
| 2 | addAll() | 添加集合中的所有元素到 arraylist 中 |
| 3 | clear() | 删除 arraylist 中的所有元素 |
| 4 | clone() | 复制一份 arraylist |
| 5 | contains() | 判断元素是否在 arraylist |
| 6 | get() | 通过索引值获取 arraylist 中的元素 |
| 7 | indexOf() | 返回 arraylist 中元素的索引值 |
| 8 | removeAll() | 删除存在于指定集合中的 arraylist 里的所有元素 |
| 9 | remove() | 删除 arraylist 里的单个元素 |
| 10 | size() | 返回 arraylist 里元素数量 |
| 11 | isEmpty() | 判断 arraylist 是否为空 |
| 12 | subList() | 截取部分 arraylist 的元素 |
| 13 | set() | 替换 arraylist 中指定索引的元素 |
| 14 | sort() | 对 arraylist 元素进行排序 |
| 15 | toArray() | 将 arraylist 转换为数组 |
| 16 | toString() | 将 arraylist 转换为字符串 |
| 17 | ensureCapacity() | 设置指定容量大小的 arraylist |
| 18 | lastIndexOf() | 返回指定元素在 arraylist 中最后一次出现的位置 |
| 19 | retainAll() | 保留 arraylist 中在指定集合中也存在的那些元素 |
| 20 | containsAll() | 查看 arraylist 是否包含指定集合中的所有元素 |
| 21 | trimToSize() | 将 arraylist 中的容量调整为数组中的元素个数 |
| 22 | removeRange() | 删除 arraylist 中指定索引之间存在的元素 |
| 23 | replaceAll() | 将给定的操作内容替换掉数组中每一个元素 |
| 24 | removeIf() | 删除所有满足特定条件的 arraylist 元素 |
| 25 | forEach() | 遍历 arraylist 中每一个元素并执行特定操作 |

LinkedList

特点

1.双向链表结构: 这是它与ArrayList最主要的差别, LinkedList 的底层数据结构是双向链表,每个节点都包含对前一个和后一个元素的引用。

2.动态大小: 类似于 ArrayListLinkedList 的大小也是动态可变的,可以根据需要自动增加或缩小。

3.插入和删除效率高: 由于链表结构,LinkedList 在中间插入和删除元素的操作比 ArrayList 效率更高。因此在任意位置插入或者删除元素时,不需要搬移元素,效率比较高。

4.非随机访问效率相对较低:ArrayList 不同,LinkedList 的随机访问效率相对较低。如果需要频繁随机访问元素,ArrayList 可能更适合。

5.迭代效率: 在迭代时,LinkedList 的性能较差。由于访问节点需要跳跃指针,相比于数组的连续存储,会增加迭代的开销。

6.占用更多内存: 由于每个节点都需要存储额外的引用,相对于 ArrayListLinkedList 在内存占用上可能会更多。

7.非同步: LinkedList 也不是线程安全的,不支持多线程并发操作。如果需要在多线程环境中使用,可以考虑使用 Collections.synchronizedList 方法包装 LinkedList

8.特定场景的优势: 在某些特定的场景中,如实现栈、队列或双端队列等数据结构时,LinkedList 可能更为适用。

使用方法

同样是引用和初始化

java 复制代码
import java.util.LinkedList;

public class Test01 {
    public static void main(String[] args) {
        LinkedList<String> linkedList = new LinkedList<>();
        
    }
}

linkedList:对象名

LinkedList<String>:这<>里面的是泛型数据类型,用于设置 linkedList的数据类型,只能为引用数据类型。

一些示范

java 复制代码
import java.util.LinkedList;

public class Test01 {
    public static void main(String[] args) {
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("Apple");
        linkedList.add("Banana");
        linkedList.add("Orange");
        System.out.println(linkedList);
// 在指定位置插入元素
        linkedList.add(1, "Grapes");
        System.out.println(linkedList);
        //获取链表中的元素:
        String element = linkedList.get(0);
        System.out.println(element);
        //更新链表中的元素
        linkedList.set(0, "NewElement");
        System.out.println(linkedList);
    }
}

运行结果

常见用法

|----|----------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------|
| 1 | linkedList.add("Element"); | 在链表末尾添加元素 |
| 2 | linkedList.add(index, "Element"); | 在指定位置插入元素 |
| 3 | linkedList.get(index); | 获取链表中的元素 |
| 4 | linkedList.set(index, "NewElement"); | 更新链表中的元素 |
| 5 | linkedList.remove(index); | 删除指定位置的元素 |
| 6 | int size = linkedList.size(); | 获取链表的大小 |
| 7 | linkedList.isEmpty(); | 判断链表是否为空 |
| 8 | linkedList.contains("Element"); | 查找元素是否存在 |
| 9 | linkedList.getFirst();linkedList.getLast(); | 获取第一个和最后一个元素 |
| 10 | linkedList.removeFirst(); linkedList.removeLast(); | 删除第一个和最后一个元素 |
| 11 | Iterator<String> iterator = linkedList.iterator(); while (iterator.hasNext()) { String element = iterator.next(); // 处理元素 } | 迭代器遍历链表 |
| 12 | ListIterator<String> iterator = linkedList.listIterator(linkedList.size()); while (iterator.hasPrevious()) { String element = iterator.previous(); // 处理元素 } | 反向遍历链表 |

ArrayList 和 LinkedList 的性能对比

  • ArrayList:适合频繁的随机访问操作,时间复杂度为O(1)。但在中间插入或删除元素时,时间复杂度为O(n),因为需要移动后续元素。

线程安全

  • ArrayList和LinkedList都不是线程安全的。如果需要在多线程环境中使用,可以使用Collections.synchronizedList来包装它们:

    java 复制代码
         List<String> synchronizedList = Collections.synchronizedList(new ArrayList<>());
  • 或者使用CopyOnWriteArrayList,它是线程安全的List实现,适合读多写少的场景。

迭代器

  • ArrayList和LinkedList都支持Iterator和ListIterator。ListIterator提供了双向遍历的能力,可以在遍历过程中修改列表。

    java 复制代码
         ListIterator<String> iterator = list.listIterator();
    
         while (iterator.hasNext()) {
    
             String element = iterator.next();
    
             // 处理元素
    
         }

容量管理

  • ArrayList在内部使用数组存储元素,当数组容量不足时会自动扩容。可以通过ensureCapacity(int minCapacity)方法来预先分配足够的容量,避免频繁扩容带来的性能开销。

    java 复制代码
         ArrayList<String> list = new ArrayList<>();
    
         list.ensureCapacity(100); // 预先分配100个元素的容量

LinkedList 的特殊方法

  • LinkedList实现了Deque接口,因此可以用作栈或队列。它提供了addFirst、addLast、removeFirst、removeLast等方法,可以方便地实现栈和队列的操作。

    java 复制代码
         LinkedList<String> queue = new LinkedList<>();
    
         queue.addLast("A"); // 入队
    
         String first = queue.removeFirst(); // 出队

性能优化建议

  • 如果需要频繁在列表中间插入或删除元素,优先选择LinkedList。
  • 如果需要频繁随机访问元素,优先选择ArrayList。
  • 如果列表大小固定且已知,可以使用Arrays.asList来创建不可变的列表,减少内存开销。

    java 复制代码
         List<String> fixedList = Arrays.asList("A", "B", "C");

进一步优化与迭代方向

  • 性能测试:在实际项目中,建议对ArrayList和LinkedList进行性能测试,根据具体场景选择最合适的集合类。
  • 并发控制:如果需要在多线程环境中使用List,可以考虑使用CopyOnWriteArrayList或Collections.synchronizedList来保证线程安全。
  • 内存优化:对于大数据量的列表,可以考虑使用ArrayList并预先分配足够的容量,避免频繁扩容带来的性能开销。

脑图

觉得不清晰文章顶部有资源可以下载

相关推荐
众乐乐_20083 分钟前
JVM栈帧中|局部变量表、操作数栈、动态链接各自的任务是什么?
java·开发语言·jvm
菜鸟单飞6 分钟前
一键查看电脑各硬件详细信息 轻松查看电脑硬件参数
windows·电脑
m0_7482393342 分钟前
深入解析Spring Boot中的@ConfigurationProperties注解
java·spring boot·后端
兴趣广泛的程序猿2 小时前
Tomcat添加到Windows系统服务中,服务名称带空格
windows·tomcat
茂桑2 小时前
Redis的数据过期策略和数据淘汰策略
java·数据库·redis
涟漪海洋2 小时前
[2025年最新]2024.3版本idea无法安装插件问题解决
java·ide·intellij-idea
土豆炒马铃薯。3 小时前
【系统设计】Spring、SpringMVC 与 Spring Boot 技术选型指南:人群、场景与实战建议
java·spring boot·后端·spring
逸狼3 小时前
【JavaEE进阶】Spring MVC(1)
java·java-ee
XJSFDX_Ali3 小时前
安卓开发,底部导航栏
android·java·开发语言
半旧5183 小时前
重构谷粒商城01:为何重构谷粒商城
java·后端·全栈·项目·谷粒商城