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

Java 如何使用lambda表达式比较两个双值列表,java,lambda,comparison,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); List firstList=new Ar

让我们从以下列表开始:

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);
List firstList=new ArrayList();
firstList.add(2.0);
firstList.add(3.0);
List secondList=new ArrayList();
第二个列表。添加(2.0000000001);
第二个列表。添加(2.999999994);
我知道我可以用蛮力逐个比较每个元素。当然,我已经检查了两个列表是否具有相同数量的元素

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;
布尔isEqual=true;
对于(int i=0;i
我的问题:有没有一种方法可以使用lambda表达式来比较这两个双值列表?使用任何其他类型的对象似乎都很容易,但使用双精度对象则不容易。我需要检查这两个列表在数字上是否相等


提前谢谢。

当然可以。使用比较方法创建一个接口,该方法接受两个列表并返回布尔值。将现有代码包装在lambda表达式中。

给定以下语句:

当然,我已经检查了两个列表是否有相同数量的 元素

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;
然后您可以使用
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
未实现,因为它根本不会被调用。原因是这个特定的重载设计用于并行流,所以为了使组合器工作,流必须是并行的


然而,我们仍然需要使用这个重载来完成手头的任务。

在函数式语言中,您可以使用
zip
函数压缩两个列表(流),然后使用map或reduce使用lambdas操作合并列表。不幸的是,Java没有这种现成的功能。但是,您可以使用Google Guava
Streams
压缩两个列表,并使用lambda(功能样式)获得结果:

BiFunction-zippingFunction=(a,b)->Math.abs(a-b)<1.0e-6;
布尔结果=Streams.zip(firstList.stream(),secondList.stream(),zippingFunction)
.reduce(true,Boolean::logicalAnd);

为什么您认为lambda是必要的?你那里的东西很好用。订单重要吗?@Joe C我知道这很好用。我很好奇如何使用lambdas做同样的事情。@clinomaniac是的,顺序很重要。很好!。您可以在没有外部库的情况下实现同样的功能,尽管它可能不那么整洁。我已经在我的帖子中提供了:)我不明白为什么必须使用组合器字段。你不能只使用
t reduce(t标识,二进制运算符累加器)
?@MichałZabielski该重载声明
标识
,以及
累加器
的参数必须全部为同一类型。如果我继续使用这种方法,代码将无法编译。因此需要这个重载,它允许
标识
与流中的元素类型不同。在这种情况下,
累加器
的类型为
布尔
,而
i
的类型为
整数
。这使我能够折叠成布尔结果并访问索引。@MichałZabielski看到重载和重载的签名。好的,现在我看到了。事实上,您在reduce中执行了两个步骤:比较两个列表中的
double
,然后将其缩减为一个布尔值。很高兴知道这项技术与
组合器
字段:)我永远不会使用第二种方法。它不仅更长,而且不会短路。如果一对元素不满足条件,为什么要一直检查到最后一个?
    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);