带你们看下Map源码,Map底层使用,深入底层源码思考问题

2021/7/9 9:07:22

本文主要是介绍带你们看下Map源码,Map底层使用,深入底层源码思考问题,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

     下面我们结合Map源码讲解下Map的使用,比较简单的API方法我们就不在这里叙述了,下面开始我的的Map集合之旅。

目录

getOrDefault

forEach

merge 

putIfAbsent

computeIfAbsent

 computeIfPresent

put

compute

getOrDefault

 V getOrDefault(Object key, V defaultValue) 方法:
如果map集合存在该key,或者key对应的value不为空,就返回对应的value,否则返defaultValue

看一个demo例子

        Map map = new HashMap();
        map.put("1",11);
        Object rs =  map.getOrDefault("2",22);

        rs结果你认为是多少,上面我们已经说过了,显而易见结果是22,因为map里不存在key=2,所有 返回默认值。

forEach

 void forEach(BiConsumer<? super K, ? super V> action) 
就是变量输出map数据 

demo: 

    map.forEach(new BiConsumer() {
          @Override
          public void accept(Object o, Object o2) {
              System.out.println("key:"+o+"  value:"+o2);
          }
      });

merge 

default V merge(K key, V value,
        BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
    Objects.requireNonNull(remappingFunction);
    Objects.requireNonNull(value);
    V oldValue = get(key);
    V newValue = (oldValue == null) ? value :
               remappingFunction.apply(oldValue, value);
    if(newValue == null) {
        remove(key);
    } else {
        put(key, newValue);
    }
    return newValue;
}

合并,如果map里的key不存在或者key对应的value为空,在map里插入一对数据,value不可为null,如果map存在key且key对应的value不为空,就建立map对应key的value和传入的value之间的映射,可以对两个value求和并重新复制给key 

demo:

        Map<String, Integer> map = new HashMap();
        map.put("1",11);
        map.put("2",112);
        map.put("12",1);

        map.merge("12", 11   , (older,newvalue)->older+newvalue);
        map.forEach((o, o2) -> System.out.println("key:"+o+"  value:"+o2));

 输出结果:

key:1  value:11
key:12  value:12
key:2  value:112

putIfAbsent

@Override
public V putIfAbsent(K key, V value) {
    return putVal(hash(key), key, value, true, true);
}

返回覆盖后的值,只有当key不存在时才有用,在key不存在的时候才会建立key和value的映射关系

 demo:

  Map<String, Integer> map = new HashMap();
        map.put("1",11);
        Integer newvalue = map.computeIfAbsent("1", k -> {
            return  new Integer(211);
        });

输出结果:

11

computeIfAbsent

default V computeIfAbsent(K key,
        Function<? super K, ? extends V> mappingFunction) {
    Objects.requireNonNull(mappingFunction);
    V v;
    if ((v = get(key)) == null) {
        V newValue;
        if ((newValue = mappingFunction.apply(key)) != null) {
            put(key, newValue);
            return newValue;
        }
    }

    return v;
}
只有map中不存在key或者key对应valueweinull,才建立key与value的映射,如果是key不存在返回null,如果key存在但是key对应value为null 同样返回null,
如果map中存在key,且key对应value不为null则不建立映射,直接返回key对应的value即olderValue

        Map<String, Integer> map = new HashMap();
        map.put("1",11);
        map.put("2",null);
        Integer newvalue = map.computeIfAbsent("1", new Function<String, Integer>() {
            @Override
            public Integer apply(String key) {
                return map.put(key, 22);
            }
        });
        System.out.println(newvalue);
        System.out.println(map);

输出结果:

11
null
null
{1=11, 2=22, 3=22}

 computeIfPresent

default V computeIfPresent(K key,
        BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
    Objects.requireNonNull(remappingFunction);
    V oldValue;
    if ((oldValue = get(key)) != null) {
        V newValue = remappingFunction.apply(key, oldValue);
        if (newValue != null) {
            put(key, newValue);
            return newValue;
        } else {
            remove(key);
            return null;
        }
    } else {
        return null;
    }
}

只有在key存在且key对应的value不为null,并且key,olderValue映射得到的newvalue不为空的时候,返回值是new value,其他情况都是返回null;如果key存在且value不为空,但是得到的newValue为null时则从Map中删除key

demo:

   Map<String, Integer> map = new HashMap();
        map.put("1", 11);
        map.put("2", null);
        Integer newvalue = map.computeIfPresent("2", (key, olderValue) -> map.put(key, 22));
        System.out.println(newvalue);

        newvalue = map.computeIfPresent("3", (key, olderValue) -> map.put(key, 22));
        System.out.println(newvalue);

        newvalue = map.computeIfPresent("1", (key, olderValue) -> map.get(key)+olderValue);
        System.out.println(newvalue);
        System.out.println("map:"+map);

        newvalue = map.computeIfPresent("1", (key, olderValue) -> null);
        System.out.println(newvalue);
        System.out.println("map:"+map);

输出结果:

null
null
22
map:{1=22, 2=null}
null
map:{2=null}

put

public V put(K key, V value) {
    return putVal(hash(key), key, value, false, true);
}
返回的是覆盖前的值,如果map里以前不存在key,返回值为null 

demo:

        Map<String, Integer> map = new HashMap();
        map.put("1",11);
        Integer newvalue = map.put("1", 112);
        System.out.println(newvalue);
        Integer newvalue2= map.put("2", 112);
        System.out.println(newvalue2);

输出结果;

11
null 

compute

default V compute(K key,
        BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
    Objects.requireNonNull(remappingFunction);
    V oldValue = get(key);

    V newValue = remappingFunction.apply(key, oldValue);
    if (newValue == null) {
        // delete mapping
        if (oldValue != null || containsKey(key)) {
            // something to remove
            remove(key);
            return null;
        } else {
            // nothing to do. Leave things as they were.
            return null;
        }
    } else {
        // add or replace old mapping
        put(key, newValue);
        return newValue;
    }
}

 会覆盖前面map中存在的key ,并返回覆盖后的值,如果得到的新值为null且以前map中存在在key,则会在map中移除key

 demo

     Map<String, Integer> map = new HashMap();
        map.put("1",11);
        Integer newvalue = map.compute("1", (key, olderVale) -> null);
        System.out.println(newvalue);
        System.out.println(map);

 输出结果:

null
{}

 Map按照Value排序

        HashMap<String, Integer> map = new HashMap();
        map.put("1", 22);
        map.put("4", 44);
        map.put("3", 33);
        map.put("5", 66);
        map.put("2", 11);

        Set<Map.Entry<String, Integer>> entry = map.entrySet();
        Map<String, Integer> map1 = entry.stream().sorted(Map.Entry.comparingByValue()).
                collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (v1, v2) -> v1, TreeMap::new));

        System.out.println(map1);

        ArrayList<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(map.entrySet());

        Comparator comparator = new Comparator<Map.Entry<String, Integer>>() {
            @Override
            public int compare(Map.Entry<String, Integer> arg0,
                               Map.Entry<String, Integer> arg1) {
                return arg0.getValue().compareTo(arg1.getValue());
            }
        };
        Collections.sort(list, comparator);

        list.stream().forEach(entry1 -> System.out.println(entry1.getKey() + "  " + entry1.getValue()));

        HashMap map2 = new LinkedHashMap();
        list.stream().forEach(entry1 -> map2.put(entry1.getKey(),entry1.getValue()));

        System.out.println(map2);

这里说下如果map会自己按照key排序,如果想要安装value排序这里使用了LinkHashMap 



这篇关于带你们看下Map源码,Map底层使用,深入底层源码思考问题的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程