Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap
Vector非常类似ArrayList,但是Vector是同步的。由Vector创建的Iterator,虽然和 ArrayList创建的Iterator是同一接口,
Set是一种不包含重复的元素的Collection,即任意的两个元素e1和e2都有e1.equals(e2)=false,Set最多有一个null元素。
很明显,Set的构造函数有一个约束条件,传入的Collection参数不能包含重复的元素。
请注意:必须小心操作可变对象(Mutable Object)。如果一个Set中的可变元素改变了自身状态导致Object.equals(Object)=true将导致一些问题。
Collection接口是Set接口和List接口的父接口,通常情况下不被直接使用,但定义了一些通用方法,通过这些方法可以实现对集合的基本操作。
Collection接口的常用方法如下:
1)add():向集合中添加对象
2)remove():向集合中移除对象
3)isEmpty():判断当前集合是否为空
4)iterator():返回迭代器,用于遍历集合中的对象
5)size():获取集合中元素的个数
6)clear():清空集合
7)contains():判断集合中是否存有指定的对象
8)addAll():把指定集合中所有的对象添加到集合中
map接口没有继承Collection接口L峁﹌ey到value的映射。map接口的常用方法如下:
1)clear():清空
2)isEmpty():判断集合元素是否为空
3)size():获取集合元素的个数
4)put(key k,value v):向集合中添加键值映射
5)get(Object key):返回指定键对象所对应的值
6)keySet():返回该集合中所有键对象形成的Set集合
7)values():返回该集合中所有值对象形成的Collecion集合
仅仅对于HashSet、HashMap之类的哈希表,“equals()的两个对象,hashcode()必须相等,否则,没用”是正确的。
JDK的所有哈希表均采用拉链法解决哈希冲突,当你调用put()方法的时候,JDK会先算出对象的hashcode(),如果此hashcode对 应的链表为空,则会直接插入;否则将遍历整个链表,依次调用已经存在的元素的equals()进行比较;如果equals()==true,则不插 入,break;当遍历完整个链表之后,说明这个链表所有对象的equals()==false,把新的对象插入到链表头部。
如果想使用JDK的哈希表,一般无需重写hashcode,因为Object自带的hashcode做的很好,在数据量不大的情况下,不会有任何冲突,CRUD的复杂度均为O(1)。
但当数据量非常大时,如:超过千万级,对象的hashcode难免会出现重复;如果数据量更大,则冲突会更加严重,哈希表的CRUD效率将逐渐退化为 O(sqrt(N))。此时,你就可以重写hashcode来减少冲突。或者重写compareTo方法,使用TreeMap,对于超大数据 量,TreeMap的效率是O(log2N),反而好于HashMap。
另外,最重要的,不要只从“重写”、“继承”等等肤浅的角度去分析问题,也不要轻信别人的回复(包括我的回复)、甚至ThinkingInJava、Java核心技术的相关解释之后,就把问题丢在一边;调试和分析JDK源码,才是掌握知识的最权威、最直接的方式!