集合


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());
}
posted @ 2023-08-21 11:09  lwx_R  阅读(2)  评论(0编辑  收藏  举报