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

Whi*_*cal 4 sorting lambda lazy-evaluation java-8 java-stream

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

如果我输入 2005 年、2020 年、2000 年、1967 年和 2018 年,我预计会得到以下结果(限制为 10):

2020
2019
2018 2018  
2017 2017
2016 2016 2016
2015 ...
Run Code Online (Sandbox Code Playgroud)

我正在使用的测试是:

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

任何其他近距离接触将不胜感激!

Hol*_*ger 5

的文档Stream.sorted()说:

\n\n
\n

这是一个有状态的中间操作

\n
\n\n

这又被描述为

\n\n
\n

有状态操作可能需要在产生结果之前处理整个输入。例如,在查看流的所有元素之前,无法通过对流进行排序来产生任何结果。

\n
\n\n

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

\n\n

您说您希望排序 \xe2\x80\x9c 是惰性的 \xe2\x80\x9d 但您实际期望的是在消耗后对每个项目再次进行排序,这意味着对n 个元素的流进行排序意味着实际上进行排序nn次,其他人都不会想到,特别是因为它peek并不意味着会产生影响正在进行的操作的副作用。

\n

  • 你已经有了一个[工作解决方案](http://stackoverflow.com/a/29202124/2711488),但我想解释一下你第一次尝试失败的背景...... (3认同)