java SE ----- 集合以及集合的安全问题

一.java中集合的整体概述

1.常见集合
java SE ----- 集合以及集合的安全问题_第1张图片

2.集合和数组的区别?
集合的长度和是可变的,数组时不可变的,其次集合不能存储基本数据类型的数据,存储的都是对象。

3.集合的遍历
(1)Collection集合
<1>foreach遍历集合,但是不能一边遍历一边删除元素(存在线程安全问题)
<2>迭代器iterator遍历集合,可以一边遍历一边删除

(2)Map集合
<1>获取键key的集合:Set keySet()
<2>获取值value的集合:Collection values()
<3>获取Map集合的entry对象:Set> entrySet()

4.ArrayList
(1)jdk1.6 初始化集合时,直接将其大小初始化为10,后面每次扩容为原来的1.5倍。jdk1.7,1.8 初始化时,容量最开始为0,第一次当检测到有元素添加进集合而容量不足时,集合大小会由0变到10,后面再次检测到集合容量不够时,每次扩容为原来的1.5倍。
(2)当我们删除集合的元素时,集合不会因为元素的减少而自动缩小。但是集合ArrayList中有一个方法trimToSize()可以调整大小。

5.Set和存储顺序
加入Set的每个元素都必须是唯一的,因为Set不保存重复的元素。加入Set的元素必须定义equals方法以确保对象的唯一性。Set接口不保证维护元素的次序。
(1)HashSet 为了快速查找而设计的Set。存入HashSet的元素必须定义hashCode()。
(2)TreeSet 保持次序的Set,底层为树结构。使用它可以从Set中提取有序的序列。元素必须实现Comparable接口。
(3)LinkedHashSet 具有HashSet的查询速度,且内部使用链表维护元素的顺序(插入的顺序)。于是使用迭代器遍历Set时,结果会按插入的次序显示。元素也必须定义HashCode方法。
注意:必须为树形存储和散列存储都创建一个equals()方法,但是hashCode()只有在这个类将会被置于HashSet或LinkedHashSet中时才是必须的。

二.关于集合的一些底层原理

1.java快速失败机制
是集合的一种检查错误的机制,当多个线程对集合进行结构上的改变操作时,有可能会触发fail-fast机制。我们通过查看底层的源代码,发现当我们在用foreach或则获取迭代器Iterator对象时,会用ExpectedModCount记录当前集合被修改的次数ModCount的值,ExpectedModCount =ModCount ;如果在遍历过程中发现二则的值不相等,说明你用集合的add,remove等方法修改了了当前集合的元素,说明集合中的元素已经遭到了"破坏",为了保证数据的一致性,就会抛出ConcurrentModificationException异常。

2.HashMap
(1)jdk1.7时HashMap的底层为数组+链表,jdk1.8时为数组+链表/数组+红黑树
(2)HashMap底层的数组的初始化长度为多少以及扩容机制。jdk1.7中,
数组的初始化大小为为0,当第一次添加元素时,数组的大小会由0变为16。而后每当集合中元素的数量达到阈值(threshold)时并且当前将要存入数组的下标的值不为null,集合的大小会扩容为原来的2倍,否则当前次添加不会触发扩容。 threshold=table.length*0.75(DEFAULT_LOAD_FACTOR).
jdk1.8中 当链表的长度大于8时,并且table数组的长度大于等于64,将会由链表变为红黑树,如果数组的长度没有达到64,会先扩容。当红黑树中结点的个数小于6个时,又会由红黑树变为链表。
(3)HashMap底层数组下标的计算原理
当我们存入的元素的键(key)的值为null时,存在下标为0的位置。否则,先计算该存入元素的hash值,然后将hash值与(table.length-1)按位与运算,得到index的值。
(4)为什么数组的长度要保证2的幂次方?
只有当数组的长度为2的幂次方时,hash&(table.length-1)才会等价于h%table.length。
(5)jdk1.7中链表采用头插的方式,jdk1.8中链表采用尾插的方式。

三.集合的安全问题及解决方案

1.ArrayList的线程安全问题的解决方案
(1)可以使用老版的Vector集合,是线程安全的
(2)使用集合的工具类中的方法,Collections.synchronizedList(new ArrayList<>());
(3)使用CopyOnWriteArrayList<>()

2.Set集合安全问题的解决方案
使用java.util.concurrent包下的CopyOnWriteArraySet<>()

3.HashMap集合的安全问题的解决方案
使用ConcurrentHashMap<>()
java SE ----- 集合以及集合的安全问题_第2张图片
以上即是笔者关于集合方面知识的简单总结,如有错误还请批评指正。

你可能感兴趣的:(java)