Java?集合!!!
在Java开发中,集合是高频使用的基础组件,它本质是用于存储和管理一组对象的容器,解决了数组长度固定、操作繁琐的痛点。很多新手在学习时会被ArrayList、HashMap、HashSet等类搞得眼花缭乱,其实只要理清集合的体系结构,掌握核心方法,就能轻松上手。今天这篇博客,就来系统梳理Java集合的体系框架,总结各常用集合的核心方法
一、Java集合体系总览
Java集合框架主要分为两大核心体系:Collection(单列集合)和Map(双列集合),二者无继承关系,分别对应不同的存储场景。所有集合类均位于java.util包下,核心设计思想是“接口标准化、数据结构封装”,开发者无需关注底层实现,只需调用API即可完成操作。
1. 核心体系结构图(简化版,好记不复杂)
```
java.util
├─ Collection(单列集合根接口):存储单个元素,继承Iterable接口,支持迭代遍历
│ ├─ List(子接口):有序、可重复、有索引,支持按索引操作
│ │ ├─ ArrayList:动态数组实现(开发首选)
│ │ ├─ LinkedList:双向链表实现(高频增删场景)
│ │ └─ Vector:线程安全(效率低,已过时)
│ ├─ Set(子接口):无序、不可重复、无索引,核心用于去重
│ │ ├─ HashSet:哈希表实现(去重首选)
│ │ ├─ LinkedHashSet:哈希表+链表(维持插入顺序)
│ │ └─ TreeSet:红黑树实现(自动排序)
│ └─ Queue(子接口):队列(FIFO),用于元素排队处理
│ ├─ LinkedList:双向链表实现的队列/双端队列
│ └─ PriorityQueue:优先级队列(按规则排序)
└─ Map(双列集合根接口):存储键值对(K-V),键唯一、值可重复
├─ HashMap:哈希表实现(键值对首选)
├─ LinkedHashMap:哈希表+链表(维持插入/访问顺序)
├─ TreeMap:红黑树实现(按键排序)
└─ Hashtable:线程安全(效率低,已过时)
```
2. 核心说明
-
Collection:存储“单个元素”,比如存储一组字符串、一组用户对象,所有子接口都遵循Collection的基本规范。
-
Map:存储“键值对”,比如存储用户ID和用户对象的映射关系,通过键(Key)快速查找值(Value),键不能重复,值可以重复。
-
Iterable接口:Collection的父接口,提供迭代器(Iterator),支持foreach遍历,这是所有单列集合遍历的基础。
-
工具类:Collections(注意区分Collection接口),提供静态方法,用于集合的排序、反转、查找最值等操作。
二、Collection体系详解(单列集合)
Collection是单列集合的顶层接口,定义了所有单列集合的通用方法,其子接口List、Set、Queue在此基础上扩展了各自的特有方法。先掌握通用方法,再学习特有方法,效率更高。
1. Collection通用方法(所有单列集合都能用)
这些方法是Collection接口的核心,适用于ArrayList、HashSet、LinkedList等所有实现类,重点掌握前6个高频方法:
|
方法名 |
说明 |
示例(以ArrayList为例) |
|---|---|---|
|
boolean add(E e) |
添加元素,成功返回true,失败返回false(Set去重时重复元素返回false) |
list.add("Java"); // 添加成功返回true |
|
boolean remove(Object o) |
删除指定元素,成功返回true;List删除第一个匹配元素,Set删除唯一匹配元素 |
list.remove("Java"); // 删除元素"Java" |
|
int size() |
返回集合中元素的个数 |
int len = list.size(); // 获取集合长度 |
|
boolean isEmpty() |
判断集合是否为空,空返回true,非空返回false |
boolean empty = list.isEmpty(); // 空集合返回true |
|
boolean contains(Object o) |
判断集合中是否包含指定元素,包含返回true |
boolean hasJava = list.contains("Java"); |
|
void clear() |
清空集合中所有元素(集合对象仍存在,元素清空) |
list.clear(); // 清空后size为0 |
|
Object[] toArray() |
将集合转换为数组 |
Object[] arr = list.toArray(); |
|
Iterator<E> iterator() |
获取迭代器,用于遍历集合(foreach底层就是迭代器) |
Iterator<String> it = list.iterator(); |
2. List子接口(有序、可重复、有索引)
List接口继承自Collection,新增了“按索引操作”的方法,因为有序、有索引,所以可以精确操作某个位置的元素,常用实现类是ArrayList和LinkedList。
(1)List特有高频方法
|
方法名 |
说明 |
示例 |
|---|---|---|
|
E get(int index) |
获取指定索引位置的元素(核心方法) |
String str = list.get(0); // 获取第一个元素 |
|
E set(int index, E e) |
修改指定索引位置的元素,返回被修改的旧元素 |
String old = list.set(0, "Python"); // 替换第一个元素 |
|
void add(int index, E e) |
在指定索引位置插入元素,后续元素向后移动 |
list.add(1, "MySQL"); // 在第二个位置插入 |
|
E remove(int index) |
删除指定索引位置的元素,返回被删除的元素 |
String del = list.remove(1); // 删除第二个元素 |
|
int indexOf(Object o) |
查找元素第一次出现的索引,没有则返回-1 |
int idx = list.indexOf("Java"); |
(2)常用实现类:ArrayList vs LinkedList
两者都是List的常用实现,核心区别在底层数据结构,决定了它们的性能差异,选型时重点关注“查询”和“增删”频率:
-
ArrayList:底层是动态数组(连续内存),默认初始容量10,扩容规则为原容量的1.5倍。
-
优势:查询、修改快(通过索引直接访问,时间复杂度O(1));
-
劣势:新增、删除慢(需移动后续元素,时间复杂度O(n));
-
场景:读多写少(如商品列表展示、数据查询)。
-
-
LinkedList:底层是双向链表(非连续内存),每个节点存储元素和前后节点引用,无数组扩容概念。
-
优势:新增、删除快(仅修改节点引用,首尾操作时间复杂度O(1));
-
劣势:查询、修改慢(需遍历链表,时间复杂度O(n));
-
场景:写多读少(如消息队列、任务栈,频繁操作首尾元素)。
-
3. Set子接口(无序、不可重复、无索引)
Set接口继承自Collection,核心特点是“去重”,因为无索引,所以不能按索引操作,也不能使用普通for循环遍历(只能用foreach或迭代器)。常用实现类是HashSet和TreeSet。
(1)Set核心注意点
-
去重原理:依赖元素的hashCode()和equals()方法——先比较哈希值,哈希值不同则元素不同;哈希值相同,再通过equals()比较内容,内容相同则视为重复元素,不允许添加。
-
无序性:指元素的存储顺序与插入顺序无关(HashSet),并非随机;LinkedHashSet可维持插入顺序,TreeSet可维持排序顺序。
-
无索引:不能使用get(int index)方法,遍历只能用foreach或Iterator。
(2)常用实现类及方法
-
HashSet:底层是哈希表(本质是HashMap的封装,元素作为HashMap的Key),去重首选,效率最高。
-
核心方法:仅继承Collection的通用方法,无特有方法;
-
特点:允许存储1个null元素,无序、不可重复,添加/删除/查询效率均为O(1)(理想无哈希冲突情况);
-
示例:存储用户ID、标签等需要去重的数据。
-
-
TreeSet:底层是红黑树(自平衡二叉搜索树),会自动对元素排序。
-
核心方法:继承Collection通用方法,新增排序相关方法(如first()、last());
-
排序规则:元素需实现Comparable接口,或创建TreeSet时传入Comparator比较器;
-
特点:不可重复、有序(按规则排序),查询、插入、删除时间复杂度O(logn);
-
示例:存储需要排序的数据(如排行榜、成绩排序)。
-
三、Map体系详解(双列集合)
Map是双列集合的顶层接口,与Collection体系完全独立,核心是“键值对映射”,Key唯一、Value可重复,通过Key能快速定位Value,是开发中高频使用的集合(如存储配置、用户信息)。常用实现类是HashMap和TreeMap。
1. Map通用高频方法
所有Map实现类都支持以下方法,重点掌握“增删改查”核心操作:
|
方法名 |
说明 |
示例(以HashMap为例) |
|---|---|---|
|
V put(K key, V value) |
添加/修改键值对:Key不存在则添加,存在则修改Value,返回旧Value(无旧值返回null) |
map.put("name", "张三"); // 添加键值对 |
|
V get(Object key) |
通过Key获取Value,Key不存在返回null |
String name = map.get("name"); // 获取Value |
|
V remove(Object key) |
通过Key删除键值对,返回被删除的Value,Key不存在返回null |
String delName = map.remove("name"); |
|
Set<K> keySet() |
获取所有Key的集合(Set类型,保证Key唯一) |
Set<String> keys = map.keySet(); |
|
Collection<V> values() |
获取所有Value的集合(Collection类型,可重复) |
Collection<String> vals = map.values(); |
|
Set<Map.Entry<K,V>> entrySet() |
获取所有键值对的集合(推荐用于遍历所有键值对) |
Set<Map.Entry<String,String>> entries = map.entrySet(); |
|
boolean containsKey(Object key) |
判断是否包含指定Key |
boolean hasName = map.containsKey("name"); |
|
int size() / boolean isEmpty() / void clear() |
与Collection中方法功能一致,分别对应获取长度、判断空、清空 |
int len = map.size(); |
2. 常用实现类:HashMap vs TreeMap
-
HashMap:底层是“数组+链表+红黑树”(JDK8及以后),键值对首选,效率最高。
-
底层细节:默认初始容量16,负载因子0.75(扩容阈值=容量×负载因子);当链表长度≥8、数组容量≥64时,链表转为红黑树,提升查询效率(从O(n)变为O(logn));
-
特点:无序、非线程安全、Key唯一、Value可重复,允许Key和Value为null(Key仅允许1个null);
-
场景:绝大多数键值对存储场景(如用户会话、配置存储)。
-
-
TreeMap:底层是红黑树,会自动按Key排序。
-
排序规则:Key需实现Comparable接口,或创建TreeMap时传入Comparator比较器;
-
特点:有序(按Key排序)、非线程安全、Key唯一,不允许Key为null;
-
场景:需要按Key排序的键值对场景(如按ID排序的用户列表、排行榜)。
-
四、高频面试/开发注意事项
-
线程安全问题:ArrayList、HashMap、HashSet等均为非线程安全,多线程环境下需使用线程安全集合(如CopyOnWriteArrayList、ConcurrentHashMap),避免使用已过时的Vector、Hashtable(效率极低)。
-
Set去重关键:存储自定义对象时,必须重写hashCode()和equals()方法,否则无法实现去重(默认使用Object类的方法,比较的是对象地址)。
-
集合与数组转换:使用Collection的toArray()方法将集合转为数组,使用Arrays.asList()方法将数组转为集合(注意:Arrays.asList()返回的集合不可修改)。
-
遍历方式选择:List可用普通for、foreach、迭代器;Set可用foreach、迭代器;Map可用keySet()遍历Key、values()遍历Value、entrySet()遍历键值对(推荐entrySet(),效率更高)。
-
扩容问题:ArrayList、HashMap频繁扩容会影响性能,可在创建时指定初始容量(如new ArrayList<>(100)),减少扩容次数。
五、总结
Java集合体系看似复杂,其实核心就是“两大体系(Collection、Map)、三大核心接口(List、Set、Map)、几个常用实现类”。学习时记住:
-
需存储单个元素 → 用Collection体系:有序可重复用List(ArrayList首选),去重用Set(HashSet首选);
-
需存储键值对 → 用Map体系:无需排序用HashMap(首选),需排序用TreeMap;
-
核心方法优先掌握“增删改查”,结合底层数据结构理解性能差异,就能精准选型。
更多推荐




所有评论(0)