Java Sort Using Comparators

Java sort using Comparators.

Comparator Interface

1
2
3
4
@FunctionalInterface
public interface Comparator<T> {
int compare(T o1, T o2);
}

java.util.Comparator is a functional interface. Functional interface is an interface that has exactly one abstract method. A functional interface can have any number of default methods, static methods, and abstract methods from the Object class.

The Comparator interface has only one abstract method, compare. The compare method compares its two arguments for order. It returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.

Comparator interface has multiple default and static methods to help us create comparators easily.

Sorting Using Lambda Expressions

sort method takes a comparator as an argument. We can use lambda expressions to create comparators.

Sorting integers in ascending order:

1
2
3
List<Integer> list = Arrays.asList(3, 1, 2);
list.sort((i1, i2) -> i1.compareTo(i2));
System.out.println(list); // [1, 2, 3]

Sorting Strings in descending order:

1
2
3
List<String> list = Arrays.asList("c", "a", "b");
list.sort( (s1,s2) -> s2.compareTo(s1));
System.out.println(list); // [c, b, a]

Sorting Integers

Sorting integers in ascending order:

1
2
3
List<Integer> list = Arrays.asList(3, 1, 2);
list.sort(Comparator.naturalOrder());
System.out.println(list); // [1, 2, 3]

Sorting integers in descending order:

1
2
3
List<Integer> list = Arrays.asList(3, 1, 2);
list.sort(Comparator.reverseOrder());
System.out.println(list); // [3, 2, 1]

Sorting Strings

Sorting strings in ascending order:

1
2
3
List<String> list = Arrays.asList("c", "a", "b");
list.sort(Comparator.naturalOrder());
System.out.println(list); // [a, b, c]

Sorting strings in descending order:

1
2
3
List<String> list = Arrays.asList("c", "a", "b");
list.sort(Comparator.reverseOrder());
System.out.println(list); // [c, b, a]

Sort strings by length in ascending order:

1
2
3
List<String> list = Arrays.asList("ccc", "aa", "b");
list.sort(Comparator.comparing(String::length));
System.out.println(list); // [b, aa, ccc]

Sorting Objects

Sort persons by age(Int) in ascending order:

1
2
3
4
5
6
7
8
9
10
11
class Person {
String name;
int age;
}
List<Person> list = Arrays.asList(
new Person("Alice", 20),
new Person("Bob", 30),
new Person("Charlie", 10)
);
list.sort(Comparator.comparingInt(Person::getAge));
System.out.println(list); // [Charlie, Alice, Bob]

sort persons by name(String) in descending order:

1
2
3
4
5
6
7
List<Person> list = Arrays.asList(
new Person("Alice", 20),
new Person("Bob", 30),
new Person("Charlie", 10)
);
list.sort(Comparator.comparing(Person::getName).reversed());
System.out.println(list); // [Charlie, Bob, Alice]

Sorting with Multiple Fields

sort persons by age in ascending order, then by name in descending order:

1
2
3
4
5
6
7
8
List<Person> list = Arrays.asList(
new Person("Alice", 20),
new Person("Bob", 30),
new Person("Charlie", 10),
new Person("Alice", 30)
);
list.sort(Comparator.comparingInt(Person::getAge).thenComparing(Person::getName).reversed());
System.out.println(list); // [Charlie, Alice, Bob, Alice]

Null Handling

sort persons by name in ascending order, nulls last:

1
2
3
4
5
6
7
8
List<Person> list = Arrays.asList(
new Person("Alice", 20),
new Person("Bob", 30),
new Person("Charlie", 10),
new Person(null, 40)
);
list.sort(Comparator.comparing(Person::getName, Comparator.nullsLast(Comparator.naturalOrder())));
System.out.println(list); // [Alice, Bob, Charlie, null]

Map Sorting by Key

sort a map by key in ascending order:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Map<String, Integer> map = new HashMap<>();
map.put("Alice", 25);
map.put("Bob", 30);
map.put("David", 40);
map.put("Charlie", 35);

LinkedHashMap<String, Integer> sortedMap = map.entrySet()
.stream()
.sorted(Map.Entry.<String, Integer>comparingByKey())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e2, LinkedHashMap::new));

sortedMap.forEach((k, v) -> {
System.out.println(k + " " + v);
});

Sort a map by key using string length in descending order:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Map<String, Integer> map = new HashMap<>();
map.put("Alice", 25);
map.put("Bob", 30);
map.put("David", 40);
map.put("Charlie", 35);

LinkedHashMap<String, Integer> sortedMap = map.entrySet()
.stream()
.sorted(Map.Entry.<String, Integer>comparingByKey(Comparator.comparing(String::length)).reversed())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e2, LinkedHashMap::new));

sortedMap.forEach((k, v) -> {
System.out.println(k + " " + v);
});

Map Sorting by Value

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Map<String, Integer> map = new HashMap<>();
map.put("Alice", 25);
map.put("Bob", 30);
map.put("David", 40);
map.put("Charlie", 35);

LinkedHashMap<String, Integer> sortedMap = map.entrySet()
.stream()
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e2, LinkedHashMap::new));

sortedMap.forEach((k, v) -> {
System.out.println(k + " " + v);
});