当前位置: 首页 > news >正文

day16——Java集合进阶(Collection、List、Set)

文章目录

      • 一、Collection集合框架全景
        • 1. 集合体系架构
        • 2. Collection核心方法
        • 3. Collection的遍历方式
          • (1). 迭代器遍历 - 最通用的遍历方式
          • (2) 增强for循环 - 语法糖的典范
          • (3) Lambda表达式 - JDK8+的现代化方案
          • (4) 普通for循环 - List专属方案
        • 4. 性能关键数据
      • 二、List集合深度解析
        • 1. List特有方法
        • 2. 四大遍历方式对比
        • 3. ArrayList底层原理
        • 4. LinkedList底层原理
      • 三、Set集合核心探秘
        • 1. HashSet实现机制
        • 2. LinkedHashSet特性
        • 3. TreeSet排序控制
      • 四、关键问题解决方案
        • 1. 并发修改异常处理
        • 2. 集合选型黄金法则
      • 结语:技术本质思考

深度掌握Java集合框架是成为合格Java开发者的必经之路。 本文将全面解析异常处理机制与Collection集合体系的核心知识,助你构建坚实的Java基础。

一、Collection集合框架全景

1. 集合体系架构

在这里插入图片描述

集合类型特点实现类
List有序、可重复、有索引ArrayList, LinkedList
Set无序、不重复、无索引HashSet, TreeSet
QueueFIFO(先进先出)LinkedList
2. Collection核心方法

Collection是集合的祖宗类,它的功能是全部集合都可以继承使用的,所以要学习它。

在这里插入图片描述

Collection<String> coll = new ArrayList<>();
coll.add("Java");       // 添加元素
coll.remove("C++");     // 删除元素
coll.contains("Python");// 检查存在
coll.size();            // 获取大小
coll.clear();           // 清空集合
Object[] arr = coll.toArray(); // 转为数组
3. Collection的遍历方式
(1). 迭代器遍历 - 最通用的遍历方式

核心原理:通过Iterator对象实现解耦访问
Collection集合获取迭代器的方法
在这里插入图片描述Iterator迭代器中的常用方法
在这里插入图片描述

Collection<String> coll = new ArrayList<>();
coll.add("Java");
coll.add("Python");
coll.add("Go");Iterator<String> it = coll.iterator();
while(it.hasNext()) {String element = it.next();System.out.println(element);// 安全删除当前元素if("Python".equals(element)) {it.remove(); // ✅ 唯一线程安全的删除方式}
}

关键特性

  • 🛡️ 并发安全:唯一支持遍历时安全删除元素的方式
  • 🔄 单向移动:只能向前遍历,不可回溯
  • ⚠️ 注意:每次调用next()前必须用hasNext()检查
(2) 增强for循环 - 语法糖的典范

本质:编译器自动转换为迭代器实现
格式
for (元素的数据类型 变量名 : 数组或者集合) {

}

快捷键:数组或者集合 . for +回车

for(String language : coll) {System.out.println(language);// coll.remove(language);  // ❌ 触发ConcurrentModificationException
}

优势与局限

  • 代码简洁:比传统迭代器减少50%代码量
  • 编译优化:自动处理迭代器创建和边界检查
  • 禁止修改:遍历时修改集合会抛出并发修改异常
(3) Lambda表达式 - JDK8+的现代化方案

需要使用Collection的如下方法来完成

函数式编程实践
在这里插入图片描述

技术本质

  • 🎯 基于Iterable接口的forEach()方法
  • 🔧 底层仍使用迭代器实现
  • 💡 重要特性:同样不支持遍历时修改集合
(4) 普通for循环 - List专属方案

仅适用于List实现类

