一、List、Set、Map的区别。
List:
1. 可以有重复的对象。
2. 允许存放多个null元素。
3. 有序,保证了每个元素的插入顺序。
4. 常用的实现类有 ArrayList、LinkedList 和 Vector。ArrayList 最为流行,它提供了使用索引的随意访问,而 LinkedList 则对于经常需要从 List 中添加或删除元素的场合更为合适,Vector是线程同步的。
Set:
1. 不允许重复对象
2. 只允许一个null元素
3. 无序,无法保证每个元素的存储顺序。
4. 常用的实现类有HashSet、LinkedHashSet 以及 TreeSet。最流行的是基于 HashMap 实现的 HashSet;TreeSet 还实现了 SortedSet 接口,因此 TreeSet 是一个根据其 compare() 和 compareTo() 的定义进行排序的有序容器(TreeSet不允许null值,因为比较时会出现空指针异常)。LinkedHashSet使用LinkedList维护了插入元素的先后顺序。
Map:
1. Map不是Collection的一个子接口或实现类,它是一个接口。
2. Map的每个Entry都持有两个对象,分别是键和值,Map可能会有相同的值对象,但键对象是唯一的。
3. ThreeMap通过Comparator或Comparable维护了一个排序顺序。
4. Map里可以有多个null值,但只能由一个null键
5. Map 接口最流行的几个实现类是 HashMap、LinkedHashMap、Hashtable 和 TreeMap。(HashMap、TreeMap最常用)
参考:List、Set、Map的区别
二、ArrayList、LinkedList、Vector的区别。
1. ArrayList是最常用的,内部是通过数组实现,它允许对子元素快速随机访问。数组的存储空间是连续的,所以当数组大小不足以满足存储需求时,就要将已有数组的数据复制到新的数组中。当从数组中插入,删除元素时,需要对数组进行复制、移动,代价较高。因此,它适合随机查找和遍历,不适合插入和删除。
2. Vector和ArrayList一样是通过数组实现的,不同的是Vector支持线程的同步。实现线程的同步需要很高的花费,因此,访问它比访问ArrayList慢。
3. LinkedList是用链表来存储数据的,很适合数据的动态插入和删除,但随机访问速度比较慢。另外,它还提供了专门用于操作表头和表尾元素,可当做堆栈,队列、双向队列使用。
关于ArrayList和Vector区别如下:
1 . ArrayList在内存不够时默认是扩展50% + 1个,Vector是默认扩展1倍。
2 . Vector提供indexOf(obj, start)接口,ArrayList没有。
3 . Vector属于线程安全级别的,但是大多数情况下不使用Vector,因为线程安全需要更大的系统开销。
ArrayList和LinkedList的区别如下:
1.对ArrayList和LinkedList而言,在列表末尾增加一个元素所花的开销都是固定的。对 ArrayList而言,主要是在内部数组中增加一项,指向所添加的元素,偶尔可能会导致对数组重新进行分配;而对LinkedList而言,这个开销是 统一的,分配一个内部Entry对象。
2.在ArrayList的 中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;而在LinkedList的中间插入或删除一个元素的开销是固定的。
3.LinkedList不支持高效的随机元素访问。
4.ArrayList的空 间浪费主要体现在在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在每一个元素都需要消耗相当的空间
可以这样说:当操作是在一列 数据的后面添加数据而不是在前面或中间,并且需要随机地访问其中的元素时,使用ArrayList会提供比较好的性能;当你的操作是在一列数据的前面或中 间添加或删除数据,并且按照顺序访问其中的元素时,就应该使用LinkedList了。
所以,如果只是查找特定位置的元素或只在集合的末端增加、移除元素,那么使用Vector或ArrayList都可以。如果是对其它指定位置的插入、删除操作,最好选择LinkedList。
参考:Vector,ArrayList,LinkedList的区别与适用场景
三、CopyOnWriteArrayList的了解。
CopyOnWrite容器即写时复制容器,用于并发读写。对CopyOnWriteArrayList进行写操作的时候,会复制出一份数组出来,写入新数据,写入完成后再把指针指向修改后的数组。写入前和写入中对CopyOnWriteArrayList读操作读到的都是未修改的数组。因为进行了并发处理,写操作耗时较长,比较适合读多写少的应用场景。
一些特点:
1. 读写分离。2.数据最终一致性。3.使用另外开辟空间的思路,解决并发冲突。
存在的问题:
1. 因为每次写都会复制一份出来,占用内存,可能会造成频繁gc。
2. 不能保证数据的实时一致性。
参考:
聊聊并发-Java中的Copy-On-Write容器
线程安全的CopyOnWriteArrayList介绍
四、HashMap和HashTable的区别。
1. HashTable是java1.1中加入的,HashMap是java1.2中加入的。
2. HashMap支持键和值为null,HashMap将null的hashCode值定为了0。
3. java7和之前,他们的哈希桶的内部实现是一致的,在java8中,默认链表长度大于8时HashMap内部实现转换为红黑树。
4. 初始容量大小和每次扩充容量大小的不同。HashTable默认的初始大小为11,之后每次扩充为原来的2n+1。HashMap默认的初始化大小为16,之后每次扩充为原来的2倍。
5.HashTable线程安全,HashMap线程不安全。因为HashTable在公开方法都加了Synchronized描述符。
参考:HashMap 和 HashTable 到底哪不同 ?
五、HashMap和ConcurrentHashMap的区别,HashMap的底层源码。
HashMap:内部实现是数组和链表,通过计算key的hash值来确定entry在数组中的位置,如果对应位置已存在entry,则这插入到现存entry的前面,形成链表。
ConcurrentHashMap:在HashMap的基础上,将数据分成了多个段,默认16个(concurrency level),每次操作锁住一个segment,避免多线程锁的几率, 提高并发操作效率。
参考及更多:HashMap源码分析
Java8系列之重新认识HashMap
ConcurrentHashMap的锁分段技术
六、TreeMap、HashMap、LindedHashMap的区别。
TreeMap:遍历顺序为根据键的大小排序后的顺序,需要key类实现Comparable或构造方法中传入Comparator比较器。
LinkedHashMap:保证了遍历顺序为存放顺序,也可以在构造参数中指定跟据对key进行操作的时间排序,时间最近的在最后。
HashMap : 键值对。保证键唯一性,值可以重复。遍历顺序无序。
参考:https://blog.csdn.net/fg2006/article/details/6411200
七、Collection包结构,与Collections的区别。
Collection是Collection层次结构中的根接口,继承了Iterable。常用子类有List、Set,List的子类又有ArrayList、LinkedList、Vector。Set的子类有HashSet、LinkedHashSet、TreeSet。
Map是一个单独的接口,直接子类AbstratMap,间接子类有HashMap、LinkedHashMap、TreeMap、ConcurrentHashMap等。
Collections是一个辅助Collection框架的工具类,由在 collection 上进行操作或返回 collection 的静态方法组成。
参考:介绍Collection框架的结构;Collection 和 Collections的区别