1.三大集合框架
1.1.集合和数组的区别
a.集合和数组都是容器
b.数组长度不可以改变,但是可以存储基本数据类型
c.集合的长度可变,但是不能存储基本类型数据,可以存储任意类型的对象
1.2.集合的共同特性
集合都可以添加一个对象,删除一个对象,查找一个对象,以及修改一个对象。
1.3.单列集合-Collection
相比所有集合都有特性,Collection接口下比较特殊的方法有,removeAll(),addAll(),containsAll(),这些方法所操作的对象变为了一整个集合。
1.4.List与Set-实现Collection接口的两个接口
他们最大的区别是:
a.List可存放重复元素,元素存取是有序的(即线性的)
b.set不可以存放重复元素,元素存取是无序的(不带自然顺序的时候需要我们重写equals方法才可以判断是否是相同的元素)
1.5.实现List的类
实现List的类有很多:AbstractList, AbstractSequentialList, ArrayList, AttributeList, CopyOnWriteArrayList, LinkedList, RoleList, RoleUnresolvedList, Stack, Vector
其中,ArrayList、LinkedList最为常用。
1.5.1.ArrayList
ArrayList最大的特点是查找快,增删慢,为什么会这样?查看源码,可以发现ArrayList的实现是依靠数组(Object[])的,也就是说,通过索引值,我们可以快速定位到某个元素,但是当我们增删的时候,因为数组在内存中是连续存放的,所以我们需要移动拷贝元素,当数组不够大时,还要考虑到扩容问题(ArrayList默认大小为10,每次扩容大约增长到原来的1.5倍),因此比较耗时。
1.5.2.LinkedList
LinkedList最大的特点是增删快,查找慢,通过查看源码,不难发现,LinkedList是通过双向链表实现的,在内存中存放是不连续的,删除或者增加元素的时候,只需要修改元素节点指向就可以了,但当我们需要查询元素时,只能一个个去遍历,所以效率较低。
1.5.3.Vector
Vector用法基本同ArrayList,但是值得注意的是Vector是线程安全的,ArrayList是线程不安全的。Vector基本上使用很少,但当我们使用合并流的时候,需要使用到Vector。
1.6.实现Set的类
Set接口中的方法与collection相比,并没有额外的功能。其中实现它的类有:AbstractSet, ConcurrentHashMap.KeySetView, ConcurrentSkipListSet, CopyOnWriteArraySet, EnumSet, HashSet, JobStateReasons, LinkedHashSet, TreeSet 。其中比较常用的有HashSet,LinkedHashSet,TreeSet 。
1.6.1.HashSet
HashSet的低层是依靠哈希表实现的,线程不安全,依靠hashCode方法来确定在内存中存放的位置。相比其他的Set,它的存取速度相对较快。
HashSet是如何判断元素是否相等?如下
If(hashCode得到的值与其他元素都不相同){
If(与hashCode得到的值相同的元素使用equals方法进行比较,结果为true){
两个元素为相同的元素!;
}
Else{
放进去的元素不重复!;
}
}
Else{
放进去的元素重复!;
}
因此,当我们使用 HashSet时,需要重写hashCode,equals方法。
1.6.2.TreeSet
TreeSet最大的特点是可以将放进去的元素进行排序,实现依靠红-黑树,因此当元素没有自然顺序的时候,我们需要实现Comparable接口或者实现一个比较器Comparator,重写compareTo或者compare方法。
1.6.3.LinkedHashSet
LinkedHashSet特点是会保存元素的插入顺序,线程不安全,依靠哈希表和链接链表实现。相对于HashSet,迭代速度相对快,但是插入相对慢。
1.7.双列集合-Map
与Collection对比:
a.Map中存放的是键值对,一个键对应一个唯一的值,但是一个值不一定只对应一个键。
b.同时类似Set,Map中的键也是唯一的。
c.取出元素时,不能直接取出,三种方法获取,(1)通过keySet拿到一个set,再通过set里面的key拿到相应的values;(2)通过values 拿到所有的values,但不能拿到key;(3)通过Entry获得一个Set
1.7.1.Hashtable
低层依靠哈希表实现,线程安全,效率较低。不可以放入null键,null值。
1.7.2.HashMap
与LinkedHashMap相比,同样是依靠哈希表实现,效率较高,但是线程是不安全的,可以放入null键,null值。类似于HashSet,判断元素是否重复时,我们需要重写hashCode方法,和equals方法。
1.7.3.LinkedHashMap
与LinkedHashSet类似,低层依靠哈希表和双重链接列表实现,线程不安全,可以保存输入的顺序,输出的时候可以按照输入的顺序输出。
1.7.4.TreeMap
低层同样依靠红黑树算法,同样需要Comparable或者Comparator 对key进行排序,线程不安全。
1.8.什么使用情况下使用对应的框架?
If(存放的是对象){
If(元素可以重复){
If(线程不需要安全的){
If(增删多,查询少){
使用LinkedList;
}
Else if(增删多,查询少){
使用ArrayList;
}
}
Else if(线程需要安全的){
使用Vector;
}
}
Else if(元素不可以重复){
If(需要对元素进行排序){
使用TreeSet;
}
Else if(不需要对元素进行排序){
If(需要保留存储顺序){
使用LinkedHashSet;
}
Else if(不需要保留存储顺序){
使用HashSet;
}
}
}
}
Else if(存放的是键值对){
If(需要对元素进行排序){
使用TreeMap;
}
Else if(不需要对元素进行排序){
If(需要保留存取顺序){
使用LinkedHashMap;
}
Else if(不需要保留存取顺序){
使用HashMap;
}
}
}