Java 8 Stream排序字符串列表[重复]

Posted

技术标签:

【中文标题】Java 8 Stream排序字符串列表[重复]【英文标题】:Java 8 Stream sorting List of String [duplicate] 【发布时间】:2017-02-18 10:23:31 【问题描述】:

我在流上调用 sorted 方法。 Java 文档说:

“Sorted 方法返回一个由该流的元素组成的流,按照自然顺序排序。”

但是当我运行下面的代码时:

List<String> list = new ArrayList<String>();
list.add("b");
list.add("a");
list.add("z");
list.add("p");
list.stream().sorted();
System.out.println(list);

我得到的输出为

[b, a, z, p]

为什么我没有得到自然排序的输出?

【问题讨论】:

sorted() 返回一个元素已排序的流,它不会对您当前的流进行排序。 @Snickers3192:您的意思是“它不会对List 进行排序”,因为没有“当前流”。 OP 表明,命名错误会导致混乱。 @Holger 对不起,用列表替换流。 【参考方案1】:

改变这个

list.stream().sorted();
System.out.println(list);

类似

list.stream().sorted().forEachOrdered(System.out::println);

您的方法是 println list (不是排序的流)。或者(或另外),您可以缩短初始化程序并重新收集 List 之类的

List<String> list = new ArrayList<>(Arrays.asList("b","a","z","p"));
list = list.stream().sorted().collect(Collectors.toList());
System.out.println(list);

哪些输出(如您所料)

[a, b, p, z]

【讨论】:

我想你的意思是forEachOrdered,而不是forEach 没有理由将Arrays.asList的结果复制到ArrayList;方法Arrays.asList 返回一个List。在任何一种情况下,列表都是可变的,不需要像list = list.stream().sorted().collect(Collectors.toList()); 这样的流绕道,一个简单的list.sort(null); 将就地对列表进行排序。【参考方案2】:

您应该收集排序的结果,然后将其分配给您的列表。

    List<String> list = new ArrayList<String>();
    list.add("b");
    list.add("a");
    list.add("z");
    list.add("p");
    list = list.stream().sorted().collect(Collectors.toList());
    System.out.println(list);

【讨论】:

【参考方案3】:

如果你想要你的排序列表。

让我们改变这个

list.stream().sorted();

list.sort((e1, e2) -> e1.compareTo(e2));

希望对您有所帮助!

【讨论】:

不幸的是,这不是一个可以接受的答案。因为,OP的方式确实是正确的。您无需传递自定义比较器即可获得给定字符串对象流的自然顺序。顺便提一句;以上2个答案将指出出了什么问题。希望你能从中学到一些东西:) @Jude:你知道打电话给list.stream().sorted()和打电话给list.sort(…)的区别吗?自定义比较器可能已经过时,但这个答案是正确的。 @Holger 嗨,第一个只会按自然顺序对元素进行排序。 (使用 compareTo 或 obj.toString().compareTo() 实现)。哦,伙计……这是从 Java 8 添加到 List 接口的新默认方法。对不起这是我的错。但是,这个答案并没有指出除非有终端操作,否则中间操作不会触发。 @Jude:即使使用终端操作,流操作也不会修改源列表。是的,这个答案缺乏解释,但提供了一个直接的解决方案。不过,我更喜欢list.sort(null)list.sort(Comparator.naturalOrder())... @Holger 是的。 Comparator.naturalOrder() 是重点。【参考方案4】:

您的流没有终端运算符,因此不会被处理。终端操作符包括但不限于:forEach、toArray、reduce、collect。您的代码段应类似于

list.stream().sorted().forEachOrdered(System.out::println);

【讨论】:

我想你的意思是forEachOrdered,而不是forEach @LouisWasserman 啊,是的,谢谢。我会确保编辑它。

以上是关于Java 8 Stream排序字符串列表[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Java 8 Stream 映射调用字符串与合并为一个 [重复]

Java 8 Stream 按键过滤对象列表。排除列表中的键并获取字符串

Java 8 Stream 函数将字谜列表分组为列表映射

按字符串属性C#对对象列表进行排序[重复]

Java 8 流映射到按值排序的键列表

Java 8 Stream入门