1

我正在尝试使用“轻量级流”以比我在下面管理的更快的方式计算两个列表的最大总和对:

 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));
4

3 回答 3

3
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 列表。但在使用时,实际尺寸是事先知道的。

由于也想对最大值进行归约,并额外接收 maxIndex,因此最好使用经典循环而不是使用 Stream。

于 2019-04-03T14:05:15.600 回答
2

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

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类:

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)

于 2019-04-03T15:44:28.597 回答
1

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

    //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它(map 就像一个 foreach 但为每个列表项返回一个结果)。

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

然后你只需要将.collect它们重新放入一个列表中。

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

于 2019-04-03T14:44:44.607 回答