快速获取 java 中两个浮点数列表总和的最大值和最大值索引

Get max and maxIndex of sum of two lists of floats in java fast

我正在尝试使用 "lightweight streams":

以比我在下面管理的更快的方式计算两个列表的最大和对
 List<Float> pairsSum = new ArrayList<>();
 // Get the list with all the sums
 Stream.range(0, list1.size())
          .forEach(i -> pairsSum.add(list1.get(i) + list2.get(i)));
 // Get the index of the max pair
 maxIndex = pairsSum.indexOf(Stream.of(pairsSum).max(Double::compare).orElse(0f));
List<Float> pairsSum = new ArrayList<>(repLeftForces.size());
// Get the list with all the sums
int maxIndex = -1;
float max = 0F;
for (int i =0; i < repLeftForces.size(); ++i) {
    float sum = list1.get(i) + list2.get(i);
    //pairsSum.add(sub);
    if (maxIndex == -1 || sum > max) {
        maxIndex = i;
        max = sum;
    }
 }

实际上不需要 pairsSum 列表。但是使用的时候,实际尺寸是事先知道的。

因为有人想为最大值做一个 reduce,并额外接收 maxIndex,最好是经典循环而不是使用 Stream。

您可以通过映射流在一行中创建总和列表(为了易读性,我确实添加了换行符):

    //made some example lists
    List<Float> list1 = Arrays.asList(new Float[]{1F, 2F, 3F});
    List<Float> list2 = Arrays.asList(new Float[]{2F, 3F, 4F});

    // Get the list with all the sums
    List<Float> sums = list1.stream()
            .map( f -> (list2.get(list1.lastIndexOf(f)) + f ) )
            .collect(Collectors.toList());

    // Get the index of the max pair
    int maxIndex = sums.indexOf(sums.stream().max(Float::compareTo).get());

只需流式传输第一个列表,然后 .map 它(映射类似于 foreach,但 returns 每个列表项的结果)。

地图上发生了什么: 对于每个项目,它会在列表 1 中找到当前值 f 的最高索引。这将是第一个列表中当前项目的索引。然后它在第二个列表中获取该索引的值。 list2.get(list1.lastIndexOf(f))。所以现在你将当前值 f 添加到它。这样,对于列表 1 的全长,您将输出共享相同索引的两个值的总和。

然后您只需要 .collect 将它们放回列表中即可。

最后为了找到最大索引,我将采用与您完全相同的方法。

简短的解决方案是使用 IntStreamreduce() 方法:

int maxIndex = IntStream.range(0, list1.size())
        .reduce((i1, i2) -> list1.get(i1) + list2.get(i1) < list1.get(i2) + list2.get(i2) ? i2 : i1)
        .orElse(-1);

如果你想要索引,值和总和,你可以使用自定义 Result class:

public static class Result {
    private int index;
    private float left;
    private float right;
    private float sum;
    // constructor and getters
}

这样使用:

Result max = IntStream.range(0, list1.size())
        .mapToObj(i -> new Result(i, list1.get(i), list2.get(i), list1.get(i) + list2.get(i)))
        .max(Comparator.comparing(Result::getSum))
        .orElse(null);

两种情况的时间复杂度都是O(n).