我有以下代码生成一系列的总和,即 1, 1+2, 1+2+3, 1+2+3+4
public static void main(String[] args) {
Stream<Integer> inputStream = Stream.of(1,2,3,4);
Iterator<Integer> iterator = inputStream.iterator();
Stream<Integer> outputStream = Stream.iterate(
iterator.next(),
i -> iterator.hasNext(),
next -> {
return iterator.next() + next;
}
);
List<Integer> outputList = outputStream.collect(Collectors.toList());
System.out.println(outputList);
}
但这会打印:[1, 3, 6]
,缺少最后一个元素。
请注意,这似乎得到了我想要的正确检查,但是否有更好的解决方案?看起来很糟糕:
public static void main(String[] args) {
Stream<Integer> inputStream = Stream.of(1,2,3,4);
Iterator<Integer> iterator = inputStream.iterator();
AtomicBoolean check = new AtomicBoolean(true);
Stream<Integer> outputStream = Stream.iterate(
iterator.next(),
i -> check.get(),
next -> {
check.set(iterator.hasNext());
return iterator.hasNext() ? iterator.next() + next : next;
}
);
List<Integer> outputList = outputStream.collect(Collectors.toList());
System.out.println(outputList);
}
这是一个说明问题的通用代码。
public static <O, I> Stream<O> iterate(O seed, Stream<I> stream, BiFunction<I,O,O> function) {
return iterate(seed, stream.iterator(), function);
}
public static <O, I> Stream<O> iterate(O seed, Iterator<I> iterator, BiFunction<I,O,O> function) {
AtomicBoolean hasNext = new AtomicBoolean(true);
return Stream.iterate(
seed,
i -> hasNext.get(),
next -> {
hasNext.set(iterator.hasNext());
return iterator.hasNext() ? function.apply(iterator.next(), next) : next;
}
);
}
public static void main(String[] args) {
Stream<Integer> inputStream = Stream.of(2,3,4);
BiFunction<Integer, Integer, Integer> f = Integer::sum;
Stream<Integer> outputStream = iterate(1, inputStream, f);
List<Integer> outputList = outputStream.collect(Collectors.toList());
System.out.println(outputList);
}
基本上,我想这样做是因为我正在创建一个函数来预测计息账户的余额。
我希望能够获取日期流,然后生成余额流。这样你就不需要知道会有多少元素,甚至不需要知道日期的分布,这使它成为一种更灵活的方法。
另请注意,Stream
的下一个元素取决于前一个元素。这就是为什么我有一个 seed
代表第一个值(没有以前的值),这将是期初余额。
最佳答案
... but is there a better solution?
是的,一个优雅的解决方案可以是使用 Arrays#parallelPrefix
.
public class Main {
public static void main(String args[]) {
int[] arr = { 1, 2, 3, 4 };
Arrays.parallelPrefix(arr, Integer::sum);
System.out.println(Arrays.toString(arr));
}
}
输出:
[1, 3, 6, 10]
您始终可以在 Stream<Integer>
之间来回转换和 int[]
根据您的要求。
public class Main {
public static void main(String args[]) {
int[] arr = Stream.of(1, 2, 3, 4).mapToInt(Integer::valueOf).toArray();
Arrays.parallelPrefix(arr, Integer::sum);
System.out.println(Arrays.toString(arr));
// In case , you need a Stream<Integer> again
Stream<Integer> resultStream = Arrays.stream(arr).boxed();
// Or want the result as a List<Integer>
List<Integer> resultList = resultStream.toList();
System.out.println(resultList);
}
}
https://stackoverflow.com/questions/74783526/