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, 而是红黑二叉树
} }

 

posted @ 2019-10-07 14:34  不咬人的兔子  阅读(158)  评论(0编辑  收藏  举报