Java8新特性:Map的新方法详解

一、getOrDefault

  Java 8里Map里有一个方法getOrDefault,定义如下:

	default V getOrDefault(Object key, V defaultValue)

参数说明:

  • key :对应Map的key
  • defaultValue :传入的默认值

返回值:

  使用时候的具体含义是:当去Map中(Java8的Map)去获取一个 key 对应的 value 时:

  • 如果Map中这个 key 存在,则返回这个key对应的 value
  • 如果Map中这个 key 不存在,则把传入的defaultValue作为返回值

具体的我们看一个实例:

    @Test
    public void getOrDefault(){
    	// 假设定义一个,错误码和错误信息的映射
        Map<String, String> hashMap = new HashMap<>();
        hashMap.put("0000","交易成功");
        hashMap.put("1000","交易失败");
        hashMap.put("2000","处理中");
        hashMap.put("3000","交易已取消");
        System.out.println("---------------------原生操作----------------------");
        // 假设取一个不存在的key:4000
        String normalValue = hashMap.get("4000");
        if (StringUtils.isBlank(normalValue)){
            normalValue="交易未知";
        }
        System.out.println("常规方法取值:"+normalValue);

        System.out.println("---------------------Java8 操作----------------------");
        String value1 = hashMap.getOrDefault("0000", "交易未知");
        System.out.println("正常取值结果:"+value1);

        String value2 = hashMap.getOrDefault("4000", "交易未知");
        System.out.println("带默认值取值结果:"+value2);

		System.out.println("最终hashMap的值:"+hashMap.toString());
    }

运行结果(Map里的值改变了)

---------------------原生操作----------------------
常规方法取值:交易未知
---------------------Java8 操作----------------------
正常取值结果:交易成功
带默认值取值结果:交易未知
最终hashMap的值:{0000=交易成功, 1000=交易失败, 2000=处理中, 3000=交易已取消}

二、compute

  Java 8里Map里有一个方法 compute,定义如下:

	default V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction)

参数说明:

  • key :对应Map的key
  • remappingFunction :重新映射函数,用于重新计算值,得到newValue

返回值:

  • 如果Map中 key 对应的 value 不存在,则返回该 null
  • 如果Map中 key 对应的 value 存在,则返回通过 remappingFunction 重新计算值,如果计算后的值newValue不为null ,则把计算后的值newValue返回,并且把计算后的值newValue更新到映射中;如果计算后的值newValue为null ,则返回null,并且把当前key 对应的映射从集合中删除。

具体的我们看一个实例:

    @Test
    public void compute() {
        // 假设我们定义一个订单号对应的金额的映射
        Map<String, Integer> hashMap = new HashMap<>();
        hashMap.put("S2021123100001", 200);
        hashMap.put("S2021123100002", 400);
        hashMap.put("S2021123100003", 600);
        System.out.println("------------------------------模拟操作不存在的订单--------------------------------");
        // 模拟操作不存在的订单
        Integer noneExistValue = hashMap.compute("S2021123100004", (key, value) -> {
            if (value == null) {
                return value;
            }
            return value * 80 / 100;
        });
        System.out.println("操作一个不存在的key结果:" + noneExistValue);
        System.out.println("最终hashMap的值:"+hashMap.toString());
        System.out.println("-------------------------------模拟订单存在,总价打个8折-------------------------------");
        // 模拟订单存在,总价打个8折
        Integer existValue = hashMap.compute("S2021123100001", (key, value) -> {
            if (value == null) {
                return value;
            }
            return value * 80 / 100;
        });
        System.out.println("操作一个存在的key,计算结果不为空的结果:" + existValue);
        System.out.println("最终hashMap的值:"+hashMap.toString());
        System.out.println("-------------------------------模拟操作返回null-------------------------------");
        // 模拟操作返回null
        Integer nullValue = hashMap.compute("S2021123100003", (key, value) -> {
            return null;
        });
        System.out.println("操作一个不存在的key,计算结果为空的结果:" + nullValue);
        System.out.println("最终hashMap的值:"+hashMap.toString());
    }

运行结果(注意Map里的值)

------------------------------模拟操作不存在的订单--------------------------------
操作一个不存在的key结果:null
最终hashMap的值:{S2021123100001=200, S2021123100002=400, S2021123100003=600}
-------------------------------模拟订单存在,总价打个8折-------------------------------
操作一个存在的key,计算结果不为空的结果:160
最终hashMap的值:{S2021123100001=160, S2021123100002=400, S2021123100003=600}
-------------------------------模拟操作返回null-------------------------------
操作一个不存在的key,计算结果为空的结果:null
最终hashMap的值:{S2021123100001=160, S2021123100002=400}

注意:这里一定要注意类型,不要写成如下方式了

