2026/4/6
集合体系
单列集合: 一次只能存一个对象
Collection 顶层接口
- List 有序/有索引/可重复
ArrayList: 数组
LinkedList: 链表
- Set 无序/无索引/不可重复
TreeSet: 红黑树
HashSet: 哈希表
LinkedHashSet
双列集合: 一次可以存两个对象,一一对应
Map 顶层接口
TreeMap
HashMap
LinkedHashMap
Collection:
void add(E e) 添加元素
boolean remove(E e) 删除指定元素,通过集合中对象的equals()方法,判断元素是否相同
boolean contains(E e) 判断是否包含指定的元素,通过集合中对象的equals()方法,判断元素是否相同
boolean isEmpty() 判断集合中的是否有元素 有-false 没有-true
void clear() 清空集合所有元素
int size() 获取集合的元素的个数
遍历: 就是将集合中的元素,一个一个拿出来的过程。
1. 普通for循环
必须要有get()方法。
2. 迭代器 Iterator
Iterator it = 集合.iterator() // 获取迭代器对象
while(it.hasNext()){ // 判断是否还有下一个元素
it.next(); // 获取集合的元素,并移动指针
}
3. 增强for 语法糖
for(元素类型 元素对象 : 容器对象){
// 操作元素对象
}
底层就是普通for和迭代器。
4. foreach
参数: Comsuer 接口
5. ListIterator
ListIterator是Iterator的子接口,比Iterator要更牛逼。
删除:Iterator remove()
添加和删除/倒着遍历:ListIterator remove() add()
方法引用:
你在使用lambda完全某些事情的时候,有那么一个方法可以帮你全部完成,则可以将该方法引用过来。
List:有序/有索引/可重复
ArrayList: 数组
LinkedList: 链表
特有方法:
void add(index,e) 在某个索引位置插入元素
E remove(index) 删除指定索引的元素,并返回被删除元素
E set(index,E) 替换index出的元素,返回被替换元素
E get(index) 获取指定索引处的元素
并发修改异常:
不能在使用迭代器遍历集合的同时,使用集合对象,操作集合的元素个数。
所以只能使用迭代器自己的方法完全增删操作。
增强for也会出现这个问题,因为它底层就是迭代器。
数据结构:
栈:先进后出
队列:先进先出
数组:查询快,增删慢
链表:查询慢,增删快 特别是首尾元素
2026/4/7
1. 泛型
是一种未知的数据类型。
当我们定义类/方法/接口中,有方法参数或者变量类型不明取,则可以使用泛型代替。
使用者,使用时,指定泛型的具体类型,则类中所有的泛型,都会变成指定的类型。
好处:
1. 避免类型转换
2. 将运行阶段异常,提前到了编译阶段
泛型类:
class MyClass<T>{}
MyClass<String> m = new MyClass();
泛型方法:
public static <T> T show(T t){}
integer a = show(123);
String s = show("abc");
泛型接口:
interface Inter<T>{
void show(T t);
}
class MyInter implements Inter<String>{
public void show(String s){}
}
class MyInter<T> implements Inter<T>{
public void show(T s){}
}
通配符:
?: 任意类型
限制方法内部,只读
? extends E:
E或者E的子类
? super E:
E或者E的父类
2. Set
特点:
无序/去重/无索引
TreeSet: 去重+排序
红黑树,增删改查效率比链表高的一种数据结构。
红黑树:底层采用二分查找法。
比较器:
自然排序: Comparable<T>
compareTo(T t){
this - t: 正序
t - this: 降序
0: 去重
}
比较器排序:Comparator<T>
compare(T o1,T o2){
o1 - o2: 正序
o2 - o1: 降序
0: 去重
}
两个比较器同时存在,优先使用比较器排序。
HashSet: 去重
哈希表:
JDK8以后:
数组 + 链表 + 红黑树
数组:存储哈希桶
链表(哈希桶):存取元素
红黑树:链表数量超过8,且数组长度 >= 64,则转成红黑树,以提高查询效率。
当红黑树节点数量少于6,则转回链表。
加载因子 0.75:用来计算扩容的阈值
加载因子 * 数组长度 = 阈值
扩容系数:2
当哈希桶数量达到阈值,则扩容,为之前数组长度的2倍。
扩容后,会对哈希桶的元素进行二次哈西,为了减少哈希桶内元素个数。
哈希值:
作用:
1. 计算元素存入数组的索引位置(哈希桶)。
2. 判断元素是否重复。
就是一个int类型数据值。
有hashCode()方法计算出来的。
如果不重写该方法,则调用Object对象中的方法,根据对象地址值,生成一个哈希值。
不同对象(属性相同),通过Object的hashCode方法,生成的哈希值不同。
而我们认为属性相同的对象,就是同一个对象。
所以我们要重写hashCode()方法,根据属性值,生成哈希值。
去重:
hashCode()和equals()方法实现。
存入元素,先计算哈希值,然后根据哈希值获取数组索引位置。
判断位置是否有元素,如果为null,则直接存入。
如果有元素,则与哈希桶内所有元素进行逐一比较:
先比较哈希值,如果哈希值不同,则直接存。
如果哈希值相同,则比较equals()
相同,不存入
不同,存。
LinkedHashSet: 去重+有序
哈希表 + 双向链表:
通过双向链表用来保证数据的存取有序。
3. Collections
集合工具类,提供很多方便操作集合的方法。
addAll() 批量添加元素
shuffler() 打乱集合元素
max/min() 获取最大值和最小值 前提:集合中元素,必须实现自然排序
sort() 排序,也可以通过传入比较器的方式进行指定规则排序
可变参数:
就是一个数组。
调用者,可以传0个或多个参数。
注意:
1. 只能有一个可变参数
2. 必须在末尾
4. Map
双列集合
键值对集合
一个键对应一个值。
只能键找值。
键不能重复,值随意。
存入的键值对,会封装成一个Entry对象,也称之为键值对对象。
put() 添加键值对
remove() 根据建删除键值对,返回值
clear() 清空
isEmpty() 判断是否为空
size() 个数
containsKey() 判断是否包含指定的键
containsvalue() 判断是否包含指定的值
遍历:
keySet()+get()
先获取所有的键,然后通过键一个一个找值
entrySet() + getKey() getValue()
先获取所有键值对对象,再获取每一个entry对象的键和值
foreach()
就是把上面第二种方式的代码,它帮你写了,你只需要做你想做的。