collection与Map的总结
1.关系图:
collection(接口) Map
| |
—————————— ———————
| | | |
List Set | TreeMap
| | |
———— HashSet <----- HashMap
| |
ArrayList LinkedList
-----------------------------------------------------------------------------------------------------------------------
2.关系:
A.HashMap的实现:
HashMap是由数组与链表(LinkedList)实现的。
原理:先创建一个数组(array),然后创建array.size()个链表,让数组的每一项都存储一个链表 的地址。而通过存储key,value时,key.hashCode()分配一个哈希值对应array.size()中 的一个数,我们就把存入对象node存入数组对应项的链表中 (array[key.hashCode()]=node).
(可能有人疑惑了,我们不是put了key,value两个值吗?怎么存放的是object?其实我们会 将key,value封装为一个对象node存放在链表中。)
补充:a.hashCode()原理:
hashCode是一个根据key产生一个在数组大小的范围内的一个数。
eg.Object key,value
class Node(){
public Object key;
public Object value;
}
int[] array=new int[100];
LinkedList list=new LinkedList();
array[66]=list;
int i=key.mHashCode(); //假设返回的是66。
public int mHashCode(){
//模仿hashCode()
//先扩大范围,便于分散存储(id 为key的地址)
int k=id*32;
retrun k%100-1 //返回一个0到99的数
}
Node node =new Node();
node.key=key;
node.value=value;
LinkedList tmp=array[i];
最后将node加入到tmp的尾节点。
b.HashMap不能用相同的Key,如果用了,后面的value会覆盖前面的value:
上面a中mhashMap中的id有点特殊,因为如果里put两个(key1,value1) (key2,value2)后,但是key1与key2的值是一样的话,那么他们所生成的id就 是一样的,这就是为什么在hashMap不能用相同的Key,否则value2会覆value1
B.HashSet与HashMap的关系:
我们可以说hashSet是hashMap的是使用者。因为HashSet内部用了hashMap来存放数据的,那怎么 用的了?
首先我们说说hashSet和List都有相同的父类collection,但是它们两最大的区别是:HashSet里 不能存取两个相同的对象。下面是具体的解释:
前面我们说了HaseSet里用了HashMap来存储对象,是这么用的:
HaseSet hSet=new HashSet();
//在其内部
Node node =new Node();
node.key=key;
node.value=value;
hSet.add(node);
Object value1=null;
HashMap hMap=new HashMap();
hMap.put(node,vlaue1);
一位hashMap的key不能相同,故node不能想同.
即
node.key=key1;
node.value=value2;
hMap.put(node,vlaue1);
此时存进去的node的key=key1;value=value1;
------------------------------------------------------------------------------------------------------------------------------
3.关于remove()的坑
对于HashSet与HashMap不存在这个坑,但是对于ArrayList和LinkedList就有了,那坑是什么?坑在于我们remove了对象以后,此时我们遍历的游标指向的是remove对象的前一个对象。故我们循 环的时候要将循环数减1.
eg.
for(int i=0;i<b.size();i++){
String name=b.get(i).getName();
if(mname.equals(name)){
b.remove(b.get(i));
i--; //注意删除一项时,不能这个位子空着,所以让后面填在这里
}
}
当然我们用迭代器(Iterator)就没事了,它内部会帮你这个问题解决(HashSet与HashMap也可以)
而Iterator.remove删除游标所指对象的前一个对象。
Iterator itr=arrayList.iterator();
while(itr.hasNext()){
//因为iterator.next()返回当前对象值,并将游标指向下一位对象
String str=(String)itr.next();
//所以remove删除游标所指对象的前一个对象。
itr.remove();
//但不能连续调用itr.remove();因为其内部有一个记录其遍历时上一个对象变量。但我们
//第一次remove是,我们删除的是游标所指对象的前一个对象。故我们会把变量置为null;
//所以当我们连续第二次remove时会报对象为null;
}
-------------------------------------------------------------
4.hashMap的遍历:
http://blog.csdn.net/u010127245/article/details/50937384
-----------------------------------------------------------
5.IdentityHashMap
具有HashMap的特性:key,value。但不同的是:IdentityHashMap 的key值不能重复的是其地址不 能重复。而HashMap是key的内容不能一样(hashCode与equals)。所以其键值(key)必须为常量池 中的字符串;我们来看下例子:
IdentityHashMap<String,String> ihm=new IdentityHashMap<String,String>();
ihm.put("a","sdaas");
ihm.put("a","sdaasdas");
ihm.put(new String("a"),"sdasdas");
ihm.put(new String("a"),"sdffaas");
ihm.size();
(其结果为3,为什么?因为第二的一第一个的地址是一样的,而第三个与第四个是new的会当中不 同对象,其地址也就不同了,所以其键值(key)必须为常量池 中的字符串;)
-------------------------------------------------------------
6.枚举map
enum haha{
SPRING,SUMMER,AUTUMN,WINTER
}
public void test(){
EnumMap<haha,String> map=new EnumMap<haha,String>(haha.class);
map.put(haha.SPRING,"XIXI");
}
-----------------------------------------------------------------------
好吧,就这么多吧。加油,不再让自己失望。