一般问题:什么是反转流的正确方法?假设我们不知道流由什么类型的元素组成,反转任何流的通用方法是什么?

具体问题:

IntStream提供了在特定范围内生成整数的range方法。range(-range, 0),现在我想反转它,从0到负切换范围将不起作用,我也不能使用Integer::比较

List<Integer> list = Arrays.asList(1,2,3,4);
list.stream().sorted(Integer::compare).forEach(System.out::println);

使用IntStream,我将得到这个编译器错误

错误:(191,0)ajc: IntStream类型中的sorted()方法不适用于参数(Integer::compare)

我错过了什么?


当前回答

回答与IntStream反转的具体问题,以下工作对我来说:

IntStream.range(0, 10)
  .map(x -> x * -1)
  .sorted()
  .map(Math::abs)
  .forEach(System.out::println);

其他回答

最通用和最简单的反转列表的方法是:

public static <T> void reverseHelper(List<T> li){

 li.stream()
.sorted((x,y)-> -1)
.collect(Collectors.toList())
.forEach(System.out::println);

    }

cyclops-react StreamUtils有一个反向流方法(javadoc)。

  StreamUtils.reverse(Stream.of("1", "2", "20", "3"))
             .forEach(System.out::println);

它的工作原理是收集到一个数组列表,然后使用可以向任意方向迭代的ListIterator类,在列表上向后迭代。

如果你已经有了一个List,它会更有效率

  StreamUtils.reversedStream(Arrays.asList("1", "2", "20", "3"))
             .forEach(System.out::println);

在所有这些问题中,我没有看到我首先要回答的答案。

这并不是对这个问题的直接回答,但却是一个潜在的解决方案。

只要一开始就逆向构建列表。如果可以的话,使用LinkedList而不是ArrayList,当你添加项目时使用“Push”而不是add。列表将以相反的顺序构建,然后将正确地流,而不需要任何操作。

这并不适用于您正在处理原始数组或列表的情况,这些原始数组或列表已经以各种方式使用,但在令人惊讶的大量情况下工作得很好。

优雅的解决方案

List<Integer> list = Arrays.asList(1,2,3,4);
list.stream()
    .sorted(Collections.reverseOrder()) // Method on Stream<Integer>
    .forEach(System.out::println);

作为参考,我正在考虑同样的问题,我想以相反的顺序连接流元素的字符串值。

itemList = {last, middle, first} =>第一个,中间,最后一个

我开始从comonad或Stuart Marks的ArrayDeque收集器中使用colltingandthen的中间收集,尽管我对中间收集不满意,然后再次使用流式

itemList.stream()
        .map(TheObject::toString)
        .collect(Collectors.collectingAndThen(Collectors.toList(),
                                              strings -> {
                                                      Collections.reverse(strings);
                                                      return strings;
                                              }))
        .stream()
        .collect(Collector.joining());

所以我迭代了Stuart Marks的答案,它使用了收集器。factory,它有一个有趣的结束项。

itemList.stream()
        .collect(Collector.of(StringBuilder::new,
                             (sb, o) -> sb.insert(0, o),
                             (r1, r2) -> { r1.insert(0, r2); return r1; },
                             StringBuilder::toString));

由于在这种情况下,流不是并行的,组合器不是那么相关,我使用插入无论如何为了代码的一致性,但这并不重要,因为它将取决于哪个stringbuilder是第一个构建的。

我看了看StringJoiner,但是它没有插入方法。