Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
├HashSet
│ └LinkedHashSet
└SortedSet
└TreeSet
List接口:
List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置。用户能够用索引来访问List中的元素,List允许有相同的元素。
实现List接口的常用类有LinkedList,ArrayList,Vector和Stack
LinkedList类
LinkedList实现了List接口,允许null元素。此外LinkedList提供额外的get,remove,insert方法在LinkedList的首部或尾部。这些操作使LinkedList可被用作堆栈(stack),队列(queue)或者双向队列(deque)。
LinkedList没有同步方法。 如果多个线程同时访问一个List,则必须自己实现访问同步。一种解决办法是在创建List时构造一个同步的List:
List list=Collections.synchronizedList(new LinkedList(…));
LinkedList:链表实现,增删快,查询慢
ArrayList类
ArrayList实现了可变大小的数组,它允许所有元素,包括null。ArrayList没有同步。
数组实现,查询快,增删慢,线程不安全,轻量级;下标也是从0开始
和LinkedList一样,ArrayList也是非同步的(unsynchronized).
Vector类
Vector是同步的。
数组实现,线程安全,重量级
Stack类
Stack继承自Vector,实现后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个远在在堆栈中的位置。Stack刚创建后是空栈。
Set接口
Set是一种不包含重复元素的Collection,即任意的两个元素e1和e2都有e1.equals(e2) = false,Set最多有一个null。
Set实现的基础是map(hashmap)
Hashset:
Hashset的存储方式是把hashmap中的key作为set的对应存储项。
LinkedHashset:是Hashset一个子类,一个链表
Treeset:Sortedset的子类,它不同于hashset的根本就是treeset是有序的。是通过sortedmap来实现的。
Map
├Hashtable
├HashMap
└WeakHashMap
Map接口
Map没有继承Collection接口,Map提供key到value的映射。一个Map中不能包含相同的key,每个key只能映射一个value。Map接口提供3种集合的视图,Map的内容可以当作一组key集合,一组value集合,或者一组key-value映射。
HashTable类
Hashtable继承Map接口,实现一个key-value映射的哈希表。任何非空(non-null)的对象都可作为key或者value。
HashTable是同步的。
HashMap类
HashMap是非同步的,并允许nul,即null value,null key
WeakHashMap类
WeakHashMap是一种改进的HashMap,它对key实行“弱引用”,如果一个key不再被外部所引用,那么该key可以被gc回收。
总结:
如果涉及到堆栈,队列等操作,应该考虑用List,对于快速插入、删除元素,应该使用LinkedList,如果是需要快速随机访问元素,应该使用ArrayList。
如果程序在单线程环境运行,或者访问仅仅在一个线程中进行,考虑非同步的类,其效率较高,如果多个线程可能同时操作一个类,应该使用同步的类。
特别要注意对哈希表的操作,作为key的对象要正确复写equals和hashcode方法。
尽量返回接口而非实际的类型,如返回List而非ArrayList,这样如果以后需要可以将ArrayList换成LinkedList时,客户端代码不用改变。
同步性:
Vector是同步的,是线程安全的,而ArrayList是异步的,是非线程安全。同步的要求会影响执行的效率,所以如果不需要线程安全的集合那么使用ArrayList。
数据增长:
从内部实现机制来讲ArrayList和Vector都是使用数组(Array)来控制集合的对象。当向这两种类型中增加元素的时候,如果元素的数据超出了内部数组目前的长度塔门都需要扩展内部数组的长度。Vector缺省情况下自动增长原来一倍的数组长度,ArrayList是原来的50%,所以最好你获取的这种集合所占的空间总是比你实际需要的要大。所以如果你要在集合中保存大量的数据那么使用vector有一些优势,因为你可以通过设置集合的初始化大小来避免不必要的资源开销。