Java 使用流操作,将列表映射到累积和列表
我想将一个列表映射到一个列表,该列表是原始列表的累积和列表 我的意思是,结果列表中每个索引处的值应该是从开始到原始列表中该点的每个索引处的值的总和 更正式地说: 目标是通过对原始列表中的元素流进行操作来实现这一点Java 使用流操作,将列表映射到累积和列表,java,java-stream,Java,Java Stream,我想将一个列表映射到一个列表,该列表是原始列表的累积和列表 我的意思是,结果列表中每个索引处的值应该是从开始到原始列表中该点的每个索引处的值的总和 更正式地说: 目标是通过对原始列表中的元素流进行操作来实现这一点 L=O.stream[…这里的东西…].collectCollectors.toList 如果您想通过流API实现,可以这样做: int[] accum = new int[1]; System.out.println( Arrays.asLis
L=O.stream[…这里的东西…].collectCollectors.toList 如果您想通过流API实现,可以这样做:
int[] accum = new int[1];
System.out.println(
Arrays.asList(1, 1, 2, 1, 3).stream()
.map(s -> s + accum[0])
.peek(s-> accum[0] = s)
.collect(Collectors.toList())
);
输出:
[1, 2, 4, 5, 8]
我喜欢流,但我不认为我们应该把流用于所有事情,仅仅是为了它。在这里,没有外部列表之类的东西,就没有干净的方法。 如果可以避免循环,我不喜欢使用for循环,因此在这里,我将使用递归方法:
private static List<Integer> sum(List<Integer> remainingList, List<Integer> resultList) {
if(remainingList.isEmpty()) {
return resultList;
}
int currentValue = remainingList.get(0);
int previousSum = resultList.isEmpty() ? 0 : resultList.get(resultList.size()-1);
resultList.add(currentValue + previousSum);
return sum(remainingList.subList(1, remainingList.size()), resultList);
}
然后
在函数式语言中,您尝试执行的操作称为。当然,您可以在Java中实现类似的东西,但是流被设计为可并行的,所以像Scan这样暗示单线程操作的操作并没有得到很好的支持
public static void demo() {
List<Integer> ints = List.of(1,1,2,1,3);
List<Integer> sums = ints.stream().collect(scan(Integer::sum));
System.out.println(sums);
}
public static <T> Collector<T, ?, List<T>> scan(BinaryOperator<T> reducer) {
return Collector.of(
ArrayList::new,
(List<T> list, T x) -> {
if (list.isEmpty()) {
list.add(x);
} else {
list.add(reducer.apply(list.get(list.size() - 1), x));
}
},
(l1, l2) -> {throw new UnsupportedOperationException("Scans cannot be efficiently parallelized");}
);
}
这也可用于:
List<Integer> lst = Arrays.asList(1,1,2,1,3);
List<Integer> updList = IntStream.range(0, lst.size()).map((i)-> {
List<Integer> aux = lst.subList(0, i+1);
int out=aux.stream().reduce(0,Integer::sum);
return out;
}).boxed()
.collect(Collectors.toList());
System.out.println(updList.stream().map(i->String.valueOf(i)).collect(Collectors.joining(",")));
如果没有流,你怎么写呢?将for循环替换为IntStream.range…@Eugene你的意思是流索引?@Scratte完全正确。可能是重复的
List<Integer> lst = Arrays.asList(1,1,2,1,3);
List<Integer> updList = IntStream.range(0, lst.size()).map((i)-> {
List<Integer> aux = lst.subList(0, i+1);
int out=aux.stream().reduce(0,Integer::sum);
return out;
}).boxed()
.collect(Collectors.toList());
System.out.println(updList.stream().map(i->String.valueOf(i)).collect(Collectors.joining(",")));
1,2,4,5,8