jdk8 接口默认方法_JDK 8中方便的新地图默认方法

jdk8 接口默认方法

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 CommonsDefaultedMap提供的功能类似于新的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;
 } else
     return 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);
 } else
     return 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;
 } else
     return 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

jdk8 接口默认方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值