hashMap.compute("S2021123100004", (key, value) -> value == null ? value : value * 80 / 100);

  因为这里的value 的类型是Integer,如果是key存在,并且value不为null,能正常运行;当key不存在或者对应的value为null就会报空指针异常了。

三、computeIfAbsent

  Java 8里Map里有一个方法 computeIfAbsent,定义如下:

	default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) 

参数说明:

  • key :对应Map的key
  • mappingFunction :重新映射函数,用于重新计算值,得到newValue

返回值:

  • 如果Map中 key 对应的 value 存在,返回 value
  • 如果Map中 key 对应的 value 不存在,则通过remappingFunction 重新计算值,如果新计算的值newValue不为null,并保存从key 到计算后的值newValue的一个映射;如果新计算的值newValue为null,则不会加入映射

具体的我们看一个实例:

    @Test
    public void computeIfAbsent() {
        // 假设我们定义水果英文和中文的映射
        Map<String, String> hashMap = new HashMap<>();
        hashMap.put("Apple", "苹果");
        hashMap.put("Orange", "橘子");
        hashMap.put("Banana", "香蕉");
        System.out.println("-------------------------------模拟key存在-------------------------------");
        String orange = hashMap.computeIfAbsent("Orange", key -> "西瓜");
        System.out.println("操作存在的key的结果:"+orange);
        System.out.println("最终hashMap的值:"+hashMap.toString());

        System.out.println("-------------------------------模拟key不存在,计算后的值不为null(增加映射)-------------------------------");
        String watermelon = hashMap.computeIfAbsent("watermelon", key -> "西瓜");
        System.out.println("操作不存在的key,计算后的值不为null的结果:"+watermelon);
        System.out.println("最终hashMap的值:"+hashMap.toString());

        System.out.println("-------------------------------模拟key不存在,计算后的值为null-------------------------------");
        String strawberry = hashMap.computeIfAbsent("strawberry", key -> null);
        System.out.println("操作不存在的key,计算后的值为null的结果:"+strawberry);
        System.out.println("最终hashMap的值:"+hashMap.toString());
    }

运行结果(注意Map里的值)

-------------------------------模拟key存在-------------------------------
操作存在的key的结果:橘子
最终hashMap的值:{Apple=苹果, Orange=橘子, Banana=香蕉}
-------------------------------模拟key不存在,计算后的值不为null(增加映射)-------------------------------
操作不存在的key,计算后的值不为null的结果:西瓜
最终hashMap的值:{Apple=苹果, watermelon=西瓜, Orange=橘子, Banana=香蕉}
-------------------------------模拟key不存在,计算后的值为null-------------------------------
操作不存在的key,计算后的值为null的结果:null
最终hashMap的值:{Apple=苹果, watermelon=西瓜, Orange=橘子, Banana=香蕉}

四、computeIfPresent

  Java 8里Map里有一个方法 computeIfPresent,定义如下:

	default V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction)

参数说明:

  • key :对应Map的key
  • mappingFunction :重新映射函数,用于重新计算值,得到newValue

返回值:

  • 如果Map中 key 对应的 value 不存在,则返回该 null
  • 如果Map中 key 对应的 value 存在,则通过 remappingFunction 重新计算值,如果新计算的值不为null,则更新从key 到计算后的值newValue的一个映射;如果新计算的值为null,则删除key 到value的映射

具体的我们看一个实例:

    @Test
    public void computeIfPresent() {
        // 假设我们定义一个订单号对应的金额的映射
        Map<String, Integer> hashMap = new HashMap<>();
        hashMap.put("S2021123100001", 200);
        hashMap.put("S2021123100002", 400);
        hashMap.put("S2021123100003", 600);
        System.out.println("-------------------------------模拟key存在-------------------------------");
        // 假设抽取到的订单,就给总价打个8折
        Integer existValue = hashMap.computeIfPresent("S2021123100001", (key, value) -> value * 80 / 100);
        System.out.println("操作一个存在的key结果:" + existValue);
        System.out.println("最终hashMap的值:" + hashMap.toString());

        System.out.println("-------------------------------模拟key不存在,,计算结果不为null-------------------------------");
        Integer noneExistValue = hashMap.computeIfPresent("S2021123100004", (key, value) -> value * 80 / 100);
        System.out.println("操作一个不存在的key,计算结果不为null结果:" + noneExistValue);
        System.out.println("最终hashMap的值:" + hashMap.toString());

        System.out.println("-------------------------------模拟key存在,计算结果为null(删除映射)-------------------------------");
        Integer existKeyWithNullValue = hashMap.computeIfPresent("S2021123100002", (key, value) -> null);
        System.out.println("操作一个存在的key,计算结果为null结果:" + existKeyWithNullValue);
        System.out.println("最终hashMap的值:" + hashMap.toString());
    }

运行结果(注意Map里的值)

