让我们从以下列表开始:
List<Double> firstList = new ArrayList<>();
firstList.add(2.0);
firstList.add(3.0);
List<Double> secondList = new ArrayList<>();
secondList .add(2.0000000001);
secondList .add(2.99999999994);
我知道我可以使用蛮力逐个比较每个元素。当然,我已经检查过两个列表都有相同数量的元素。
boolean isEqual = true;
for (int i = 0; i < firstList.size(); i++) {
isEqual &= Math.abs(firstList.get(i) - secondList.get(i)) < 1.0e-6;
}
return isEqual;
我的问题:有没有办法使用lambda表达式比较这两个double值列表?对于任何其他类型的对象来说似乎很容易,但不是双打。我需要检查这两个列表在数值上是否相等。
提前致谢。
答案 0 :(得分:3)
鉴于声明:
当然,我已经检查过两个列表的编号相同 元件。
然后您可以使用IntStream.range
和allMatch
完成相同的结果,如下所示:
boolean isEqual = firstList.isEmpty() ||
IntStream.range(0, firstList.size())
.allMatch(i -> Math.abs(firstList.get(i) - secondList.get(i)) < 1.0e-6);
使用reduce
的另一种解决方案:
BiPredicate<Double, Double> biPredicate = (e, a) -> Math.abs(e - a) < 1.0e-6;
boolean isEqual =
IntStream.range(0, firstList.size())
.boxed()
.reduce(Boolean.TRUE,
(accumulator, i) -> Boolean.logicalAnd(accumulator, biPredicate.test(firstList.get(i), secondList.get(i))),
(a, b) -> {
throw new RuntimeException("not implemented");
});
我故意将第三个参数(合并器)留给reduce
未实现,因为它根本不会被调用。原因是这个特定的重载被设计为与并行流一起使用,因此为了使组合器工作,流必须是并行的。
然而,我们仍然需要使用这个重载来完成手头的任务。
答案 1 :(得分:2)
在函数式语言中,您可以使用zip
函数压缩两个列表(流),然后使用map或reduce来使用lambdas操作合并列表。不幸的是,Java没有开箱即用的功能。但是,您可以使用Google Guava Streams
压缩两个列表并使用lambda(功能样式)获取结果:
BiFunction<Double, Double, Boolean> zippingFunction = (a, b) -> Math.abs(a - b) < 1.0e-6;
boolean result = Streams.zip(firstList.stream(), secondList.stream(), zippingFunction)
.reduce(true, Boolean::logicalAnd);
答案 2 :(得分:0)
不确定。使用compare方法创建一个接口,该方法接受两个List并返回boolean。将现有代码包装在lambda表达式中。