List、Set和Map的区别
List和Set都实现了Collection接口,Map没有。
List:
-
可以允许重复的元素;
-
可以插入多个null元素;
-
是一个有序容器,保持了每个元素的插入顺序,输出顺序就是插入顺序;
-
常用的实现类有ArrayList、LinkedList和Vector
这三种的区别及实现原理:
(1)存储结构方面:ArrayList和Vector都是顺序存储,都是基于数组实现的。而LinkedList是基于双向链表实现的(含有头结点);
(2)线程安全性方面:ArrayList不具有线程安全性,在单线程的环境中,LinkedList也是不安全的。Vector是线程安全的,它的绝大多数方法都包含Synchronized关键字,但是它的效率没有ArrayList和LinkedList高;
(3) 扩容机制方面:ArrayList和Vector都是使用数组来存储元素,当容量不够时,会自动进行扩充,ArrayList扩充后的容量时原来的1.5倍,Vector是原来的2倍。
(4)性能方面:ArrayList和Vector中查询一个元素、在尾部插入或删除一个元素的时间复杂度都是O(1),如果是在其他位置删除或插入一个元素的时间复杂度为O(n)。LinkedList中插入或者删除任意位置的元素的时间复杂度都为O(1),但查询一个元素的时间复杂度为O(n)。
Set:
-
不允许有重复的元素(只要两个对象用equals方法比较返回true,Set就不会接受这两个对象);
-
只允许有一个null元素;
-
是一个无序容器,其中TreeSet是通过Comparator或者Comparable维护的一个排序顺序;
-
常用的实现类有HashSet、TreeSet和LinkedHashSet
(1)HashSet:是基于HashMap实现的。当向HashSet中存入一个元素时,HashSet首先会调用该对象的hashCode()方法,来得到该对象的hashCode值,然后根据hashCode值来决定该对象的存储位置;
(2)TreeSet:可以保证元素处于排序排序状态,TreeSet支持两种排序,自然排序和定制排序,默认为自然排序;
(3)LinkedHashSet:同样根据hashCode来决定元素的存储位置,但是它同时使用链表来维护元素的次序。
Map:
- Map集合中保存着两组值,一组用来保存key,一组用来保存value;
- Map中可以拥有相同的value,但key必须是唯一的;
- Map里可以拥有任意个数的null的value,但key只能拥有一个null;
- 常用的实现类有HashMap、LinkedListMap、TreeMap和Hashtable
(1)特点:HashMap和Hashtable不保证数据有序,LinkedHashMap保证数据可以保持插入顺序,而TreeMap可以按key的大小顺序排序;
(2)HashMap和Hashtable的区别:
a. Hashtable是一个古老的Map实现类,不建议使用;
b. Hashtable是一个线程安全的Map实现类,但HashMap是线程不安全的;
c. Hashtable不允许null作为key和value,但HashMap可以。