JDK 8中方便的新地图默认方法

Map接口在JDK 8中提供了一些方便的新方法 。 因为我在本文中介绍的Map方法是作为默认方法实现的,所以Map接口的所有现有实现都享有默认方法中定义的默认行为,而无需任何新代码。 这篇文章中介绍的JDK 8引入的Map方法是getOrDefault(Object,V) , putIfAbsent(K,V) ,remove(Object,Object), remove(Object,Object) , replace(K,V)和replace(K ,V,V) 。

演示示例图

在本博文的所有示例中,我将使用以下代码中所示的声明和初始化MapstatesAndCapitals字段是类级别的静态字段。 我特意只包含了美国五十个州中的一小部分,以使阅读更加清晰,并使某些新的JDK 8 Map默认方法的演示更加容易。

private final static Map statesAndCapitals;static{statesAndCapitals = new HashMap<>();statesAndCapitals.put("Alaska", "Anchorage");statesAndCapitals.put("California", "Sacramento");statesAndCapitals.put("Colorado", "Denver");statesAndCapitals.put("Florida", "Tallahassee");statesAndCapitals.put("Nevada", "Las Vegas");statesAndCapitals.put("New Mexico", "Sante Fe");statesAndCapitals.put("Utah", "Salt Lake City");statesAndCapitals.put("Wyoming", "Cheyenne");}

Map.getOrDefault(Object,V)

Map的新方法getOrDefault(Object,V)允许调用者在单个语句中指定以获取与提供的键对应的映射值,或者如果找不到与提供的键匹配的返回值,则返回提供的“默认值”键。

下一个代码清单比较了如何在JDK 8之前实现与映射中提供的键相匹配的值的检查,或者如果没有找到匹配项,则使用默认值,以及如何在JDK 8中实现。

/** Demonstrate Map.getOrDefault and compare to pre-JDK 8 approach. The JDK 8* addition of Map.getOrDefault requires fewer lines of code than the* traditional approach and allows the returned value to be assigned to a* "final" variable.*/// pre-JDK 8 approach
String capitalGeorgia = statesAndCapitals.get("Georgia");
if (capitalGeorgia == null)
{capitalGeorgia = "Unknown";
}// JDK 8 approach
final String capitalWisconsin = statesAndCapitals.getOrDefault("Wisconsin", "Unknown");

Apache Commons类DefaultedMap提供的功能类似于新的Map.getOrDefault(Object, V)方法。 Groovy GDK包括一个与Groovy类似的方法Map.get(Object,Object) ,但是它的行为有些不同,因为如果找不到“ key”,它不仅会返回提供的默认值,而且还会添加带有基础地图的默认值。

Map.putIfAbsent(K,V)

Map的新方法putIfAbsent(K,V)的 Javadoc公布了等效的默认实现:

The default implementation is equivalent to, for this map:V v = map.get(key);if (v == null)v = map.put(key, value);return v;

另一个代码示例对此进行了说明,该示例将JDK 8之前的方法与JDK 8的方法进行了比较。

/** Demonstrate Map.putIfAbsent and compare to pre-JDK 8 approach. The JDK 8* addition of Map.putIfAbsent requires fewer lines of code than the* traditional approach and allows the returned value to be assigned to a* "final" variable.*/// pre-JDK 8 approach
String capitalMississippi = statesAndCapitals.get("Mississippi");
if (capitalMississippi == null)
{capitalMississippi = statesAndCapitals.put("Mississippi", "Jackson");
}// JDK 8 approach
final String capitalNewYork = statesAndCapitals.putIfAbsent("New York", "Albany");

在StackOverflow线程Java map.get(key)中讨论了在添加putIfAbsent方法之前在Java空间中的替代解决方案–自动执行put(key)并在key不存在时返回? 。 值得注意的是,在JDK 8之前, ConcurrentMap接口(扩展Map )已经提供了putIfAbsent(K,V)方法。

Map.remove(Object,Object)

