集合
1.List
1.1 ArrayList
内部数组实现,可以快速随机访问。数组大小不满足时,已有数组复制到新的空间中。适合查找遍历。
线性安全 Collections.synchronizedList
List synchronizedList = Collections.synchronizedList(new ArrayList<>());
ArrayList扩容机制
1、添加元素时,首先进行判断是否大于默认容量10
2、如果,小于默认容量,直接在原来基础上+1,元素添加完毕
3、如果,大于默认容量,则需要进行扩容,扩容核心是grow()方法
3.1 扩容之前,首先创建一个新的数组,且旧数组被复制到新的数组中
这样就得到了一个全新的副本,我们在操作时就不会影响原来数组了
3.2 然后通过位运算符将新的容量更新为旧容量的1.5陪
3.3 如果新的容量-旧的容量<=0,就拿新的容量-最大容量长度如果<=0的,那么最终容量就是扩容后的容量
1.2 Vector
数组实现,支持线程同步,因此访问慢,线程安全
1.3 LinkedList
链表结构,适合插入删除,有操作表头,表尾的方法,当做栈,队列,双向队列使用,线程不安全
2.Set
对象相等性是对象hashCode值(根据内存地址计算),俩个对象相同,必须覆盖hashCode和equals方法
2.1 HashSet
线程不安全
HashSet 首先判断两个元素的哈希值,如果哈希值一样,接着会比较
equals 方法 如果 equls 结果为true ,HashSet 就视为同一个元素。如果equals 为false 就不是同一个元素。
2.2 TreeSet
底层红黑树
- 按照二叉树原理对add新对象排序
- 自定义对象必须实现Comparable接口且覆盖compareTo函数
2.3 LinkedHashSet
使用LinkedHashMap保存元素,继承HashSet,方法上与其相同
3.Map
3.1 HashMap
- 根据键的hashCode 值存储数据
- 非线程安全,使用Collections 的synchronizedMap或ConcurrentHashMap
HashMap 默认的初始化⼤⼩为16。之后每次扩充,容量变为原来的 2 倍。
创建时如果给定了容量初始值, HashMap 会将其扩充为 2 的幂次⽅⼤⼩
3.1.1 Java 7实现
整体是数组,数组中每个元素是单向链表,扩容后为当前2倍
根据hash值定位到数组下标,但是需要顺着链表一个个比较下去才能找到我们需要的,时间复杂度取决于链表的长度,为 O(n)
3.1.2 Java 8实现
链表元素超过8个,将链表转化为红黑树。O(logN)
3.2 ConcurrentHashMap
整个 ConcurrentHashMap 由一个个 Segment 组成,Segment 代表”部分“或”一段“的意思,所以很多地方都会将其描述为分段锁。
3.2.1 线程安全
Segment 通过继承ReentrantLock 来进行加锁,所以每次需要加锁的操作锁住的是一个 segment,这样只要保证每个Segment 是线程安全的,也就实现了全局的线程安全。
3.2.2 Java7
- 并行度concurrencyLevel:默认16,有16个segments段,最多支持同时16个线程并行写,该参不可扩容
3.2.3 Java8
引入红黑树
3.3 HashTable
遗留类
3.4 TreeMap
实现SortedMap接口,默认按key升序排序,必须实现Comparable接口或构造TreeMap时传入Comparator
3.5 LinkedHashMap
保存记录插入顺序
4.Collection工具类
4.1 排序
void reverse(List list)//反转
void shuffle(List list)//随机排序
void sort(List list)//按⾃然排序的升序排序
void sort(List list, Comparator c)//定制排序,由Comparator控制排序逻辑
void swap(List list, int i , int j)//交换两个索引位置的元素
void rotate(List list, int distance)//旋转。当distance为正数时,将list后
distance个元素整体移到前⾯。当distance为负数时,将 list的前distance个元
素整体移到后⾯
4.2 查找和替换
int binarySearch(List list, Object key)//对List进⾏⼆分查找,返回索引,
注意List必须是有序的
int max(Collection coll)//根据元素的⾃然顺序,返回最⼤的元素。 类⽐int
min(Collection coll)
int max(Collection coll, Comparator c)//根据定制排序,返回最⼤元素,排序
规则由Comparatator类控制。类⽐int min(Collection coll, Comparator c)
void fill(List list, Object obj)//⽤指定的元素代替指定list中的所有元素。
int frequency(Collection c, Object o)//统计元素出现次数
int indexOfSubList(List list, List target)//统计target在list中第⼀次出现
的索引,找不到则返回-1,类⽐int lastIndexOfSubList(List source, list
target).
boolean replaceAll(List list, Object oldVal, Object newVal), ⽤新元素替
换旧元素
5.其他问题
5.1 快速失败
快速失败(fail-fast) 是 Java 集合的⼀种错误检测机制。
在使⽤迭代器对集合进⾏遍历的时候,我们在多线程下操作⾮安全失败(fail-safe)的集合类可能就会触发 fail-fast 机制,导致抛出
ConcurrentModificationException 异常。
另外,在单线程下,如果在遍历过程中对集合对象的内容进⾏了修改的话也会触发 fail-fast 机制。
不要使用foreach进行remove/add操作,要使用迭代器
5.2.安全失败
采⽤安全失败机制的集合容器,在遍历时不是直接在集合内容上访问的,⽽是先复制原有集合内容,在拷⻉的集合上进⾏遍历。
所以,在遍历过程中对原集合所作的修改并不能被迭代器检测到,故不会抛ConcurrentModificationException 异常。
5.3.Arrays.List
传递的数组必须是对象数组,⽽不是基本类型。
Arrays.asList() 是泛型⽅法,传⼊的对象必须是对象数组。
使⽤包装类型数组就可以解决这个问题
6.迭代器
6.1 遍历
Iterator<Map.Entry<Integer, Stringef iterator =
map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<Integer, String> entry = iterator.next();
System.out.println(entry.getKey() + entry.getValue());
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律