使用 Java Stream - 独立处理流的两半



我目前有这段代码:

AtomicInteger counter = new AtomicInteger(0);
return IntStream.range(0, costs.length)
.mapToObj(i -> new int[]{costs[i][0]-costs[i][1], i})
.sorted(Comparator.comparingInt(d -> d[0]))
.mapToInt(s -> 
counter.getAndIncrement() < costs.length/2 ? costs[s[1]][0] : costs[s[1]][1]
)
.sum();

我计算数组中两个元素的差异,然后对其进行排序,最后我需要独立处理两半。

有没有比使用AtomicInteger作为计数器更好的方法?是否有一些像mapToIntWithIndex这样的方法可以在 JDK 内部(而不是在外部库中(访问?在 python 中是否有类似zip()的东西,我可以将索引与流连接在一起?如果没有,是否有计划将其添加到下一个 Java 版本中?

这不是执行此操作的可靠方法。Streams API 明确指出,映射中使用的函数不应是有状态的。

如果流操作的行为参数是有状态的,则流管道结果可能是不确定的或不正确的。

如果您使用有状态函数,它可能看起来可以工作,但由于您没有根据文档使用它,因此该行为在技术上是未定义的,并且可能会在未来版本的 Java 中中断。

收集到列表,然后处理列表的两半:

List<int[]> list = /* your stream up to and including the sort */.collect(toList());
int sum = list.subList(0,    half       ).stream().mapToInt(s -> costs[s[1]][0]).sum()
+ list.subList(half, list.size()).stream().mapToInt(s -> costs[s[1]][1]).sum();

实际上,我很想把它写成循环,因为我只是觉得它更容易看:

int sum = 0;
for (int[][] s : list.subList(0, half))           sum += costs[s[1]][0];
for (int[][] s : list.subList(half, list.size())) sum += costs[s[1]][1];

最新更新