Java集合框架
在Java语言中,Java语言的设计者对常用的数据结构和算法做了一些规范(接口)和实现(具体实现接口的类)。
所有抽象出来的数据结构和操作(算法)统称为Java集合框架(JavaCollectionFramework)。---->所有集合底层几乎都是数组,有的是链表(LinkedList)。
作用:1.减低了程序员的工作量
2.提供了高性能的数据结构和算法实现
3.减少了学习,设计和实现API的工作量
Collection(继承了Iterable接口)和Map是两个顶级接口,所有的接口和实现类都直接或者间接实现了这两个接口。
常用的接口用List,Set,Map
List:集合元素是有序的并且是允许重复,
ArrayList:
LinkedList:
ArrayList和LinkedList的异同?
1.ArrayList和LinkedList都是不同步的,也就是不保证线程安全;
2.ArrayList底层使用的是Object数组,而LinkedList底层使用的是双向循环遍历链表;
3.ArrayList采用的数组存储,所以插入和删除元素的时间复杂度受元素位置的影响,而LinkedList采用的是链表存储,不受影响。
4.ArrayList实现了RandomAccess接口,所以支持快速随机元素的访问(通过元素的序号快速获取元素对象),而LinkedList不支持,
ArrayList和Vector的区别:Vector类的所有方法都是同步的,可以两个线程安全地址访问一个Vector对象,但是比较耗时。
List集合的主要方法有:
查:get(int index)
增:add(E)/add(int E)
删:remove(E e)
改:set(int index,E e)
Set:集合元素是无序的并且是不允许重复的。几乎所有的Set实现都是基于同类型Map的,简单地说,Set是剪切版的Map。
每个Set内都有一个同类型的Map实例(CopyOnWriteArraySet除外,它内置的是CopyOnWriteArrayList实例),Set把元素作为
key存储在自己的Map实例中,value则是一个空的Object。
HashSet:集合元素是无序的并且是唯一的,基于HashMap实现的,底层采用HashMap来保存元素。
LinkedHashSet:继承于HashSet,内部是通过LinkedHashMap来实现的。
TreeSet:集合元素是有序的并且是唯一的,红黑树
Map:是在Collection接口的基础上,为其中的每一个对象指定了一个key,并使用Entry保存每个key-value对,以实现通过key快速定位到对象(value)。
JDK1.8之前底层是由数组+链表组成的,数组使主体,而链表则是主要为了解决哈希冲突。
解决哈希冲突的方法有:
拉链法(也叫链地址法):指的是在数组后创建一个链表,当产生哈希冲突时就将冲突的哈希值添加到链表中。
开放地址法:如果出现了哈希冲突,就重新探测一个空闲位置,将其插入
当出现非常极端情况,也就是所有的哈希值相同时,会变成一条链表,而链表的查询速度较慢,所以就添加了红黑树,
JDK1.8之后底层是由数组+链表+红黑树组成,当链表长度大于8时,会将链表转换为红黑树,以减少搜索时间。
HashMap:JDK1.8之后底层是由数据+链表+红黑树组成的,线程是不安全的。
HashTable:跟HashMap几乎一样,不过HashTable是线程安全的。
LinkedHashMap:继承于HashMap,底层跟HashMap一样,不过LinkedHashMap增加一条双向链表,
可以保持键值对的插入顺序,实现了访问顺序的相关逻辑。
TreeMap:红黑树
ConcurrentHashMap:是HashMap的线程安全版(JDK1.5引入),提供了比Hashtable更高效的并发性能。是由
Segement数组结构和HashEntry数组结构组成。Segement实现了ReentrantLock,所以是一种可重入锁,扮演锁的角色。HashEntry用于存储键值对数据。
一个ConcurrentHashMap里包含了一个Segement数组。Segement的结构和HashMap类似,是一种数组+链表的结构,一个Segement包含了一个HashEntry
每个HashEntry使一个链表结构的元素,每个Segement守护一个HashEntry数组里的元素,当对HashEntry数组的数据进行修改时,必须获得对应的Segement的锁。
Map接口的主要方法有:
size():集合内的对象数量
put(K,V)/putAll(map):向Map内添加单个/批量对象
get(K):返回key对应的对象
remove():删除key对应的对象
keySet():返回包含Map中所有key的Set
values():返回包含Map中所有value的Collection
entrySet():返回包含Map中所有的key-value对的Entry
containsKey(K)/containsValue(V):判断Map中是否存在指定key/value。
面试题:HashMap VS Hashtable VS ConcurrentHashMap
1. 三者在数据存储层面的机制原理基本一致;
2.HashMap,线程是不安全的,多线程环境下除了不能保证数据一致性之外,还有可能在rehash阶段引发Entry链表成环,导致死循环;
3.Hashtable,线程是安全的,能保证绝对的数据一致性,但是性能是问题,并发线程越多,性能越差
4.ConcurrentHashMap也是线程安全的,使用分离锁和volatile等方法极大地提升了读写性能,同时也能保证在绝大部分情况下的数据
一致性。但不能保证绝对的数据一致性,在一个线程向Map中加入Entry的操作没有完全完成之前,其他线程有可能读不到新加入的Entry。