Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Map在Java 8中增加非常实用哪些函数接口?

Map在Java 8中增加非常实用哪些函数接口?

作者头像
码农架构
发布于 2021-02-08 14:34:15
发布于 2021-02-08 14:34:15
2.1K00
代码可运行
举报
文章被收录于专栏:码农架构码农架构
运行总次数:0
代码可运行

Map中的新方法

相比 Collection,Map中加入了更多的方法!

forEach()

该方法签名为void forEach(BiConsumer<? super K,? super V> action),作用是对Map中的每个映射执行action指定的操作,其中BiConsumer是一个函数接口,里面有一个待实现方法void accept(T t, U u)。BinConsumer接口名字和accept()方法名字都不重要,请不要记忆他们。

需求:假设有一个数字到对应英文单词的Map,请输出Map中的所有映射关系.

Java7以及之前经典的代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// Java7以及之前迭代Map
HashMap<Integer, String> map = new HashMap<>();
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");
for(Map.Entry<Integer, String> entry : map.entrySet()){
    System.out.println(entry.getKey() + "=" + entry.getValue());
}

使用Map.forEach()方法,结合匿名内部类,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 使用forEach()结合匿名内部类迭代Map
HashMap<Integer, String> map = new HashMap<>();
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");
map.forEach(new BiConsumer<Integer, String>(){
    @Override
    public void accept(Integer k, String v){
        System.out.println(k + "=" + v);
    }
});

上述代码调用forEach()方法,并使用匿名内部类实现BiConsumer接口。当然,实际场景中没人使用匿名内部类写法,因为有Lambda表达式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 使用forEach()结合Lambda表达式迭代Map
HashMap<Integer, String> map = new HashMap<>();
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");
map.forEach((k, v) -> System.out.println(k + "=" + v));
}

getOrDefault()

该方法跟Lambda表达式没关系,但是很有用。方法签名为V getOrDefault(Object key, V defaultValue),作用是按照给定的key查询Map中对应的value,如果没有找到则返回defaultValue。使用该方法程序员可以省去查询指定键值是否存在的麻烦.

需求;假设有一个数字到对应英文单词的Map,输出4对应的英文单词,如果不存在则输出NoValue

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 查询Map中指定的值,不存在时使用默认值
HashMap<Integer, String> map = new HashMap<>();
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");
// Java7以及之前做法
if(map.containsKey(4)){ // 1
    System.out.println(map.get(4));
}else{
    System.out.println("NoValue");
}
// Java8使用Map.getOrDefault()
System.out.println(map.getOrDefault(4, "NoValue")); // 2

putIfAbsent() 该方法跟Lambda表达式没关系,但是很有用。方法签名为V putIfAbsent(K key, V value),作用是只有在不存在key值的映射或映射值为null时,才将value指定的值放入到Map中,否则不对Map做更改.该方法将条件判断和赋值合二为一,使用起来更加方便.

remove()

我们都知道Map中有一个remove(Object key)方法,来根据指定key值删除Map中的映射关系;Java8新增了remove(Object key, Object value)方法,只有在当前Map中key正好映射到value时才删除该映射,否则什么也不做.

replace()

在Java7及以前,要想替换Map中的映射关系可通过put(K key, V value)方法实现,该方法总是会用新值替换原来的值.为了更精确的控制替换行为,Java8在Map中加入了两个replace()方法,分别如下:

  • replace(K key, V value),只有在当前Map中key的映射存在时才用value去替换原来的值,否则什么也不做.
  • replace(K key, V oldValue, V newValue),只有在当前Map中key的映射存在且等于oldValue时才用newValue去替换原来的值,否则什么也不做.

replaceAll() 该方法签名为replaceAll(BiFunction<? super K,? super V,? extends V> function),作用是对Map中的每个映射执行function指定的操作,并用function的执行结果替换原来的value,其中BiFunction是一个函数接口,里面有一个待实现方法R apply(T t, U u).不要被如此多的函数接口吓到,因为使用的时候根本不需要知道他们的名字.

需求:假设有一个数字到对应英文单词的Map,请将原来映射关系中的单词都转换成大写.

Java7以及之前经典的代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// Java7以及之前替换所有Map中所有映射关系
HashMap<Integer, String> map = new HashMap<>();
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");
for(Map.Entry<Integer, String> entry : map.entrySet()){
    entry.setValue(entry.getValue().toUpperCase());
}

使用replaceAll()方法结合匿名内部类,实现如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 使用replaceAll()结合匿名内部类实现
HashMap<Integer, String> map = new HashMap<>();
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");
map.replaceAll(new BiFunction<Integer, String, String>(){
    @Override
    public String apply(Integer k, String v){
        return v.toUpperCase();
    }
});

上述代码调用replaceAll()方法,并使用匿名内部类实现BiFunction接口。更进一步的,使用Lambda表达式实现如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 使用replaceAll()结合Lambda表达式实现
HashMap<Integer, String> map = new HashMap<>();
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");
map.replaceAll((k, v) -> v.toUpperCase());

