16

I am calling the sorted method on a stream. And the java doc says:

"Sorted method returns a stream consisting of the elements of this stream, sorted according to natural order."

But when I run the code below:

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);

I am getting output as

[b, a, z, p]

Why am I not getting the output of a natural sort?

3
  • 1
    sorted() returns a stream with the elements sorted, it doesn't sort your current stream. Commented Oct 10, 2016 at 3:14
  • @Snickers3192: you meant “it doesn’t sort the List” as there is no “current stream”. Naming things that wrong leads to exactly the confusion, the OP has shown. Commented Oct 10, 2016 at 15:03
  • @Holger Sorry yeah replace stream with list. Commented Oct 10, 2016 at 23:20

4 Answers 4

16

Change this

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

to something like

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

Your method is println the list (not the sorted stream). Alternatively (or additionally), you could shorten your initialization routine and re-collect the List like

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

Which outputs (as you probably expected)

[a, b, p, z]
Sign up to request clarification or add additional context in comments.

2 Comments

I think you mean forEachOrdered, not forEach.
There is no reason to copy the result of Arrays.asList to an ArrayList; the method Arrays.asList returns a List. In either case, the list is mutable and doesn’t need a stream detour like list = list.stream().sorted().collect(Collectors.toList()); a simple list.sort(null); will sort the list in-place.
9

You should collect the result of the sorting and then assign it to your list.

    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);

Comments

8

If you want to have your sorted list.

Let's change this

list.stream().sorted();

to

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

Hope this help!

5 Comments

unfortunately, this is not a acceptable answer. Because, the OP's way is indeed correct. You don't need to pass a custom comparator in order to get the natural ordering for a given stream of string objects. BTW; above 2 answers will point what has went wrong. Hope you could learn something from it :)
@Jude: do you know the difference between calling list.stream().sorted() and calling list.sort(…)? The custom comparator might be obsolete, still, this answer is correct.
@Holger hi, the 1st one will just sort the elements in natural order. (using compareTo or obj.toString().compareTo() implementations). Ohh, man... It's a new default method added from Java 8 to List interface. Sorry, my bad. But, this answer, doesn't point out the fact that intermediate operations won't fire unless having a terminal operation.
@Jude: even with a terminal operation, stream operations do not modify the source list. Yes, this answer lacks explanations, but provides a straight-forward solution. Though, I’d prefer list.sort(null) or list.sort(Comparator.naturalOrder())
@Holger yes. Comparator.naturalOrder() is to the point.
4

Your stream has no terminal operator, and therefore is not processed. Terminal operators include but are not limited to: forEach, toArray, reduce, collect. Your code segment should be similar to

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

2 Comments

I think you mean forEachOrdered, not forEach.
@LouisWasserman Ah yes, thank you. I'll make sure to edit it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.