使用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
缩短两个过滤器。