集合框架

一、集合框架

1.概述?

Java 集合框架(JCF)是一套用于存储、操作和管理对象组的标准化接口和实现类。它解决了数组的局限性(如固定长度、缺乏封装操作),提供高效的数据结构和算法。整个集合框架分为两大块,一块是基于Collection接口,另一块是基于Map接口。

二、Collection

1.概述

Collection是单列集合的根接口,其中SequenceCollection接口和SequenceSet接口都是Java21新增接口。UML图如下:
image

2.核心接口

接口 元素特点 有序性 唯一性 典型实现类
List 可重复 有序(索引) ArrayList, LinkedList
Set 不可重复 无序(多数) HashSet, TreeSet
Queue 可重复 按规则排序 PriorityQueue
Deque 可重复 双端操作 LinkedList

3.List接口的常用实现类

类名 数据结构 线程是否安全 随机访问速度 插入和删除速度 适用场景
ArrayList 动态数组 快(O(1)) 慢(O(n)) 高频查询、少增删
Vector 动态数组 是(同步) 快(O(1)) 慢(O(n)) 已被弃用,用 CopyOnWriteArrayList 替代
LinkedList 双向链表 慢(O(n)) 快(O(1)) 高频增删、需要队列/栈操作

4.Set接口的常用实现类

类名 数据结构 排序规则 线程是否安全 查询速度 特点
HashSet 哈希表 无序 O(1) 最高效,依赖 hashCode() 和 equals()
LinkedHashSet 哈希表 + 双向链表 插入顺序 O(1) 保留插入顺序
TreeSet 红黑树 自然排序/Comparator O(log n) 自动排序,要求元素实现 Comparable
注:HashSet和LinkedHashSet本质是HashMap和LinkedHashMap的key。然后LinkedHashSet是通过双向链表来控制插入顺序,即每一个结点上除了hash值,key,value,next(指向下一个结点)之外,还有before,after来控制插入时的前后顺序。

image

5.Queue接口和Deque接口的常用实现类

类名 数据结构 特点 适用场景
PriorityQueue 堆(优先队列) 按优先级排序(自然序或Comparator) 任务调度、贪婪算法
LinkedList 链表 实现了 Deque(双端队列) 队列、栈操作
注:堆在逻辑上可以看作一颗完全二叉树,但实际上存储方式是一个队列(链表或者数组实现),假设队列中首元素初始下标为0,那么2i+1就可以代表i结点的左孩子,2i+2就可以代表i结点的右孩子,而满足根节点的元素大于(小于)子节点的元素,即形成大根堆(小根堆),这样就满足了时间复杂度为O(nlogn)的堆排序。

6.迭代器Iterator及其使用方式

Iterator是所有Collection集合独有的遍历集合元素的方式。使用方式为:
1)通过iterator()方法,获取一个迭代器对象;
2)通过迭代器的hasNext()方法,判断迭代器的光标所指向的位置是否有元素,返回值为boolean类型;
3)通过迭代器的next()方法,将光标所指向的位置上的元素返回,并将光标移动到下一个位置;
总结使用:

点击查看代码
Iterator<String> iterator = collection.iterator();
while (iterator.hasNext()){
	String e = iterator.next();
}

7.迭代时删除元素问题

在使用迭代器遍历元素时,不能使用集合的方法删除元素,必须使用迭代器自带remove()方法来删除。
原因是:迭代器存在fail-fast机制。即当发现程序对集合进行并发修改时,就会让其立即执行失败,防止出现错误。
实现原理:
1)集合中设置了一个modCount属性,用来记录修改操作的执行次数;
2)当获取迭代器对象时,会给迭代器对象初始化一个expectedModCount属性,并将modCount的值赋给expectedModCount;
3)若使用集合对象的API删除集合内元素时,modCount会加1,但迭代器中expectedModCount不会加1。
4)若使用迭代器的API删除集合内元素时,modCount会加1,迭代器中expectedModCount也会加1。
5)当迭代器对象执行next()方法时,会判断modCount与expectedModCount的值是否相等,如果不相等则会抛出ConcurrentModificationException。

三、Map

1.概述

Map是双列集合(键值对)的根接口。UML图如下:
image

接口 元素特点 有序性 唯一性 典型实现类
Map Key-Value 对 Key 唯一 Key 不可重复(重复会覆盖前面的) HashMap, TreeMap

2.Map常用实现类

