java的集合类
List: ArrayList LinkedList Vector
Set: HashSet
Map:HashMap ConcurrentHashMap HashTable
ArrayList与LinkedList的区别?
底层实现不一样: 一个是数组 一个是双向链表
ArrayList 线程安全吗? 如何变得线程安全?
线程不安全,比如 执行add方法时,可能会发生数据的覆盖。
1)用Vector (通过synchronized方法来实现线程安全)
2) 用Collections.synchronizedList<List<>> ( 在外层加了一个synchronized 代码块 )、
3)用 CopyOnWriteArrayList ( 用ReentrantLock , 每次写操作时进行加锁处理,对读操作不加锁 )
HashMap:
初始容量为16, 负载因子 0.75 ,阈值=容量*负载因子
底层数据结构: 数组+链表+红黑树 (数组: 用于hash 链表: 当发生hash碰撞的时候,采用链地址法解决hash碰撞 红黑树:防止hash碰撞严重的时候,链表过长,导致查询效率下降)
put一个元素的过程:
先获取这个元素的 hashCode ,将得到的hashCode的高低16位进行异或操作,得到的结果就是hash值
将hash值与数组长度-1进行与操作,相当于对数组长度进行取余操作,采用二进制运算,效率更高。
看下标所对应的数组的位置是否为null, 如果为null,则将要插入的元素放在该位置。
如果非空,则比较他们的hash值是否相等;如果相等则比较它们的key是否相等(用的equals方法),如果相等,则相当value的值为当前值。
(这也就是为什么修改了 equals()方法,必须要修改hashCode( ) 方法)
如果不相等,则往下遍历,重复这个操作。
Node结点中,存储的哪些内容: hash、key、value、next(存储下一个结点,用于链表使用)
resize() 扩容:
当Map中的元素个数大于阈值时,就要进行扩容;每次扩容变为原来的两倍,然后将原来的元素移动到新的Map中。元素移动的时候,新的下标的位置,要么在原来的下标位置,要么是 原来的下标位置+原来的数组长度!!!
ConcurrentHashMap:
是线程安全的。
底层的数据结构是: 数组+链表+红黑树
对数组中的结点通过synchronized进行了加锁,并发度比 jdk1.7高,jdk1.7好像是对分段数组加锁。
HashSet:
HashSet的底层就是HashMap实现的!!!
HashSet传入的值作为HashMap的key, 用 new Object() 作为value, 因此 HashSet中的值是不重复的,因为HashMap中的key是不重复的!
LinkedHashMap:
TreeMap:
浙公网安备 33010602011771号