Map 特殊方法妙用

01. Map::getOrDefault

=== KEY 不存在时则获取指定默认值

  • 签名: V getOrDefault(Object key, V defaultValue);

  • 妙用: 处理约定配置场景

  • Usage.java

package org.example.spring;


import java.util.Objects;
import java.util.Properties;

public class Usage {

    static final String SPRING_DATA_REDIS_HOST_KEY = "spring.data.redis.host";
    static final String SPRING_DATA_REDIS_HOST_DEFAULT_VALUE = "127.0.0.1";

    static final String SPRING_DATA_REDIS_PORT_KEY = "spring.data.redis.port";
    static final int SPRING_DATA_REDIS_PORT_DEFAULT_VALUE = 6379;

    public static Properties settingsElement(Properties properties) {

        Objects.requireNonNull(properties);

        Properties configuration = new Properties();

        configuration.put(SPRING_DATA_REDIS_HOST_KEY, 
                          properties.getOrDefault(SPRING_DATA_REDIS_HOST_KEY, 
                                                  SPRING_DATA_REDIS_HOST_DEFAULT_VALUE));
        
        configuration.put(SPRING_DATA_REDIS_PORT_KEY, 
                          properties.getOrDefault(SPRING_DATA_REDIS_PORT_KEY, 
                                                  SPRING_DATA_REDIS_PORT_DEFAULT_VALUE));

        return configuration;

    }

    public static void main(String[] args) {
        Properties config = settingsElement(new Properties());
        System.out.println(config);
    }

}
  • [Mybatis 处理核心配置]
    在这里插入图片描述

02. Map::computeIfAbsent

=== 若 KEY 不存在时、则作用 Function 后 返回 VALLUE、KEY 存在时直接返回 VALUE

  • 签名: V computeIfAbsent(K key, Function<? super K, ? extends V> function);

  • 妙用: 处理购物车这样的数据: A 商品首次需初始化默认值、后续自增

    • A: null 0 1 2 3…
    • B: null 0 1 2 3…
  • Usage

package org.example.spring;


import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

public class Usage {

    public static void main(String[] args) {
        Map<String, AtomicInteger> shoppingBags = new HashMap<>();

        incrementByMapKey(shoppingBags, "A");
        incrementByMapKey(shoppingBags, "A");
        int value = incrementByMapKey(shoppingBags, "A");
        System.out.println("value = " + value);

        incrementByMapKey(shoppingBags, "B");
        incrementByMapKey(shoppingBags, "C");

        shoppingBags.forEach((k, v) -> System.out.println(k + " => " + v));

    }

    public static int incrementByMapKey(Map<String, AtomicInteger> map, String key) {
        return map.computeIfAbsent(key, keyOfNoUse -> new AtomicInteger(0)).incrementAndGet();
    }

}
  • 妙用: 处理 Map<String, List<String>> 结构型数据

  • Usage

package org.example.spring;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Usage {

    public static void main(String[] args) {
        Map<String, List<String>> map = new HashMap<>();

        map.computeIfAbsent("A", key -> new ArrayList<>()).add("a");
        map.computeIfAbsent("A", key -> new ArrayList<>()).add("b");
        map.computeIfAbsent("A", key -> new ArrayList<>()).add("c");

        map.computeIfAbsent("B", key -> new ArrayList<>()).add("a");
        map.computeIfAbsent("B", key -> new ArrayList<>()).add("b");
        map.computeIfAbsent("B", key -> new ArrayList<>()).add("c");
        map.computeIfAbsent("B", key -> new ArrayList<>()).add("d");

        // A -> a b c
        // B -> a b c d
        
        map.forEach((k, v) -> System.out.println(k + " => " + v));
    }

}

03. Map::computeIfPresent

=== 仅当 KEY 存在时作用 BiFunction、且返回 BiFunction 作用返回的 VALUE

  • 签名: V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> function)

  • 妙用: 处理 map 中的数据

  • Usage

package org.example.spring;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Usage {

    public static void main(String[] args) {
        Map<String, Long> map = new HashMap<>();
        map.put("A", 1L);
        map.put("B", 2L);
        map.put("C", 3L);

        computeDoubleOfMapValue(map, List.of("A", "B", "C", "D"));
        map.forEach((k, v) -> System.out.println(k + " => " + v));
    }

    static void computeDoubleOfMapValue(Map<String, Long> map, List<String> keys) {
        for (String key : keys) {
            map.computeIfPresent(key, (k, v) -> v * 2);
        }
    }

}

04. Map::merge

=== 当 KEY 不存在时、放入 KEY - VALUE、否则作用 BiFunction

  • 签名: V merge(K key, V v, BiFunction<? super V, ? super V, ? extends V> function);

  • 妙用: 合并两个 map 数据

  • Usage

package org.example.spring;

import java.security.PublicKey;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Usage {

    public static void main(String[] args) {
        Map<String, Integer> one = new HashMap<>();
        one.put("A", 1);
        one.put("B", 2);
        one.put("C", 3);

        Map<String, Integer> other = new HashMap<>();
        other.put("A", 1);
        other.put("B", 2);
        other.put("C", 3);
        other.put("D", 4);

        // {A=2, B=4, C=6, D=4}
        combine(one, other);
        System.out.println(one);
    }

    static void combine(Map<String, Integer> one, Map<String, Integer> other) {
        // Set<String> keySet = other.keySet();
        // for (String key : keySet) {
        //    one.merge(key, other.get(key), (k, ov) -> ov + other.get(key));
        // }
        
        // 一行就完事啦...
        other.forEach((k, v) -> one.merge(k, v, (ik, iv) -> v + iv));
        
    } 
}

05. Map::compute

=== 始终作用 BiFunction、作用新值不为空则放入、否则移除 KEY [若存在]

  • 签名: V compute(K key, BiFunction<? super K, ? super V, ? extends V> function);

  • 妙用: 根据值 决定 KEY 存留逻辑

  • Usage

package org.example.spring;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Usage {

    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<>();

        List<String> stringList = List.of("A", "B", "C", "A", "C", "D");
        stringList.forEach(w -> map.compute(w, (k, v) -> v == null ? 1 : v + 1));

        System.out.println(map);
        
        
        // 同理 下流收集器的逻辑不清晰
        Map<String, Long> map = Stream.of("A", "B", "C", "A", "C", "D")
                                      .collect(Collectors.groupingBy(
                                           Function.identity(), 
                                           Collectors.counting()));
        
        System.out.println(map);

    }
}
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