java - 流迭代不使用最后一个值

简化示例

我有以下代码生成一系列的总和,即 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/

相关文章:

.net - 投票 : What do you call your business layer b

performance - Oracle/PLSQL 性能

asp.net-mvc - ASP.NET MVC 中的 POST-redirect-GET 有什么

.net - 如何避免 .NET RegEx 类中的无限循环?

latex - LaTeX 环境中的多个命令

user-interface - 愚蠢且令人沮丧的跨浏览器 UI 问题

nlp - 自然语言中的范围歧义

c++ - 为什么即使还有弱指针,make_shared 也会调用析构函数?

java - @EnableGlobalMethodSecurity 在新的 spring boot

.net - Winform 样式问题 : Windows classics style?