使用Java 8 Optional进行安全的Map遍历

the*_*ors 11 java groovy lambda

Map<String, Map<String, String>> myMap在Java 8课程中.我需要导航到一个叶子字符串myMap['keyA']['keyB'],null如果相关的映射中存在'keyA''keyB'不存在则返回.

在groovy我会使用myMap?.keyA?.keyB并完成它.我知道Java 8 Optional<T>会在java中带来类似的行为.有没有办法使用这种新行为来简洁地模仿groovy功能?如果没有,是否有另一种简洁的方法来在Java 8中获得这种行为,或者我仍然坚持使用复杂的过程代码?

Phi*_*ßen 7

String valueOrNull = Optional.ofNullable(myMap.get("keyA"))
                             .map(x -> x.get("keyB"))
                             .orElse(null);
Run Code Online (Sandbox Code Playgroud)

首先,它将第一个查找的结果包装在Optional中,后者充当monad.如果添加第三层(myMap.?keyA.?keyB.?keyC),它将如下所示:

String valueOrNull = Optional.ofNullable(myMap.get("keyA"))
                             .map(x -> x.get("keyB"))
                             .map(x -> x.get("keyC"))
                             .orElse(null);
Run Code Online (Sandbox Code Playgroud)


rge*_*man 4

您可以使用OptionalofNullable方法创建一个Optional可能代表也可能不代表null值的值。然后,您可以使用将结果映射到新值(如果该值尚未存在)方法mapFunctionnull

在这里,我提供 aFunction作为 lambda 表达式,以使用第二个键从第二个表达式获取值Map

Optional<String> result = Optional.ofNullable(myMap.get("keyA")).map(m -> m.get("keyB"));
Run Code Online (Sandbox Code Playgroud)

从那里您可以查看 是否Optional具有 的值isPresent(),如果是,则使用 获取它get()

测试:

public static Optional<String> method(Map<String, Map<String, String>> map,
    String key1, String key2)
{
    return Optional.ofNullable(map.get(key1)).map(m -> m.get(key2));
}
Run Code Online (Sandbox Code Playgroud)

调用代码:

Map<String, Map<String, String>> myMap = new HashMap<>();
Map<String, String> inner = new HashMap<>();
inner.put("one", "two");
myMap.put("three", inner);
System.out.println(method(myMap, "three", "one"));
System.out.println(method(myMap, "three", "dne"));
System.out.println(method(myMap, "dne", "dne"));
Run Code Online (Sandbox Code Playgroud)

输出:

Optional[two]
Optional.empty
Optional.empty
Run Code Online (Sandbox Code Playgroud)