如何使用lambda表达式比较两个double值列表

时间:2018-03-29 18:47:18

标签: java lambda comparison

让我们从以下列表开始:

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值列表?对于任何其他类型的对象来说似乎很容易,但不是双打。我需要检查这两个列表在数值上是否相等。

提前致谢。

3 个答案:

答案 0 :(得分:3)

鉴于声明:

  

当然,我已经检查过两个列表的编号相同   元件。

然后您可以使用IntStream.rangeallMatch完成相同的结果,如下所示:

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表达式中。