假设我的货币汇率加载程序仅在成功加载所有汇率时返回isLoaded=true
结果:
//List<String> listFrom = Stream.of("EUR", "RUB").collect(toList());
//List<String> listTo = Stream.of("EUR", "CNY").collect(toList());
boolean isLoaded = true;
final FixerDataProvider httpProvider = new FixerDataProvider(maxAttempts);
final List<CurrencyRatePair> data =
listFrom.stream()
.flatMap(from -> {
final List<CurrencyRatePair> result = httpProvider.findRatesBetweenCurrencies(from, listTo);
if (Objects.isNull(result) || result.size() == 0) {
isLoaded = false; //!!!Not working as ineffectively final!!!
}
return result.stream();
}).collect(Collectors.toList());
if (!isLoaded) {
return false;
}
// do smth with loaded data
return true;
当isLoaded = false;
变量不是最终的或有效的最终变量时,不允许在lambda函数内部赋值isLoaded
。
哪个是在lambda表达式中设置/删除布尔标志的最优雅的解决方案?
您如何看待AtomicBoolean和set(false)方法?
答案 0 :(得分:8)
正如其他人所建议的那样,你可能会对旧式循环感觉更好。编写带有副作用的lambdas确实感觉有点像编程失误,但你可能会发现同样数量的开发人员认为它也很好。
至于让这种特殊的lambda-with-side效果起作用,将isLoaded
变成AtomicBoolean
可能是你最好的选择。通过将isLoaded
设为boolean[]
大小为1,您可以达到相同的效果,但这似乎不如向AtomicBoolean
提供给我。
但严重的是,尝试使用旧式循环,看看你更喜欢哪一个。
答案 1 :(得分:2)
通常不鼓励对流操作的行为参数产生副作用,因为它们通常会导致无意中违反无国籍要求以及其他线程安全隐患。
也就是说,如果你想要这样做,你用AtomicBoolean识别的解决方案就可以了。
答案 2 :(得分:2)
匿名内部类和lambda表达式中使用的变量必须是最终的。
您可以在案例中使用AtomicReference,这是ConditionEvaluationListenerJava8Test
的类似代码段public void expectedMatchMessageForAssertionConditionsWhenUsingLambdasWithoutAlias() {
final AtomicReference<String> lastMatchMessage = new AtomicReference<>();
CountDown countDown = new CountDown(10);
with()
.conditionEvaluationListener(condition -> {
try {
countDown.call();
} catch (Exception e) {
throw new RuntimeException(e);
}
lastMatchMessage.set(condition.getDescription());
})
.until(() -> assertEquals(5, (int) countDown.get()));
String expectedMatchMessage = String.format("%s reached its end value", CountDown.class.getName());
assertThat(lastMatchMessage.get(), allOf(startsWith("Condition defined as a lambda expression"), endsWith(expectedMatchMessage)));
}
干杯!
答案 3 :(得分:0)
如果我理解你,只有在所有关闭isLoaded=false
列表为空的情况下才会获得result
(如果result
列表为空,您将在下一行获得NPE,以便没有任何理由以这种方式进行空检查)。在这种情况下,您的data
列表也将为空,并且您不需要任何布尔标记,只需检查是否data.isEmpty()
并在true
时返回false。