Map的新删除(对象,对象)方法超出了长可Map.remove(对象)方法来删除一个映射条目仅所提供的密钥,并提供价值相匹配的地图(一个条目以前使用的版本只寻找要删除的“关键”匹配项)。

此方法的Javadoc注释根据等效的JDK 8之前的Java代码说明了默认方法的实现方式:
对于此映射,默认实现等效于:

if (map.containsKey(key) && Objects.equals(map.get(key), value)) {map.remove(key);return true;} elsereturn false;

下一个代码清单中显示了新方法与JDK 8之前方法的具体比较。

/** Demonstrate Map.remove(Object, Object) and compare to pre-JDK 8 approach.* The JDK 8 addition of Map.remove(Object, Object) requires fewer lines of* code than the traditional approach and allows the returned value to be* assigned to a "final" variable.*/// pre-JDK 8 approach
boolean removed = false;
if (   statesAndCapitals.containsKey("New Mexico")&& Objects.equals(statesAndCapitals.get("New Mexico"), "Sante Fe"))
{statesAndCapitals.remove("New Mexico", "Sante Fe");removed = true;
}// JDK 8 approach
final boolean removedJdk8 = statesAndCapitals.remove("California", "Sacramento");

Map.replace(K,V)

两个新Map “替换”方法中的第一个方法仅在指定键已经存在且具有某些映射值的情况下,将指定值设置为映射到指定键。 Javadoc注释说明了此默认方法实现的Java等效项:
对于此映射,默认实现等效于:

if (map.containsKey(key)) {return map.put(key, value);} elsereturn null;

接下来显示此新方法与JDK 8之前的方法的比较。

/** Demonstrate Map.replace(K, V) and compare to pre-JDK 8 approach. The JDK 8* addition of replace(K, V) requires fewer lines of code than the traditional* approach and allows the returned value to be assigned to a "final" * variable.*/// pre-JDK 8 approach
String replacedCapitalCity;
if (statesAndCapitals.containsKey("Alaska"))
{replacedCapitalCity = statesAndCapitals.put("Alaska", "Juneau");
}// JDK 8 approach
final String replacedJdk8City = statesAndCapitals.replace("Alaska", "Juneau");

Map.replace(K,V,V)

第二个新添加的Map “替换”方法在解释哪些现有值被替换时更窄。 尽管刚才介绍的方法将替换映射中可用于指定键的值中的任何值,但是这种接受附加( 第三个 )参数的“替换”方法将仅替换具有匹配键具有匹配键的映射条目的值。匹配值。 Javadoc注释显示了默认方法的实现:

The default implementation is equivalent to, for this map:if (map.containsKey(key) && Objects.equals(map.get(key), value)) {map.put(key, newValue);return true;} elsereturn false;

下一个代码清单显示了我与JDK 8之前的方法的比较。

/** Demonstrate Map.replace(K, V, V) and compare to pre-JDK 8 approach. The* JDK 8 addition of replace(K, V, V) requires fewer lines of code than the* traditional approach and allows the returned value to be assigned to a* "final" variable.*/// pre-JDK 8 approach
boolean replaced = false;
if (   statesAndCapitals.containsKey("Nevada")&& Objects.equals(statesAndCapitals.get("Nevada"), "Las Vegas"))
{statesAndCapitals.put("Nevada", "Carson City");replaced = true;
}// JDK 8 approach
final boolean replacedJdk8 = statesAndCapitals.replace("Nevada", "Las Vegas", "Carson City");

观察与结论

从这篇文章中可以得出一些结论。

  • 这些新的JDK 8 Map方法的Javadoc方法非常有用,特别是在描述新方法如何按照JDK 8之前的代码表现时。 我在有关基于JDK 8 Javadoc的API文档的更一般性讨论中讨论了这些方法的Javadoc。
  • 正如这些方法的Javadoc注释中的等效Java代码所指示的那样,这些新方法通常在访问映射键和值之前不检查null。 因此,使用Javadoc注释中所示的“等效”代码时,使用这些方法可能会遇到与null相同的问题。 实际上,Javadoc注释通常会警告NullPointerException的可能性,以及与某些Map实现允许null以及某些键和值不允许的问题有关的问题。
  • 本文中讨论的新Map方法是“默认方法”,这意味着Map实现会自动“继承”这些实现。
  • 本文中讨论的新Map方法允许使用更简洁的代码。 在我的大多数示例中,它们允许将客户端代码从多个影响状态的语句转换为可以一次性设置局部变量的单个语句。

