Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ordering List by a specific character (Java 8)

I have the following List:

List<String> fruits = new ArrayList<String>(Arrays.asList("Apple", "Banana", "Orange", "Watermelon", "Peach")); 

I need to order it with this condition:

  1. In the first place, the ones that contains the char "o" or "O"
  2. Then, the rest of them.

The result should be:

Orange, Watermelon, Apple, Banana, Peach

How can I do it in Java 8?

like image 763
hector s. Avatar asked Sep 06 '18 09:09

hector s.


1 Answers

You could use a Comparator chain.

List<String> fruits = new ArrayList<>(Arrays.asList(
                               "Apple", "Banana", "Orange", "Watermelon", "Peach"));
fruits.sort(Comparator.comparing((String s) -> !s.contains("O") && !s.contains("o"))
        .thenComparing(Comparator.naturalOrder()));
System.out.println(fruits.stream().collect(Collectors.joining(", ")));

The first comparator looks at whether the string contains an O making the ones which do go first, and the second comparator uses natural ordering.

Note: Boolean.TRUE.compareTo(Boolean.FALSE) > 0 so to make the strings which contain an O go first I flip this with a !

This prints

Orange, Watermelon, Apple, Banana, Peach

NOTE: In this case, the new ArrayList<>( ... ) isn't needed as sort doesn't change the number of elements, just re-arranges them.


EDIT: Based on @Holger's suggestion.

If a stable sort is preferred, i.e. leave the order as it was at much as possible.

List<String> fruits = Arrays.asList(
        "Watermelon", "Peach", "Orange", "Banana", "Apple");
fruits.sort(Comparator.comparing((String s) -> !s.contains("O") && !s.contains("o")));
System.out.println(fruits.stream().collect(Collectors.joining(", ")));

prints

Watermelon, Orange, Peach, Banana, Apple
like image 158
Peter Lawrey Avatar answered Oct 31 '22 14:10

Peter Lawrey