if(coll instanceof List) {List<String> list = (List<String>) coll;for(int i=0; i<list.size(); i++) {System.out.println(list.get(i));// 倒序遍历删除避免索引错位if(i > 0 && "Java".equals(list.get(i-1))) {list.remove(i-1);i--;  // 索引回退保持正确位置}}
}

适用场景

  • 🔢 需要索引访问的复杂操作
  • 🔄 倒序遍历删除元素
  • ⚠️ 注意:非List集合无法使用此方式
4. 性能关键数据
遍历方式时间复杂度内存开销修改安全性
迭代器O(n)高(支持删除)
增强forO(n)
LambdaO(n)
普通forO(n)最低中(需特殊处理)

最佳实践建议:在JDK8+环境中,优先使用forEach()+Lambda的组合,兼顾简洁性与可读性;当需要修改集合时,务必切换为迭代器模式,这是避免并发异常的黄金法则。

二、List集合深度解析

List集合因为支持索引,所以多了很多与索引相关的方法,当然,Collection的功能List也都继承了。

1. List特有方法

在这里插入图片描述

List<String> list = new ArrayList<>();
list.add(1, "Spring"); // 指定位置插入
list.remove(0);         // 按索引移除
list.set(2, "MySQL");   // 替换元素
String item = list.get(1); // 获取元素
2. 四大遍历方式对比
    public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("糖宝宝");list.add("蜘蛛精");list.add("至尊宝");//(1)for循环for (int i = 0; i < list.size(); i++) {// i = 0 1 2String s = list.get(i);System.out.println(s);}//(2)迭代器。Iterator<String> it = list.iterator();while (it.hasNext()) {System.out.println(it.next());}//(3)增强for循环(foreach遍历)for (String s : list) {System.out.println(s);}//(4)JDK 1.8开始之后的Lambda表达式list.forEach(s -> {System.out.println(s);});}
3. ArrayList底层原理
  • 数组结构:初始容量10
  • 扩容机制:1.5倍动态扩容
  • 特点
    • 查询速度快
    • 尾部插入高效
    • 中间插入/删除慢(需移动元素)
4. LinkedList底层原理

在这里插入图片描述
在这里插入图片描述
特点:查询慢,增删相对较快,但对首尾元素进行增删改查的速度是极快的。

  • 双向链表:节点结构prev|data|next
  • 特有方法

在这里插入图片描述

  • 应用场景
    • 队列实现:FIFO(先进先出)
    Queue<String> queue = new LinkedList<>();// 入队queue.addLast("第1号人");queue.addLast("第2号人");// 出队System.out.println(queue.removeFirst());System.out.println(queue.removeFirst())queue.offer("A"); // 入队
    queue.poll();     // 出队
    
    • 栈实现:LIFO(后进先出)
    Deque<String> stack = new LinkedList<>();
    stack.push("A"); // 压栈  push() = addFirst()
    stack.pop();      // 弹栈  pop() = removeFirst()
    

注意:ArrayList和LinkedList 底层采用的数据结构不同,应用场景不同

三、Set集合核心探秘

Set系列集合特点: 无序:添加数据的顺序和获取出的数据顺序不一致; 不重复; 无索引;
HashSet : 无序、不重复、无索引。
LinkedHashSet有序、不重复、无索引。
TreeSet可排序、不重复、无索引。
注意:
Set要用到的常用方法,基本上就是Collection提供的!!
自己几乎没有额外新增一些常用功能!

1. HashSet实现机制
  • 哈希表结构:数组+链表+红黑树(JDK8+)
    红黑树,就是可以自平衡的二叉树
    红黑树是一种增删改查数据性能相对都较好的结构。

  • 去重原理
    如果希望Set集合认为2个内容一样的对象是重复的,必须重写对象的hashCode()和equals()方法

    1. 比较hashCode()
    2. 若哈希冲突,再比较equals()
    // 自定义对象去重要例
    @Override
    public int hashCode() {return Objects.hash(name, age);
    }@Override
    public boolean equals(Object o) {// 属性值比较逻辑
    }
    
2. LinkedHashSet特性

依然是基于哈希表(数组、链表、红黑树)实现的。但是,它的每个元素都额外的多了一个双链表的机制记录它前后元素的位置。

  • 双向链表:维护元素插入顺序
  • 性能平衡:在HashSet基础上增加顺序维护
3. TreeSet排序控制
  • 红黑树结构:自动排序,对于数值类型:Integer , Double,默认按照数值本身的大小进行升序排序。

    对于自定义类型如Student对象,TreeSet默认是无法直接排序的。

  • 排序规则
    TreeSet集合存储自定义类型的对象时,必须指定排序规则,支持如下两种方式来指定比较规则。

    • 方式一:
      让自定义的类(如学生类)实现Comparable接口,重写里面的compareTo方法来指定比较规则。
    • 方式二:
      通过调用TreeSet集合有参数构造器,可以设置Comparator对象(比较器对象,用于指定比较规则。
    1. 实现Comparable接口
    public class Student implements Comparable<Student> {@Overridepublic int compareTo(Student s) {return this.age - s.age;}
    }
    
    1. 自定义Comparator
    TreeSet<Student> students = new TreeSet<>((s1, s2) -> s1.getName().compareTo(s2.getName())
    );
    

四、关键问题解决方案

1. 并发修改异常处理

在这里插入图片描述

// 正确删除方式(迭代器)
Iterator<String> it = list.iterator();
while(it.hasNext()) {String item = it.next();if("removeMe".equals(item)) {it.remove(); // 使用迭代器删除,当前遍历到的数据,每删除一个数据后,相当于也在底层做了i--}
}// 逆向遍历删除
for(int i=list.size()-1; i>=0; i--) {if("removeMe".equals(list.get(i))) {list.remove(i);}
}
2. 集合选型黄金法则
场景需求推荐集合原因剖析
高频随机访问ArrayList数组结构O(1)访问
频繁首尾操作LinkedList双向链表高效增删
去重且无需排序HashSet哈希表最佳查询性能
去重且保留插入顺序LinkedHashSet哈希表+链表维护顺序
去重且需要自动排序TreeSet红黑树保证有序性

在这里插入图片描述

结语:技术本质思考

Java集合框架的精髓在于根据数据结构特性解决特定场景问题。理解这三点至关重要:

  1. 时间复杂度决定性能:ArrayList的O(1)随机访问 vs LinkedList的O(1)头尾操作
  2. 空间与时间的平衡:HashSet以空间换时间,TreeSet以排序换性能
  3. 设计模式应用:迭代器模式实现统一遍历接口,装饰者模式扩展功能(如LinkedHashSet)

高效编程的本质不是记住所有API,而是掌握数据结构的灵魂。 当你深刻理解每种集合的底层实现原理时,技术选型将不再是选择题,而是基于场景的最优解推导。

http://www.dtcms.com/a/268647.html

相关文章:

  • Kafka消息积压的原因分析与解决方案
  • 网络安全之重放攻击:原理、危害与防御之道
  • windows grpcurl
  • 用安卓手机给苹果手机设置使用时长限制,怎样将苹果手机的某些APP设置为禁用?有三种方法
  • 软件工程功能点估算基础
  • QML Row与Column布局
  • YOLOv11 架构优化:提升目标检测性能
  • 国内免代理免费使用Gemini大模型实战
  • Vue的生命周期(Vue2)
  • Maven继承:多模块项目高效管理秘笈
  • 微软重磅开源Magentic-UI!
  • 【Rust CLI项目】Rust CLI命令行处理csv文件项目实战
  • AI Tool Calling 实战——让 LLM 控制 Java 工具
  • java-Milvus 连接池(多key)与自定义端点监听设计
  • C++开源项目—2048.cpp
  • 部署MongoDB
  • 接口漏洞怎么抓?Fiddler 中文版 + Postman + Wireshark 实战指南
  • 记录一个关于Maven配置TSF的报错问题
  • 基于 Three.js 开发三维引擎-02动态圆柱墙体实现
  • Python中50个常用的内置函数(2/2)
  • 剑指offer第2版:动态规划+记忆化搜索
  • 回溯题解——子集【LeetCode】输入的视角(选或不选)
  • YOLOv11模型轻量化挑战:边缘计算设备部署优化方案
  • FastAPI依赖注入:构建高可维护API的核心理念与实战
  • Modbus_TCP 客户端低版本指令(归档)
  • Hadoop 分布式存储与计算框架详解
  • Web后端开发-请求响应
  • NLP:文本特征处理和回译数据增强法
  • Mac-右键用 VS Code 打开文件夹
  • 【Echarts】“折线+柱状”实现双图表-家庭用电量可视化【文章附完整代码】