使用Java 8流构造是否可以更简洁地表达以下逻辑:

public static Set<Pair> findSummingPairsLookAhead(int[] data, int sum){
    Set<Pair> collected = new HashSet<>();
    Set<Integer> lookaheads = new HashSet<>();

    for(int i = 0; i < data.length; i++) {
        int elem = data[i];
        if(lookaheads.contains(elem)) {
            collected.add(new Pair(elem, sum - elem));
        }
        lookaheads.add(sum - elem);
    }

    return collected;
}

Arrays.stream(data).forEach(...)的影响。

提前致谢。

最佳答案

涉及在迭代过程中改变状态的算法不适用于流。但是,通常可以根据不显式改变任何中间状态的批量操作来重新考虑算法。

对于您而言,任务是收集一组Pair(x, sum - x),其中sum - x在列表中的x之前出现。因此,我们可以先建立一个数字映射到列表中第一个出现的索引,然后使用该映射来过滤列表并构建对对:

Map<Integer, Integer> firstIdx = IntStream.range(0, data.length)
                         .boxed()
                         .collect(toMap(i -> data[i], i -> i, (a, b) -> a));

Set<Pair> result = IntStream.range(0, data.length)
                         .filter(i -> firstIdx.contains(sum - data[i]))
                         .filter(i -> firstIdx.get(sum - data[i]) < i)
                         .mapToObj(i -> new Pair(data[i], sum - data[i]))
                         .collect(toSet());

如果发现更清晰,则可以使用&&getOrDefault缩短两个过滤器。

09-05 08:54