-------------------------------模拟key存在-------------------------------
操作一个存在的key结果:160
最终hashMap的值:{S2021123100001=160, S2021123100002=400, S2021123100003=600}
-------------------------------模拟key不存在,,计算结果不为null-------------------------------
操作一个不存在的key,计算结果不为null结果:null
最终hashMap的值:{S2021123100001=160, S2021123100002=400, S2021123100003=600}
-------------------------------模拟key存在,计算结果为null(删除映射)-------------------------------
操作一个存在的key,计算结果为null结果:null
最终hashMap的值:{S2021123100001=160, S2021123100003=600}

五、putIfAbsent

  Java 8里Map里有一个方法 putIfAbsent,定义如下:

	default V putIfAbsent(K key, V value)

参数说明:

  • key :对应Map的key
  • value :将要放入map的值

返回值:

  • 如果Map中 key 对应的 value 存在,则返回value
  • 如果Map中 key 对应的 value 为 null,返回null ,并且添加从key到传入的value的映射

具体的我们看一个实例:

    @Test
    public void putIfAbsent() {
        Map<String, Integer> hashMap = new HashMap<>();
        hashMap.put("shoes", 200);
        hashMap.put("clothes", 300);
        System.out.println("-------------------------------模拟key存在-------------------------------");
        Integer shoes = hashMap.putIfAbsent("shoes", 250);
        System.out.println("操作一个存在的key结果:" + shoes);
        System.out.println("最终hashMap的值:" + hashMap.toString());

        System.out.println("-------------------------------模拟key不存在-------------------------------");
        Integer trousers = hashMap.putIfAbsent("trousers", 250);
        System.out.println("操作一个不存在的key结果:" + trousers);
        System.out.println("最终hashMap的值:" + hashMap.toString());
    }

运行结果(注意Map里的值)

-------------------------------模拟key存在-------------------------------
操作一个存在的key结果:200
最终hashMap的值:{shoes=200, clothes=300}
-------------------------------模拟key不存在-------------------------------
操作一个不存在的key结果:null
最终hashMap的值:{trousers=250, shoes=200, clothes=300}

六、merge

  Java 8里Map里有一个方法 merge,定义如下:

	default V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction)

参数说明:

  • key :对应Map的key
  • value :使用者传入的值
  • mappingFunction :重新映射函数,用于重新计算值,得到newValue

返回值:

  • 如果Map中不存在指定的key时,便将传入的value设置为key的值,
  • 如果Map中key存在value时,执行一个方法该方法接收key的旧值oldValue和传入的value,执行自定义的方法

具体的我们看一个实例:

    @Test
    public void merge() {
        Employee[] employeeArray = {
                new Employee("BAT001", "胡昊天", "销售部", 28, 3500),
                new Employee("BAT002", "王大锤", "销售部", 27, 3000),
                new Employee("BAT003", "唐二鹏", "研发部", 32, 9900),
                new Employee("BAT004", "王一林", "研发部", 30, 9000),
                new Employee("BAT005", "梁南生", "研发部", 27, 8000),
                new Employee("BAT006", "包三雅", "财务部", 25, 6000),
                new Employee("BAT007", "罗考聪", "测试部", 35, 7400),
                new Employee("BAT008", "徐浪生", "测试部", 24, 7000),
                new Employee("BAT009", "胡俊伟", "研发部", 24, 4500),
                new Employee("BAT010", "胡健儿", "人事部", 23, 4000),
                new Employee("BAT011", "陶建伟", "运维部", 25, 8000),
                new Employee("BAT012", "张萌萌", "行政部", 20, 3500)
        };
        List<Employee> list = Arrays.asList(employeeArray);
        Map<String, Double> hashMap = new HashMap<>();
        System.out.println("-------------------------------java8 写法(易理解)-------------------------------");
        list.stream().forEach(studentScore -> hashMap.merge(studentScore.getDepartment(), studentScore.getSalary(), (oldValue, newValue) -> {
            return oldValue + newValue;
        }));
        System.out.println("最终hashMap的值:" + hashMap.toString());
        System.out.println("-------------------------------java8 精简写法-------------------------------");
        Map<String, Double> map = new HashMap<>();
        list.stream().forEach(studentScore -> map.merge(studentScore.getDepartment(), studentScore.getSalary(), Double::sum));
        System.out.println("最终Map的值:" + map.toString());
    }

运行结果(注意Map里的值)

-------------------------------java8 写法(易理解)-------------------------------
最终hashMap的值:{销售部=6500.0, 测试部=14400.0, 财务部=6000.0, 人事部=4000.0, 研发部=31400.0, 行政部=3500.0, 运维部=8000.0}
-------------------------------java8 精简写法-------------------------------
最终Map的值:{销售部=6500.0, 测试部=14400.0, 财务部=6000.0, 人事部=4000.0, 研发部=31400.0, 行政部=3500.0, 运维部=8000.0}
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值