java - HashMap,TreeMap
Map: 通过key可以直接定位到一个value值
存储方式key -value 键值对
key:无序不重复
value:无序可重复
// 无序:与存入顺序无关。
Map主要分类:
HashMap 散列表,性能高,基于散列表
TreeMap 性能低, 有排序(基于unicode,可以用来排序), 基于红黑树
Properties
HashMap: 75%容量时扩容
底层结构散列表:数组+链表
将key -value包装成一个对象Node extends Entry
底层比较使用的Node对象 的hashcode,但是不同的对象有可能产生相同的hashcode。
数组:储存的是对象的hashcode(int)
链:把对象根据hashcode值存在对应位置,以链表形式放在一起,如果两个对象算出的hashcode码相同,把第二个对象链在第一个对象Node的后面
寻找时根据hashcode在数组寻找,找到对应hashcode后遍历后面跟着的链表数据,这样可以快速的寻找到对应的对象。
(相当于根据hashcode把数据进行了分类,然后寻找起来效率更高)
package Map; import java.util.*; public class HashMapTest { public static void main(String[] args){ HashMap h = new HashMap(); h.put(1,"aaa"); //以key - value键值对的方式存入 h.put(2,"bbb"); h.put(2,"ccc");//key相同时,新的数据会覆盖旧的 h.put(3,"ccc"); h.put(4,"ccc");//value可以相同 h.put(0,123);//可以存不同类型的value h.put("a",111);//可以存不同类型的key h.putIfAbsent("a",222);//如果没有key = a 的则插入这个键值对,如果有了就不插入(用put会覆盖掉旧的) //排列顺序与存入顺序无关 System.out.println(h); //{0=123, 1=aaa, a=111, 2=ccc, 3=ccc, 4=ccc} System.out.println(h.remove(2));//根据key删除,并返回删除的value值 //ccc System.out.println(h.replace(4,"ddd"));//用key - new value修改对应value,返回old value System.out.println(h.replace(3,"ddd","eee")); //也可以用key,old value, new value修改返回是否修改成功,可以防止误操作。 System.out.println(h); //{0=123, 1=aaa, a=111, 3=ccc, 4=ddd} System.out.println(h.get("a"));//根据key返回value //111 //遍历:需要先遍历key然后获得对应value Set s1 = h.keySet(); //取到h的所有key返回一个set集合 for(Object o: s1 ){ //遍历set获得key System.out.print(h.get(o) + " "); //返回所有key对应的value } System.out.println(); //123 aaa 111 ccc ddd Set<Map.Entry> s2 = h.entrySet(); //取到h的所有key - value返回一个set集合 for(Map.Entry o: s2 ){ //遍历set获得key - value System.out.print("key = " + o.getKey() + ",value = " + o.getValue() + " " + "|"); //Entry内部结构包含了key和value以及对应的方法 } System.out.println(); //key = 0,value = 123|key = 1,value = aaa|key = a,value = 111|key = 3,value = ccc|key = 4,value = ddd| System.out.println(h.containsKey(1)); //是否包含这个key System.out.println(h.containsValue(111));//是否包含这个value //true //true h.clear(); //清空 System.out.println(h); //{} System.out.println(h.getOrDefault(111,"abc"));//找到key = 111返回对应value,找不到返回abc //abc //测试 //看了一下源代码,Entry的hashcode计算是key.hashcode ^ value.hashcode ^是异或 也就是说当key = value时,Entry的hashcode会为0 h.put(111,111); h.put(112,112); Set<Map.Entry> s3 = h.entrySet(); //取到h的所有key - value返回一个set集合 for(Map.Entry o: s3 ){ //遍历set获得key - value System.out.println("key = " + o.getKey() + ",value = " + o.getValue() + " " + ",hashcode = " + o.hashCode()); //Entry内部结构包含了key和value以及对应的方法 } //key = 112,value = 112 ,hashcode = 0 //key = 111,value = 111 ,hashcode = 0 //猜测成功-。- HashMap<Integer, String> hashMap = new HashMap<Integer, String>();//HashMap也可以使用泛型规定key和value的类型 //TreeMap //基本与HashMap一样,只是会自动排序(基于compareTo,根绝unicode),且key的类型必须一致。 TreeMap hm = new TreeMap(); hm.put(2,"b"); hm.put(1,"e"); hm.put(3,"d"); hm.put(5,"c"); hm.put(2,"f"); //有相同key时,后面的会覆盖前面的 hm.put(8,"a"); hm.put(7,"e"); //允许有value相同 //TreeMap中存的key必须一致,不然调用compareTo会报错 //比如: hm.put("a", true); key为String与上面int不一致且无法自动转化无法比较 //试了一下char也不行,比较时不能自动转化。 System.out.println(hm); //{1=e, 2=f, 3=d, 5=c, 7=e, 8=a} //内部按key的unicode排序
//Entry:
// Entry<K,V> left;
// Entry<K,V> right;
// Entry<K,V> parent;
// boolean color = BLACK;
//TreeMap的Entry不只是单纯的 key - value, 而是红黑二叉树
} }