Collection、List、Set和Map都是接口(Interface),其中Collection是所有集合类的接口,Set和List也都实现该接口。
1.Set
Set是一种不包含重复的元素的无序Collection。 一般使用的有HashSet和TreeSet。
虽然Set同List都实现了Collection接口,但是他们的实现方式却大不一样。List基本上都是以Array为基础。但是Set则是在 HashMap的基础上来实现的,这个就是Set和List的根本区别。
HashSet:
通过HashCode来判断存储位置,所以对象必须实现hashCode()方法,存储的数据无序不能重复,可以存储null,但是只能存一个。
public boolean add(Object obj) {
return map.put(obj, PRESENT) == null;
}
add函数决定了,再set中不能由重复的元素。如果使用add(Object obj)方法添加已经存在的对象,则会覆盖前面的对象
LinkedHashSet
是HashSet的一个子类,严格按照插入的顺序进行存储,其内部使用LinkedHashMap实现,所以可以做到有序。当所存数据需要有序存储时,使用LinkedHashSet代替HashMap。
LinkedHashMap时非线程安全的。
TreeSet
TreeSet是SortedSet的子类,与HashSet的最根本区别就是其是有序的。
SortedSet由SortedMap实现,TreeSet是根据二叉树实现的,也就是TreeMap,元素不能重复,不能为null,可以重写comparator()来进行升序降序。
2.List
ArrayList
基于数组实现,对于插入的元素按顺序存储,ArrayList插入数据可以重复,也是有序的,按照插入的顺序来排序。,非线程安全。
适用于较小数据量的存储,每次扩容扩其50%的容量,由于非线程安全,所以效率较高。
对于数据的随机get和set或是少量数据的插入或删除
Vector
基于数组实现,但是线程安全。
每次扩容扩其一倍的容量,由于线程安全,所以效率较低。
LinkedList
基于链表的双向链表实现
对于数据的插入删除,无需像ArrayList进行大量的数据移动。
获取数据的方式:二分查找
如果序号小于链表长度的一半,则顺序查找,若大于链表的一半则从尾部进行遍历,直到找到所需元素。
3.queue
LinkedList
通过双向链表实现队列
PriorityQueue
基于堆结构实现,可以用它来实现优先队列。
4.Map
Map是将键和值进行关联的容器,一个键只能对应一个值,但一个值可以被多个键对应。同时一个键可以对应一个Map对象。
若某个键对应的值发生变化,按最后一次修改的为准。
同Set键值不能重复,为了防止数据访问存储过程中发生混乱。
HashMap
HashMap通过散列表实现,其存储没有固定顺序,非线程安全,键值可以为null。
根据Key算出Index,若index相同,则在该位置已链表的形式存储。
LinkedHashMap
LinkedHashMap继承自HashMap,特点是内部存入数据是有顺序的,增加了记住元素插入或者访问顺序的功能,这个是通过内部一个双向的循环链表实现的。与 HashMap 一样,它可以为基本操作(add、contains 和 remove)提供稳定的性能,假定哈希函数将元素正确分布到桶中。由于增加了维护链接列表的开支,其性能很可能比 HashMap 稍逊一筹,不过这一点例外:LinkedHashMap 的 collection 视图迭代所需时间与映射的大小 成比例。HashMap 迭代时间很可能开支较大,因为它所需要的时间与其容量 成比例。
HashTable
于HashMap类似,但键值不可以为Null,且线程安全,但是HashTable效率较低,现在基本不使用。
若想实现线程安全可通过HashMap手动加synchronized来进行线程同步。
TreeMap
TreeMap的使用大致跟HashMap类似,但是内部实现是根据红黑树来实现的。红黑树是一种平衡有序的二叉树,TreeMap的插入删除查询都是依据红黑树的规则来进行的。