简洁到让人难以置信.

merge()

该方法签名为merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction),作用是:

  • 如果Map中key对应的映射不存在或者为null,则将value(不能是null)关联到key上;
  • 否则执行remappingFunction,如果执行结果非null则用该结果跟key关联,否则在Map中删除key的映射.

参数中BiFunction函数接口前面已经介绍过,里面有一个待实现方法R apply(T t, U u).

merge()方法虽然语义有些复杂,但该方法的用方式很明确,一个比较常见的场景是将新的错误信息拼接到原来的信息上,比如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
map.merge(key, newMsg, (v1, v2) -> v1+v2);

compute()

该方法签名为compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction),作用是把remappingFunction的计算结果关联到key上,如果计算结果为null,则在Map中删除key的映射.

要实现上述merge()方法中错误信息拼接的例子,使用compute()代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
map.compute(key, (k,v) -> v==null ? newMsg : v.concat(newMsg));
computeIfAbsent()

该方法签名为V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction),作用是:只有在当前Map中不存在key值的映射或映射值为null时,才调用mappingFunction,并在mappingFunction执行结果非null时,将结果跟key关联.

Function是一个函数接口,里面有一个待实现方法R apply(T t).

computeIfAbsent()常用来对Map的某个key值建立初始化映射.比如我们要实现一个多值映射,Map的定义可能是Map<K,Set>,要向Map中放入新值,可通过如下代码实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Map<Integer, Set<String>> map = new HashMap<>();
// Java7及以前的实现方式
if(map.containsKey(1)){
    map.get(1).add("one");
}else{
    Set<String> valueSet = new HashSet<String>();
    valueSet.add("one");
    map.put(1, valueSet);
}
// Java8的实现方式
map.computeIfAbsent(1, v -> new HashSet<String>()).add("yi");

使用computeIfAbsent()将条件判断和添加操作合二为一,使代码更加简洁.

computeIfPresent()

该方法签名为V computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction),作用跟computeIfAbsent()相反,即,只有在当前Map中存在key值的映射且非null时,才调用remappingFunction,如果remappingFunction执行结果为null,则删除key的映射,否则使用该结果替换key原来的映射.

这个函数的功能跟如下代码是等效的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// Java7及以前跟computeIfPresent()等效的代码
if (map.get(key) != null) {
    V oldValue = map.get(key);
    V newValue = remappingFunction.apply(key, oldValue);
    if (newValue != null)
        map.put(key, newValue);
    else
        map.remove(key);
    return newValue;
}
return null;

- END -

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-02-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农架构 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Lambda表达式你会用吗?
我们先看看什么是函数。函数是一种最基本的任务,一个大型程序就是一个顶层函数调用若干底层函数,这些被调用的函数又可以调用其他函数,即大任务被一层层拆解并执行。所以函数就是面向过程的程序设计的基本单元。
说故事的五公子
2021/01/21
9330
Java Lambda 解析和使用技巧
lambda 是包着一个函数的对象 lambda 表达式非常简洁优雅。是把动态语言的特性嫁接到静态语言的一个典范。
卢衍飞
2023/02/16
1.1K0
关于 Java Lambda 表达式看这一篇就够了(强烈建议收藏)
Java Lambda表达式的一个重要用法是简化某些匿名内部类(Anonymous Classes)的写法。实际上Lambda表达式并不仅仅是匿名内部类的语法糖,JVM内部是通过invokedynamic指令来实现Lambda表达式的。具体原理放到下一篇。本篇我们首先感受一下使用Lambda表达式带来的便利之处。
张乘辉
2022/04/01
3K1
关于 Java Lambda 表达式看这一篇就够了(强烈建议收藏)
Java基础系列(四十五):集合之Map
Map是一个接口,代表的是将键映射到值的对象。一个映射不能包含重复的键,每个键最多只能映射到一个值。
山禾说
2019/01/21
6520
Java集合中的Map接口
  Map是Java三种集合中的一种位于java.util包中,Map作为一个接口存在定义了这种数据结构的一些基础操作,它的最终实现类有很多:HashMap、TreeMap、SortedMap等等,这些最终的子类大多有一个共同的抽象父类AbstractMap。在AbstractMap中实现了大多数Map实现公共的方法。本文介绍Map接口定义了哪些方法,同时JDK8又新增了哪些。
用户1148394
2019/01/07
1.9K0
java中的Map集合
Map用于保存具有映射关系的数据,Map集合里保存着两组值,一组用于保存Map的ley,另一组保存着Map的value。
全栈程序员站长
2022/09/02
9620
java中的Map集合
Map接口在1.8版本新增的几个方法
这可以说是最常用的方法了吧,获取指定key的value,当key不存在的时候返回一个默认值,也就是第二个参数.
呼延十
2019/06/26
5780
【JDK1.8】JDK1.8集合源码阅读——总章
  今天开始阅读jdk1.8的集合部分,平时在写项目的时候,用到的最多的部分可能就是Java的集合框架,通过阅读集合框架源码,了解其内部的数据结构实现,能够深入理解各个集合的性能特性,并且能够帮助自己在今后的开发中避免犯一些使用错误。另外笔者自己也是摸着石头过河,如果有描述不当的地方,希望园友们能够不吝指出,希望能够和大家共同进步!
