【问题标题】:Stream - print values before and after sort流 - 在排序之前和之后打印值
【发布时间】:2016-09-20 16:15:11
【问题描述】:

我是Java 8 的初学者,今天我刚刚开始使用我的第一个lambda 表达式。我有一个String 数组,想在排序前后打印值。下面是我的代码,现在它给出了stream has already operated upon or closed 异常,因为我在friendsStream 上使用了两次forEach

import java.util.stream.Stream;
class FirstLambda {
    public static void main(String [] args){
        String [] friends = new String [] {"C","A","B","D"};

        Stream<String> friendsStream = Stream.of(friends);

        System.out.println("My Friends:-");
        printStream(friendsStream);

        System.out.println("My Friends (after sort):- ");
        Stream<String> sortedFriends = friendsStream.sorted((String m,String n) -> m.compareTo(n));
        printStream(sortedFriends);
    }

    private static void printStream(Stream<String> stream) {
        stream.forEach(s->System.out.println(s));
    }
}

我的问题是,解决我的问题的最简单或最好的方法是什么?那就是使用java 8Stream(即lambda)在排序前后打印字符串值

【问题讨论】:

  • 您可以只使用friendsStream.sorted() 而不使用 lambda 进行排序,因为默认情况下它将使用 compareTo 方法。解决方案是使用两个不同的Stream 对象。
  • 我同意。但是,如何在排序之前和之后打印值?
  • @Sridhar 解决方案是使用两个不同的 Stream 对象。

标签: string sorting java-8 java-stream


【解决方案1】:

当你问“解决我的问题的最简单或最好的方法是什么?”时,答案是你根本不需要 Stream:

String[] friends = {"C", "A", "B", "D"};
System.out.println("My Friends: "+Arrays.toString(friends));
Arrays.sort(friends);
System.out.println("My Friends (after sort): "+Arrays.toString(friends));

请注意,Collection API 也是如此:

List<String> friends = Arrays.asList("C", "A", "B", "D");
System.out.println("My Friends: "+friends);
friends.sort(Comparator.naturalOrder());
System.out.println("My Friends (after sort): "+friends);

如果您想引入 Stream API,有几种方法。最简单的:

String[] friends = {"C", "A", "B", "D"};
System.out.println("My Friends: ");
Arrays.stream(friends).forEachOrdered(System.out::println);
System.out.println("My Friends (after sort): ");
Arrays.stream(friends).sorted().forEachOrdered(System.out::println);

请注意,Arrays.stream 是为现有数组构造流的首选方法,它也适用于int[]long[]double[],而Stream.of 是使用 varargs 特性构造具有给定参数的流的规范方式,例如Stream.of("C", "A", "B", "D").

我们可以将它用于下一个变体,使用单个流并窥视流:

Stream.of("C", "A", "B", "D")
      .peek(System.out::println)
      .sorted()
      .forEachOrdered(System.out::println);

但请注意,peek 主要用于调试 Stream 处理,因为它允许在处理元素时查看它们。

但是如果你想了解 Stream API,你应该避免使用forEachforEachOrdered,因为所有包含forEach/forEachOrdered 的操作最终只是编写循环的一种替代方式,而且不止通常是一种更复杂的方式。

考虑到实际的预期操作是编写要打印的字符串,更复杂的用法是:

String[] friends = {"C", "A", "B", "D"};
System.out.println("My Friends: "
    +Arrays.stream(friends).collect(Collectors.joining(", ")));
System.out.println("My Friends (after sort): "
    +Arrays.stream(friends).sorted().collect(Collectors.joining(", ")));

【讨论】:

  • 我喜欢偷看的单流..太棒了
  • 但是请注意,如上所述,这主要是为了找出元素是如何处理的,这很好学(所以你看到sort在终端之前强制处理所有源元素forEachOrdered 处理它们,这不是大多数其他中间操作的工作方式,例如,尝试使用 filter 而不是 sort),它有利于调试,但不是生产代码的正确解决方案。
  • 我不喜欢使用Collectors.joining,因为它在打印之前会在内存中创建一个可能很大的字符串。因此,它不如直接打印到System.out 那样有效。
  • 而使用Arrays.sortCollections.sort 的区别当然在于,支持数组/集合在过程中发生了变异,而流中没有。
  • @4castle:它总是在内存消耗和 I/O 操作数量之间进行权衡,但是打印元素是典型的示例代码,而在现实生活中几乎从未出现过代码。关于Arrays.sort/Collections.sort vs.Stream.sort,当然,如果你以后真的需要原始数组,你可以克隆数组,这就是Stream.sort的幕后发生的事情......
【解决方案2】:

每个Stream只能有一个终端操作。 forEach 是终端操作,所以每次使用printStream 时都必须使用单独的Stream 对象。

在排序前使用一个Stream,在排序后使用另一个Stream

import java.util.stream.Stream;
import java.util.Arrays;

public class FirstLambda {
    public static void main(String [] args) {
        String[] friends = new String[] {"C","A","B","D"};

        System.out.println("My Friends:-");
        printStream(Arrays.stream(friends));

        System.out.println("My Friends (after sort):- ");
        printStream(Arrays.stream(friends).sorted());
    }

    private static void printStream(Stream<?> stream) {
        stream.forEach(System.out::println);
    }
}

Ideone Demo

【讨论】:

    【解决方案3】:

    这是使用streams 的最简单方法。下面是一个使用排序前后输出结果对整数数组进行排序的示例。

    IntStream numbers = new Random().ints(10, 0, 20);
        numbers.boxed()
                .peek(n -> System.out.print(n+","))
                .sorted()
                .forEach(n -> System.out.print(n+"|"));
    

    【讨论】:

      猜你喜欢
      • 2019-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-02
      • 2021-06-18
      • 1970-01-01
      • 2013-06-12
      • 1970-01-01
      相关资源
      最近更新 更多