• HashMap深入底层源码思考问题



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

    getOrDefault

    V getOrDefault(Object key, V defaultValue) 方法:

    如果map集合存在该key,或者key对应的value不为空,就返回对应的value,否则返defaultValue

    Map map = new HashMap();
    map.put("1",11);
    Object rs =  map.getOrDefault("2",22);
    rs结果你认为是多少,上面我们已经说过了,显而易见结果是22,因为map里不存在key=2,所有 返回默认值。
    
    • 1
    • 2
    • 3
    • 4

    forEach

    void forEach(BiConsumer<? super K, ? super V> action)

    map.forEach(new BiConsumer() {
         @Override
         public void accept(Object o, Object o2) {
             System.out.println("key:"+o+"  value:"+o2);
         }
     });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    merge

    参数说明   BigFunction的三个参数 分别是 olderVlaue newValue mergerValue类型
    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;
    }
    方法说明: 该方法为合并key相同的value值,如果map里存在key,如果newValue不为空,两者可以合并求和等操作
    如果map不存在key,newValue不为空也可以进行合并
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    示例:

    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));
    输出结果为 1:11,2:112,12:12
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    putIfAbsent

    @Override
    public V putIfAbsent(K key, V value) {
        return putVal(hash(key), key, value, true, true);
    }
    方法说明:如果map里面key不存在,则可以put进去,如果map key存在,但是OlderValue是null,也可以将NewValue put进去
    
    • 1
    • 2
    • 3
    • 4
    • 5

    示例:

    HashMap<Integer, String> map = new HashMap();
    map.put(1, "121");
    map.put(2, null);
    map.putIfAbsent(2,"12");
    此时 key=2会被替换为12
    
    • 1
    • 2
    • 3
    • 4
    • 5

    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或者map的key对应Value为null,如果newValue返回值不为null 将key对应value替换为newValue并返回NewValue结果
    否则直接返回空值
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    示例:

      public static void main(String[] args) {
          HashMap<Integer, String> map = new HashMap();
          map.put(1, "121");
          map.put(2, null);
          String value = map.computeIfAbsent(2, new Function<Integer, String>() {
              @Override
              public String apply(Integer integer) {
                  return "2";
              }
          });
          System.out.println(value);
          map.forEach((key, value1) -> System.out.println("key:" + key + "  value:" + value1));
      }
        
    输出结果:
    2
    key:1  value:121
    key:2  value:2
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    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;
        }
    }
    方法说明:
    如果map里不存在key 或者map里的key对应的value为null 那么直接返回null
    否则 如果mapping返回的newValue不为null,替换key对应的value并返回newValue,如果newValue为null,就会从map里剔除key并返回null
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    示例:

    HashMap<Integer, String> map = new HashMap();
     map.put(1, "121");
     map.put(2, "222");
     map.put(3, null);
     String newValue =map.computeIfPresent(2, new BiFunction<Integer, String, String>() {
         @Override
         public String apply(Integer key, String olderValue) {
             //key=2存在 且value不为null 如果返回newValue是null 会剔除key=2
    //                return null;
             return "wwww";
         }
     });
     System.out.println(newValue);
    
     map.computeIfPresent(3, new BiFunction<Integer, String, String>() {
         @Override
         public String apply(Integer key, String olderValue) {
             //key=3 存在 但是value是null 所以返回null
             return "22";
         }
     });
     map.forEach((key, value1) -> System.out.println("key:" + key + "  value:" + value1));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    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;
        }
    }
    方法说明:跟代码一样  首先根据olderValue key建立的Mapping返回的newValue如果为null  ,但是olderValue不为Null, 或者map里存在key,就会从map里剔除key并返回null,如果说map不存在key,直接返回null
    如果计算得出的newValue不为null就替换key对应的Value并返回newValue
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    示例:

    public static void main(String[] args) {
          HashMap<Integer, String> map = new HashMap();
          map.put(1, "121");
          map.put(2, "222");
          map.put(3, null);
    
          String newValue = map.compute(2, new BiFunction<Integer, String, String>() {
              @Override
              public String apply(Integer key, String olderValue) {
                  //直接返回null 此时 map存在key=2,且OlderValue不为null 会剔除key=2
                  return null;
              }
          });
          System.out.println(newValue);
          newValue = map.compute(1, new BiFunction<Integer, String, String>() {
              @Override
              public String apply(Integer key, String olderValue) {
                  //返回值不为null 替换key=1 返回222
                  return "222";
              }
          });
          System.out.println(newValue);
    
          newValue = map.compute(3, new BiFunction<Integer, String, String>() {
              @Override
              public String apply(Integer key, String olderValue) {
                  //返回值不为null 替换key=3 返回333
                  return "333";
              }
          });
          System.out.println(newValue);
          map.forEach((key, value1) -> System.out.println("key:" + key + "  value:" + value1));
      }
    输出结果:
    null
    222
    333
    key:1  value:222
    key:3  value:333
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    Map按照Value排序

    
       public static void main(String[] args) {
           HashMap<String, Integer> map = new HashMap();
           map.put("1", 22);
           map.put("4", 33);
           map.put("3", 44);
           map.put("5", 66);
           map.put("2", 11);
    
           Set<Map.Entry<String, Integer>> entry = map.entrySet();
           List<Map.Entry> mapList = entry.stream().sorted((o1, o2) -> o1.getValue().compareTo(o2.getValue()))
                   .collect(Collectors.toList());
    
           Map<String, Integer> map1 = entry.stream().sorted((o1, o2) -> o1.getValue().compareTo(o2.getValue())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (v1, v2) -> v1, LinkedHashMap::new));
           System.out.println(mapList);
           System.out.println(map1);
    
           ArrayList<Map.Entry<String, Integer>> arrayList = 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(arrayList, comparator);
           System.out.println(arrayList);
       }
       备注:HashMap会自动按照key进行排序,如果需要对Value排序需要将排序好的map转为LinkHashMap来存储或者List
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    测试输出结果:

    [2=11, 1=22, 4=33, 3=44, 5=66]
    {2=11, 1=22, 4=33, 3=44, 5=66}
    [2=11, 1=22, 4=33, 3=44, 5=66]

  • 相关阅读:
    和大于等于 target 的最短子数组 python解答
    车载软件架构——基础软件供应商&开发工具链(二)
    kubesphere3.4.1不同等级告警发送至不同邮箱
    Redis分布式锁及缓存的简单实现
    复古风再现:探索70年代风格的室内设计在当今的复兴之路
    基于小程序的教学辅助微信小程序设计+ssm(lw+演示+源码+运行)
    Python+django+vue信息技术学习网站
    【FPGA教程案例73】基础操作3——基于FPGA的Vivado功耗估计
    重新认识 IP地址
    vulnhub靶场之THALES: 1
  • 原文地址:https://blog.csdn.net/huanglu0314/article/details/125632773