joemsu
2019/05/25
4560
【Java 基础篇】深入了解Java中的键值对集合:Map集合详解
Map是Java中常用的数据结构之一,用于存储键值对(Key-Value)映射。它提供了快速的查找和访问能力,是编程中常用的工具之一。本文将深入介绍Java中的Map集合,包括常见的Map实现类、基本操作、使用示例以及一些重要的注意事项。
繁依Fanyi
2023/10/12
4.1K0
【Java 基础篇】深入了解Java中的键值对集合:Map集合详解
JDK源码分析-Map
Map 是一个接口,它表示一种“键-值(key-value)”映射的对象(Entry),其中键是不重复的(值可以重复),且最多映射到一个值(可以理解为“映射”或者“字典”)。
WriteOnRead
2019/08/16
3970
JDK源码分析-Map
Java新特性:Lambda表达式
Lambda 表达式(Lambda expression),也可称为闭包(Closure),是 Java(SE)8 中一个重要的新特性。
栗筝i
2023/10/16
3200
Java新特性:Lambda表达式
Javamap集合_javaweb开源项目
Map 接口是 java 中两大集合接口之一,相对于 Collection,Map 接口结构规定了所有键值对形式的集合容器。同时,它与 Collection 的子接口 Set 又密切相关,Map 一部分实现依赖于 Set 集合,而 Set 集合的一些实现也依赖于 Map。
全栈程序员站长
2022/09/23
4230
Javamap集合_javaweb开源项目
java.util.Map API
Map集合是有Key和Value的,Collection集合是只有Value。Collection集合底层也是有Key和Value,只是隐藏起来。
HLee
2021/02/08
7420
java.util.Map API
Collections的singleton,singletonList,singletonMap
这里只需要创建一个元素的List的时候用Arrays.asList()的话那插件就会在代码下报黄线提示你这是代码坏味道,建议优化。后面我就发现了使用Collections的singleton的一系列方法创建单个元素集合使用:
爱敲代码的猫
2020/07/14
1.2K0
Map 只会 put、get?快来学这几个“新”方法
Map是我们日常编程中十分常用的数据接口,的在JDK8中,Map引入了几个新方法,可以简化我们对Map中数据的操作。
程序员皮皮林
2024/10/30
1160
Java之映射
集是一个集合,它可以快速地查找现有的元素。但是,要查看一个元素,需要有要查找元素的精确副本。这不是一种非常通用的查找方式,因为在集合中查找元素总是要遍历集合。通常,我们知道某些键的信息,并想要查找与之对应的元素。映射(map)数据结构就是为此而设计的。映射用来存放键/值对。如果提供了键,就能够查找到值。它们之间是一一对应关系。
kirin
2020/08/19
1.2K0
Java 从 Map 到 HashMap 的一步步实现,看这篇足矣了!
在 Java 中, Map 提供了键——值的映射关系。映射不能包含重复的键,并且每个键只能映射到一个值。 以 Map 键——值映射为基础,java.util 提供了 HashMap(最常用)、 TreeMap、Hashtble、LinkedHashMap 等数据结构。 衍生的几种 Map 的主要特点:
用户2781897
2021/01/13
3290
Java 从 Map 到 HashMap 的一步步实现,看这篇足矣了!
【Java性能优化】Map.merge()方法:告别繁琐判空,3行代码搞定统计累加!
在日常开发中,我们经常需要对Map中的值进行累加统计。比如统计每年的项目投入率总和,很多同学会写出这样的代码:
摘星编程
2025/05/20
380
【Java】:lambda 表达式
🔥 Lambda 表达式 是JDK8新增的特性,Lambda 表达式 可以取代大部分匿名内部类,写出更优雅的Java代码,尤其在集合的遍历和其他集合操作中,可以将函数作为一个方法的参数,也就是函数作为参数传递到方法中,极大地优化代码结构JDK也提供了大量的内置函数式接口供开发者使用,使得 Lambda 表达式 的运用更加方便、高效。
IsLand1314
2024/12/20
1130
【Java】:lambda 表达式
Java 8 中 Map 骚操作之 merge() 的用法
Java 8 最大的特性无异于更多地面向函数,比如引入了 lambda等,可以更好地进行函数式编程。前段时间无意间发现了 map.merge() 方法,感觉还是很好用的,此文简单做一些相关介绍。首先我们先看一个例子。
搜云库技术团队
2020/06/04
1.5K0
Java 8 中 Map 骚操作之 merge() 的用法
相关推荐
Lambda表达式你会用吗?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档