Java8 流中的惰性排序(),需要在每次迭代时求助

Lazy sorted() in Java8 Streams, need for resorting at each iteration

我正在寻找一种使用 Java 8 个流模拟以下行为的方法。 给定一系列年份,对它们进行排序,以便输出前 10 个值,这样 输出一年后,减少并再次重新开始迭代:

如果我输入 2005 年、2020 年、2000 年、1967 年和 2018 年,我希望在 10 的限制下得到以下结果:

2020
2019
2018 2018  
2017 2017
2016 2016 2016
2015 ...

我使用的测试是:

public class LazyTest {

    public static void main(String[] args) {
        Stream.of(2005,2020,2000,1967,2018)
              .map(YearWrapper::new)
              .sorted()
              .limit(10)
              .peek(year -> year.decreaseYear())
              .forEach(System.out::println);
    }

    public static class YearWrapper implements Comparable<YearWrapper>{
        private int currentYear;

        public YearWrapper(int year){
            this.currentYear=year;
        }
        public void decreaseYear(){
            currentYear--;
        }
        @Override
        public int compareTo(YearWrapper yearsToCompare) {
            return Integer.compare(yearsToCompare.currentYear, this.currentYear);
        }

        @Override
        public String toString(){
            return String.valueOf(currentYear);
        }
    }
}

不过看起来sorted()一点也不偷懒。整个排序在开始时完成一次,因此在任何进一步操作之前计算顺序,因此,示例的 5 个值按顺序逐一传递,因此 decrease() 对迭代没有实际影响。

有没有什么办法可以让 sorted() 变得懒惰并在流式传输下一个元素之前再次应用于剩余元素?

任何其他关闭方法将不胜感激!!

我对你的理解是否正确,你想从列表中取出最大的数字,递减它,把它放回列表中,重复 10 次?

如果是,那么这是 PriorityQueue 的工作:

PriorityQueue<Integer> queue = Stream.of(2005,2020,2000,1967,2018)
        .collect(toCollection(() -> new PriorityQueue(reverseOrder())));

Stream.generate(() -> {
    Integer year = queue.poll();
    queue.add(year - 1);
    return year;
}).limit(10).forEach(System.out::println);

documentation of Stream.sorted() 说:

This is a stateful intermediate operation.

这又是described as

Stateful operations may need to process the entire input before producing a result. For example, one cannot produce any results from sorting a stream until one has seen all elements of the stream.

这说明了排序的非惰性性质,但是,这与您的问题无关。即使排序是惰性的,也没有改变流的基本原则,即每个项目被流式传输到终端操作最多一次

您说您希望排序“懒惰”,但您实际期望的是在消费后对每个项目再次进行排序,这意味着对 n[=28 的流进行排序=] 元素意味着实际排序 nn 次,这是其他人不会想到的,特别是因为 peek 并不意味着影响正在进行的操作的副作用。