集合框架到底是“工具箱”还是“陷阱箱”?——你真的用明白了吗?
开篇语
哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛
今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。
我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。
小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!
前言
老实说,初学 Java 的时候,我对集合框架的第一印象是:哇,居然有这么多现成的数据结构可用!再也不用自己手搓链表了,泪目🙈。但随着代码越写越多,我才发现:集合框架就像一盒魔方,看起来炫酷,但拧不好,分分钟拧到怀疑人生。
今天我们就来拆解一下集合框架(Collections Framework),从接口到实现类、从排序到线程安全,一条龙聊透。中途插播点代码演示,不然太空洞你估计也会睡着😂。
1. 接口三巨头:List、Set、Map
List:有序可重复
- 特点:元素按插入顺序存储,可以重复。
- 常用场景:需要按索引访问,或者要维护顺序的时候。
import java.util.*;
public class DemoList {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Java");
list.add("Python");
list.add("Java"); // 重复也没问题
System.out.println(list); // [Java, Python, Java]
}
}
👉 看到没,Java
重复出现了,List 就是这么包容哈哈。
Set:无序不可重复
- 特点:元素不能重复,底层其实用哈希表来保证唯一性。
- 常用场景:去重、判重。
import java.util.*;
public class DemoSet {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
set.add("Java");
set.add("Python");
set.add("Java"); // 插不进去
System.out.println(set); // [Java, Python]
}
}
👉 友情提示:HashSet 打印的顺序不一定是插入顺序,想要保持顺序可以用 LinkedHashSet
。
Map:键值对选手
- 特点:Key 唯一,Value 可重复。
- 常用场景:存储映射关系,比如学生 ID → 学生成绩。
import java.util.*;
public class DemoMap {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<>();
map.put(1, "Java");
map.put(2, "Python");
map.put(1, "C++"); // 覆盖
System.out.println(map); // {1=C++, 2=Python}
}
}
👉 注意哈,Key 冲突的话,后面会覆盖前面的。
2. 常用集合类:ArrayList、HashSet、HashMap
ArrayList
- 底层是动态数组,查询快,增删(尤其是中间位置)稍慢。
- 适合:读多写少的场景。
HashSet
- 底层是
HashMap
,靠哈希值来保证唯一性。 - 性能:插入和查找接近 O(1),但是哈希函数要写好,不然碰撞多了效率直线下降。
HashMap
- 几乎是日常开发中最常用的 Map 实现类。
- JDK 1.8 后底层做了优化:链表长度超过 8 会转成红黑树,查找更快。
- 但要小心:多线程下用 HashMap 可能会翻车(比如死循环),这时候就要考虑 ConcurrentHashMap。
3. 排序与比较:Comparable vs Comparator
Comparable:我自己定义排序规则
class Student implements Comparable<Student> {
String name;
int score;
Student(String name, int score) {
this.name = name;
this.score = score;
}
@Override
public int compareTo(Student o) {
return this.score - o.score; // 按成绩升序
}
@Override
public String toString() {
return name + ":" + score;
}
}
public class DemoComparable {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("Alice", 95));
students.add(new Student("Bob", 88));
students.add(new Student("Cathy", 92));
Collections.sort(students);
System.out.println(students);
}
}
Comparator:别人来帮我定义规则
import java.util.*;
public class DemoComparator {
public static void main(String[] args) {
List<String> langs = Arrays.asList("Java", "Python", "C++");
langs.sort((a, b) -> b.length() - a.length()); // 按长度降序
System.out.println(langs); // [Python, Java, C++]
}
}
👉 简单理解:Comparable 是内置规则,Comparator 是外接规则。
4. 线程安全的集合类:CopyOnWriteArrayList
多线程环境下,用普通的 ArrayList 就像在地铁里刷手机:可能刚点开页面,就被挤掉了。数据结构也一样,线程一多,ArrayList 就不稳了。
这时,CopyOnWriteArrayList
就登场了:
- 原理:写操作时复制一份新数组,写完再替换掉旧的。
- 好处:读操作不会被锁,适合读多写少的场景。
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
public class DemoThreadSafe {
public static void main(String[] args) {
List<String> list = new CopyOnWriteArrayList<>();
list.add("Java");
list.add("Python");
// 多线程读写
new Thread(() -> list.add("C++")).start();
new Thread(() -> System.out.println(list)).start();
}
}
👉 注意:因为写的时候会复制,写操作性能比 ArrayList 慢,所以别滥用。
结语:集合框架,是“宝藏”还是“雷区”?
说到底,集合框架就像工具箱。用得对,它能帮你效率翻倍;用不对,它能让你调试到怀疑人生。List、Set、Map 是地基,ArrayList、HashSet、HashMap 是常客,Comparable、Comparator 给你排序自由,而线程安全的 CopyOnWriteArrayList 等则是多线程世界里的护身符。
那么问题来了:下次你写代码时,会选哪个集合类,还是继续“全都上 ArrayList”?🤔
要不要我再帮你把这篇文章扩展到更“大而全”的版本,比如再加上 TreeSet
、LinkedHashMap
、ConcurrentHashMap
的深入案例?这样内容会更全面,深度和广度都能拉满🔥。你希望文章更“入门向”还是更“进阶向”?
… …
文末
好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。
… …
学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!
wished for you successed !!!
⭐️若喜欢我,就请关注我叭。
⭐️若对您有用,就请点赞叭。
⭐️若有疑问,就请评论留言告诉我叭。
版权声明:本文由作者原创,转载请注明出处,谢谢支持!
- 点赞
- 收藏
- 关注作者
评论(0)