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

时间:2015-08-12 18:29:54

标签: java groovy lambda

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

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

3 个答案:

答案 0 :(得分:7)

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

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

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

答案 1 :(得分:4)

您可以使用Optional's ofNullable method创建Optional,该null可能代表Function值,也可能不代表null值。然后,您可以使用the map method Function,如果值已经Map,则会将结果映射到新值。

在这里,我提供Optional<String> result = Optional.ofNullable(myMap.get("keyA")).map(m -> m.get("keyB")); 作为lambda表达式,使用第二个键从第二个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)); } ,如果是,请使用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")); 获取。

测试:

Optional[two]
Optional.empty
Optional.empty

致电代码:

protected void Page_Load(object sender, EventArgs e)
{                        
if(!IsPostBack)
    //create checkbox list
}

输出:

void Page_Edit(Object sender, EventArgs e)
{
   if(yourCondition)
      yourCheckBoxList.Visible = true;
   else
      yourCheckBoxList.Visible = false;
}

答案 2 :(得分:1)

有趣的问题。

您可以考虑使用递归。

name[i]=subjhst[1]

这适用于Java&gt; = 8(您可以轻松地将其调整为以前的版本)。

奖金(需要番石榴):

/**
* Finds the value of a node in nested maps.
* @return leaf value or null if none
*/
public <K, V> V getValueFromKeys(Map<K, V> map, K... keys) {
    V value = map.getOrDefault(keys[0], null);
    if (keys.length == 1) return value;
    if (value instanceof Map) {
        K[] remainingKeys = Arrays.copyOfRange(keys, 1, keys.length);
        return getValueFromKeys((Map<K, V>) value, remainingKeys);
    }
    return null;
}