这篇文章中介绍的新Map方法并不是开创性的或破天荒的,但它们为许多Java开发人员以前实现了更多详细代码,为其编写了自己的相似方法或为第三方库提供了便利。 JDK 8将这些标准化方法带给了Java大众,而无需自定义实现或第三方框架。 由于默认方法是实现机制,因此即使已经存在了很长时间的Map实现也突然并自动访问了这些新方法,而无需对实现进行任何代码更改。

翻译自: https://www.javacodegeeks.com/2014/04/handy-new-map-default-methods-in-jdk-8.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/364545.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JS观察者模式-自定义事件

111转载于:https://www.cnblogs.com/zoeeying/p/10139131.html

linux中下载的服务压缩包存放在,linux 下tomcat6 配置为服务

本人从官网http://tomcat.apache.org/上面下载的6.0.1_31版本&#xff0c;并解压包后改名存放在&#xff1a;/usr/share/tomcat6本人使用的是root用户登录&#xff0c;下面就说说具体的操作步骤&#xff0c;1、在/usr/share/tomcat6/bin中有commons-daemon-native.tar.gz压缩包…

Java 8 Friday Goodies:精益并发

在Data Geekery &#xff0c;我们喜欢Java。 而且&#xff0c;由于我们真的很喜欢jOOQ的流畅的API和查询DSL &#xff0c;我们对Java 8将为我们的生态系统带来什么感到非常兴奋。 我们已经写了一些关于Java 8好东西的博客 &#xff0c;现在我们觉得是时候开始一个新的博客系列了…

Floyd最短路(带路径输出)

摘要(以下内容来自百度) Floyd算法又称为插点法&#xff0c;是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法&#xff0c;与Dijkstra算法类似。 该算法名称以创始人之一、1978年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特弗洛伊德命名。 简介编辑 在…

CSS 小结笔记之清除浮动

浮动是一个非常好用的属性&#xff0c;但是有时会出现一些问题&#xff0c;需要进行清除浮动。例如 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-wi…

jsp分割字符串并遍历

1、先引入JSTL库 <% taglib uri"http://java.sun.com/jsp/jstl/core" prefix"c"%> 2、分割字符串并遍历&#xff08;按“,”分割&#xff09; <c:forTokens items"${danger.imagesPath}" delims"," var"file"> …

linux shell 脚本 父子进程 等待子进程,SHELL父子进程分析

导言本节将就shell交互(脚本执行)过程中涉及子进程(subprocess)以及子SHELL(subshell)的部分&#xff0c;配以实例&#xff0c;进行说明。将详细讨论如下问题&#xff1a;subprocess和subshell是什么subprocess的产生过程是什么什么情况下会产生subprocess和subshellshell编程中…

百里香Spring测试的意见

我最近将其转换为thymeleaf &#xff0c;以便在基于Spring的Web应用程序中进行视图模板化&#xff0c;而不是jsp。 百里香叶文档中所有关于为什么百叶香叶在jsp上为何能保持水分的争论都被我肯定了。 除了能够预览模板之外&#xff0c;对我来说&#xff0c;主要原因之一是视图…

路由与交换--交换机常用配置及其实验案例

1 交换机常用配置命令 1.1 配置主机名与口令 Switch>enable Switch#config t Switch(config)#hostname SA SA(config)#enable password cisco&#xff08;明文&#xff09; SA(config)#enable secret cisco&#xff08;暗文&#xff09; SA(config)#exit SA#show running-co…

js使用工具将表单封装成json字符串传到后台,js截取字符串(学生笔记)

