Lambda 在collect之后获取java8上的索引

Lambda 在collect之后获取java8上的索引,lambda,java-8,java-stream,Lambda,Java 8,Java Stream,我有下面一段代码,我想使用Java8流API进行翻译 count = 0; for (A a : someList) { if (a.get() == 1) { count++; newList.add(new X(count)); } } 映射时如何获取该计数 newList = someList.stream .filter(a -> a.get().equals("red")) .map(a -> new X(count)) .collect(

我有下面一段代码,我想使用Java8流API进行翻译

count = 0;
for (A a : someList) {
   if (a.get() == 1) {
     count++;
     newList.add(new X(count));
   }
}
映射时如何获取该计数

newList = someList.stream
.filter(a -> a.get().equals("red"))
.map(a -> new X(count))
.collect(Collectors.toList());

a->new X(count)
替换为
a->new X(++count)
++
运算符递增变量,在本例中为
计数
,如果在变量之后,则返回旧值;如果在变量之前,则返回新值。

我认为这可能有效

AtomicInteger count = new AtomicInteger(0);
newList = someList.stream
.filter(a -> a.get().equals("red"))
.map(a -> new X(count.getAndIncrement()))
.collect(Collectors.toList());

对于这种类型的逻辑,
for
循环版本更好,但是如果您真的想使用流,那么我会保持简单,分两步完成,而不是试图将所有逻辑转储到单个流管道中,这可能会导致可读性较差的代码

int count = (int)someList.stream()
                         .filter(a -> a.get().equals(“red”))
                         .count();

IntStream.rangeClosed(1, count)
         .mapToObj(X::new)
         .collect(toList());

如前所述,这绝不比
for
循环版本更好,但这里要说明的是,有时在使用流时,最好的方法是执行多个过程,而不是尝试将所有内容都放入单个管道中。

计数应为最终值。我想我可以使用AtomicInteger或BigIntegerit,但您现在毫无理由地引入了
AtomicInteger
?你不能有一个简单的整数,因为它应该是不可变的。这不是重点,你的非流解决方案最好是使用普通循环。当您可以保证连续运行时,可以使用单个值的
int[]
。此外,如果你真的想要一个流解决方案,另一个答案有一个更好的备选方案,而且不是一成不变的,但在某些情况下,有效的最终或最终解决方案恰好能完成预期的任务。这与“it works”不同。我甚至不会称之为“multiple passes”,因为这两个语句在完全不同的事物上流动。假设在一个循环中做这两件事比使用两个专用流操作执行得更好,这甚至是不安全的。当将第二个操作更改为
Arrays.asList(IntStream.rangeClosed(1,count).mapToObj(X::new).toArray(X[]::new))
时尤其如此,这比重复添加到
ArrayList
具有已知的优势,因为流操作不需要容量增加操作…