Java 8 Java8:遍历映射的所有元素
我有一个Java 8 Java8:遍历映射的所有元素,java-8,hashmap,Java 8,Hashmap,我有一个validate方法,它返回一个布尔值 我使用以下方法调用此方法(Java 7): boolean isValid = true; for (String key: aMap.keySet()) { isValid &= validate(key, aMap.get(key)); } 我想用Java8重写这段代码 Java 8允许使用以下各项在地图上进行迭代: aMap.forEach((k,v) -> validate(k, v)
validate
方法,它返回一个布尔值
我使用以下方法调用此方法(Java 7):
boolean isValid = true;
for (String key: aMap.keySet()) {
isValid &= validate(key, aMap.get(key));
}
我想用Java8重写这段代码
Java 8允许使用以下各项在地图上进行迭代:
aMap.forEach((k,v) -> validate(k, v));
但这是行不通的:
aMap.forEach((k,v) -> isValid &= validate(k, v));
问题
如何将Java 7代码重写为Java 8以获得相同的结果
注:
我问了一个类似的问题。这篇文章的不同之处在于,这次我想遍历映射
的所有项目(用于验证
方法来构建验证报告)<如果没有发生验证错误,code>isValid
必须返回true
,如果至少发生一个验证错误,则必须返回false
。aMap.forEach((k,v)->isValid&=validate(k,v))的问题是指lambda表达式中捕获的变量应为final
或有效final
。Java中的匿名内部类
也是如此
因此,要回答您的查询,您可以将isValid
转换为final
单元素数组,如下所示:
final boolean[]isValid={true}代码>然后
aMap.forEach((k,v)->isValid[0]&=validate(k,v))代码>
您也可以将其原子化,但这需要更多的代码更改。这个解决方案要简单得多。aMap.forEach((k,v)->的问题是有效的&=validate(k,v))
是指lambda表达式中捕获的变量应为final
或有效final
。Java中的匿名内部类
也是如此
因此,要回答您的查询,您可以将isValid
转换为final
单元素数组,如下所示:
final boolean[]isValid={true}代码>然后
aMap.forEach((k,v)->isValid[0]&=validate(k,v))代码>
您也可以将其原子化,但这需要更多的代码更改。此解决方案简单得多。您可以使用
boolean isValid = aMap.entrySet().stream()
.map(e -> validate(e.getKey(), e.getValue()))
.reduce(true, Boolean::logicalAnd);
与anyMatch
、allMatch
等不同,reduce不知道短路。但是,执行所有validate
方法调用的要求表明该方法存在副作用。理解这些副作用必须是无干扰的,这一点很重要,也就是说,这些方法调用的顺序并不重要,甚至多个元素的并发评估也不应该破坏它
即使满足这些要求,也不鼓励在功能性操作中产生此类副作用。例如,下一个查看代码的开发人员可能会说,“嘿,看起来我们应该在这里使用allMatch
”
所以我会留在圈里。但是,在处理映射的关联时,不应在entrySet()
上循环以对每个键执行查找,而应使用
boolean isValid = true;
for(Map.Entry<String, ValueType> e: aMap.entrySet())
isValid &= validate(e.getKey(), e.getValue());
消除循环中最烦人的语法元素。您可以使用
boolean isValid = aMap.entrySet().stream()
.map(e -> validate(e.getKey(), e.getValue()))
.reduce(true, Boolean::logicalAnd);
与anyMatch
、allMatch
等不同,reduce不知道短路。但是,执行所有validate
方法调用的要求表明该方法存在副作用。理解这些副作用必须是无干扰的,这一点很重要,也就是说,这些方法调用的顺序并不重要,甚至多个元素的并发评估也不应该破坏它
即使满足这些要求,也不鼓励在功能性操作中产生此类副作用。例如,下一个查看代码的开发人员可能会说,“嘿,看起来我们应该在这里使用allMatch
”
所以我会留在圈里。但是,在处理映射的关联时,不应在entrySet()
上循环以对每个键执行查找,而应使用
boolean isValid = true;
for(Map.Entry<String, ValueType> e: aMap.entrySet())
isValid &= validate(e.getKey(), e.getValue());
消除该循环中最烦人的语法元素。您说:“这些方法调用的顺序应该无关紧要,甚至多个元素的并发计算也不应该破坏它。”但您编写的流不会像parallelStream()
那样并行运行。你能解释一下你的意思吗?嗯,是关于合同的。顺序流将以源映射的迭代器交付方法的相同顺序调用该方法,但这不是一个保证的属性。更糟糕的是,如果源地图一开始没有定义遭遇顺序,比如HashMap
。在相同的情况下,我们可以预测顺序调用顺序,但如果依赖顺序,代码仍然是错误的。作为重击的规则,使用流API的代码应该以这样的方式编写:即使我们还没有使用它,将其转换为并行也不会破坏它。你说:“这些方法调用的顺序不重要,甚至多个元素的并发计算也不应该破坏它。”但是您编写的流不会像parallelStream()
那样并行运行。你能解释一下你的意思吗?嗯,是关于合同的。顺序流将以源映射的迭代器交付方法的相同顺序调用该方法,但这不是一个保证的属性。更糟糕的是,如果源地图一开始没有定义遭遇顺序,比如HashMap
。在相同的情况下,我们可以预测顺序调用顺序,但如果依赖顺序,代码仍然是错误的。作为thump的规则,使用streamapi的代码应该以这样的方式编写:即使我们还没有使用它,将它转换为并行也不会破坏它。它肯定能工作。这是一个原创的解决方案,尽管以阵列为代价。尽管如此,还是投了赞成票,谢谢。这确实有效。这是一个原创的解决方案,尽管以阵列为代价。