<script src"js/jquery.min.js"></script><script src"https://cdn.bootcss.com/jquery.serializeJSON/2.9.0/jquery.serializejson.js"></script><script>// / //原始版本// $("#1").click(function(){// …

linux自动启动network服务,Windows/Linux 创建开机启动服务

系统服务是一种应用程序类型&#xff0c;它在后台运行。服务应用程序通常可以在本地和通过网络为用户提供一些功能。有些软件无需安装解压就能使用&#xff0c;或者在安装时未向系统注册服务。如果我们需要开机启动&#xff0c;需要手动创建服务。Windows系统篇相对于在注册表中…

对 Vue 的理解(一)

一、什么是 Vue ? 首先&#xff0c;Vue 是一个 MVVM 框架&#xff0c;M -- 模型&#xff0c;就是用来定义驱动的数据&#xff0c;V -- 视图&#xff0c;是经过数据改变后的 html&#xff0c;VM -- 框架视图&#xff0c;就是用来实现双向绑定的中间桥梁。Vue.js 是采用数据劫持…

Nginx做前端Proxy时TIME_WAIT过多的问题

我们的DSP系统目前基本非凌晨时段的QPS都在10W以上&#xff0c;我们使用Golang来处理这些HTTP请求&#xff0c;Web服务器的前端用Nginx来做负载均衡&#xff0c;通过Nginx的proxy_pass来与Golang交互。由于nginx代理使用了短链接的方式和后端交互的原因&#xff0c;使得系统TIM…

JDK 8功能的可疑方面

我们大多数使用Java进行开发的人通常都热衷于JDK 8附带的功能和改进。 但是&#xff0c;最近有几篇文章指出了某些功能可能会被滥用和滥用&#xff0c;并可能在将来导致其他问题。 这些功能使我想起了J2SE 5中引入的自动装箱功能&#xff0c;虽然有其有用的情况&#xff0c;但是…

Xshell 基本使用方式 (1) -- 使用Xshell 连接 VMware下的linux系统

在VMware的虚拟机设置下的网络适配器设置成桥接模式&#xff0c;点击确定。 在终端中输入ifconfig命令查看IP 打开Xshell 新建会话 输入刚刚获取的IP地址&#xff0c;我的是219.219.198.225 如果点击右侧的用户身份验证 输入你的linux登录用户名以及密码 点击连接 可以看到已经…

linux 串口 qt,Linux-QT4.7 实现串口通信

在qt5版本以下&#xff0c;想要实现串口通信需要两个集成类&#xff0c;posix_qextserialport 和 qextserialbase&#xff0c;需要的可以移步到 下载点。在posix_qextserialport这个类中关于串口设置的定义很详细&#xff0c;常用的写法一般是Posix_QextSerialPort * myCom;myC…

JS实现2048

2048这个游戏是通过对二维数组的操作来实现的&#xff0c;其算法核心如下&#xff1a; &#xff08;以一行左移为例&#xff09; c从0开始&#xff0c;遍历当前行中的元素&#xff0c;到<CN-1&#xff08;CN是一个常量&#xff0c;表示的是游戏格子的列数&#xff09;结束&a…

django01

Django的下载与基本命令: 1、下载Django&#xff1a; pip3 install django 2、创建一个django project django-admin.py startproject mysite manage.py ----- Django项目里面的工具&#xff0c;通过它可以调用django shell和数据库等。    settings.py ---- 包含了项目的…

Maven和Java多版本模块

介绍 通常&#xff0c;项目具有最低Java版本要求&#xff0c;并且适用于其所有模块。 但是每条规则都有其例外&#xff0c;最近我偶然发现了以下问题。 我的一个开源项目对大多数模块要求使用Java 1.6&#xff0c;除了一个要求1.7版本的项目。 当集成具有与您自己的项目不同的…

鼠标样式设置

<span style"cursor:auto">浏览器设置的光标</span><br /> <span style"cursor:default">默认鼠标箭头</span> <span style"cursor:pointer">一只手的形状</span> <span style"cursor:text&…