类名 数据结构 Key排序规则 线程是否安全 查询速度 特点
HashMap 数组加链表或者红黑树 无序(存入顺序与取出顺序不同) O(1) 最高效,允许 key为null
LinkedHashMap 哈希表加双向链表 插入顺序/访问顺序 O(1) 保留顺序,支持 LRU 缓存
TreeMap 红黑树 Key 排序 O(log n) Key 需可排序
Hashtable 哈希表 无序 是(同步) O(1) 已弃用,用 ConcurrentHashMap 替代
注:HashMap,LinkedHashMap存储的key必须重写equals()方法和hashcode()方法

3.关于Map的遍历

方法一:通过keySet()方法获得一个Set集合,通过Set集合的迭代器遍历。
方法二:通过entrySet()方法获得一个Set<Map.Entry<K, V>>集合,通过Set集合的迭代器遍历。

注:Map.Entry是Map的内置接口,每一个entry元素都会存储hash值,key,value三个基础值。

四、泛型

1.概述

泛型是java5新增的编译阶段功能,作用是用于保障数据类型安全,常常结合集合框架使用。

2.泛型的擦除和补偿

1)擦除:在加载类时会将泛型擦除变为Object类型,这样保证了擦除之后的代码与java5之前的代码一致。
2)补偿:虚拟机会根据元素的实际类型进行向下转型,也就是恢复元素的实际类型。

3.自定义泛型

1)在类上自定义泛型

pbulic class MyClass<T>{}
表示在类声明时,同时声明一个泛型。也可以声明多个<T,E,F...>

2)在方法上自定义泛型

public static <T,E> void m1(T t, E e){}
表示在方法声明时,同时声明两个泛型。

注:在类上自定义的泛型,在静态方法上无法使用

3)在接口上自定义泛型

public interface MyInterface<T,E,F>{}
表示在接口声明时,同时声明三个泛型。
public class MyClass<T> implements MyInterface<T>{}
表示在不知道接口会传哪种数据类型时,在实现类上自定义一个泛型,保证接口传入的与实现类接受的数据类型相同。

4.泛型通配符(在使用泛型时使用,定义时不能使用)

1)无限定通配符:<?>,?表示此处可以为任意数据类型

2)上限定通配符:<? extends Number>,?表示此处必须为Number数据类型或Number的子类

3)下限定通配符:<? super Number>,?表示此处必须为Number数据类型或Number的父类

五、重要工具类

1.Collections 工具类

java.util.Collections 是一个专为操作集合(List/Set/Map等)设计的工具类,提供排序、查找、线程安全化等能力,仅由操作或返回集合的静态方法组成。它包含对集合进行排序、搜索、线程安全化、不可变包装等方法。
核心功能:

方法类别 方法签名示例 作用
排序/重排 sort(List list) / sort(List list, Comparator) / shuffle(List<?> list) 自然排序/自定义排序/随机打乱顺序
二分查找 binarySearch(List<?> list, T key) 在已排序列表中二分查找(需先排序)
不可变集合 unmodifiableList(List list) / unmodifiableSet(Set s) 创建只读集合(任何修改操作抛异常)
线程安全集合 synchronizedList(List list) / synchronizedMap(Map<K,V> m) 将集合包装为线程安全版本(需手动同步迭代器)
特殊集合 singleton(T o) / nCopies(int n, T o) / emptyList() 创建单元素集合/N份拷贝集合/空集合
集合操作 reverse(List list) / swap(List list, int i, int j) 反转元素/交换位置
最值/频率 max(Collection coll) / frequency(Collection c, Object o) 找最大最小元素/计算元素出现次数

2.Arrays 工具类

专为操作数组设计的工具类,提供转换、排序、填充等能力。
核心功能:

方法类别 方法签名示例 作用
数组转集合 asList(T... a) 数组→固定大小List(与原数组共享内存!)
排序/二分查找 sort(int[] a) / binarySearch(int[] a, int key) 排序/二分查找(支持所有基本类型和对象数组)
比较/填充 equals(int[] a, int[] b) / fill(int[] a, int val) 数组内容比较/用指定值填充数组
流处理(Java8+) stream(T[] array) 数组转Stream(支持并行处理)
深度操作 deepEquals(Object[] a1, Object[] a2) / deepToString(Object[] a) 嵌套数组比较/嵌套数组转字符串(解决多维数组打印问题)
拷贝/截取 copyOf(T[] original, int newLength) / copyOfRange(T[] original, int from, int to) 复制数组/子数组
注:Arrays.asList() 返回的 List 是数组视图,修改元素会影响原数组。需要修改可以使用方案:new ArrayList<>(Arrays.asList(arr))修改新的List。
posted @ 2025-07-15 02:47  小心二次元T4z  阅读(20)  评论(0)    收藏  举报