说明
由于您使用的是IntStream,它只有一个sorted 方法的重载,这是自然顺序(这是有道理的)。
相反,将流从IntStream 装箱到Stream<Integer> 就足够了:
IntStream.range(1, 100)
.filter(x -> x % 2 != 0)
.boxed() // <--- boxed to Stream<Integer>
.sorted((o1,o2) -> -o1.compareTo(o2)) // now we can call compareTo on Integer
.forEach(System.out::println);
但是,正如 @Holger 在 cmets 中提到的那样:
永远不要使用像(o1,o2) -> -o1.compareTo(o2) 这样的比较器函数。它
compareTo 实现返回是完全合法的
Integer.MIN_VALUE,在这种情况下,否定将失败并产生
结果不一致。一个有效的反向比较器是 (o1,o2) ->
o2.compareTo(o1)
改进代码的建议。 JDK8
更好的方法是:
IntStream.range(1, 100)
.filter(x -> x % 2 != 0)
.boxed()
.sorted(Comparator.reverseOrder())
.forEachOrdered(System.out::println);
为什么?
- 已经有一个内置的比较器来执行如上所示的逆序。
- 如果您想保证在打印时按排序顺序查看元素,请使用
forEachOrdered(大喊@Holger 总是提醒我)
或者正如@Holger 所建议的那样,它都可以简化为:
IntStream.range(0, 50)
.map(i -> 99-i*2)
.forEachOrdered(System.out::println);
JDK9 变种
顺便说一句,在JDK9中,从您帖子中的代码开始,您可以先通过iterate将其简化为:
IntStream.iterate(1, i -> i <= 99, i -> i + 2)
.boxed()
.sorted(Comparator.reverseOrder())
.forEachOrdered(System.out::println);
通过这种方法,我们可以避免过滤器中间操作和以2为单位的增量。
最后你可以进一步简化它:
IntStream.iterate(99, i -> i > 0 , i -> i - 2)
.forEachOrdered(System.out::println);
通过这种方法,我们可以避免filter、boxed、sorted 等。