Java集合

一、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的区别

你可能感兴趣的:(Java集合)