Java 8 – Sorting List of primitive, String & Custom Objects

In this article, we will discuss how to sort list of primitive int, String & Custom Objects in Java 1.8 version.

1. Stream sorted() method

  • This Stream method is an intermediate operation which sorts elements present in the stream according to natural order
  • If elements present in the stream aren’t Comparable then java.lang.ClassCastException is thrown when final terminal operation is executed
  • For ordered streams, the sort is stable
  • For unordered streams, no stability guarantees are made.
  • Stream’s sorted() method is stateful
  • Another intermediate operation can be applied to returned stream for example filter(), map(), distinct() methods can be applied after sorted() operation
  • Method signature :- Stream<T> sorted()

1.1 Sorting List of Primitive int

  • Here, there are first 10 natural numbers in random order
  • We are sorting these integer numbers in natural order (or ascending order) using Java 8 Stream’s sorted() method
  • Lambda expression – finally, printing sorted numbers using Java 8 Stream’s forEach() method to console

SortingPrimitiveIntNumbers.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package net.bench.resources.stream.sorted.example;
 
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
 
public class SortingPrimitiveIntNumbers {
 
    public static void main(String[] args) {
 
        // 1. List - 1st 10 natural numbers in random order
        List<Integer> numbers = Arrays.asList(7, 3, 10, 1, 8, 4, 6, 5, 2, 9);
         
        // pretty print numbers in random order
        System.out.println("1. Original List of Integer numbers in random order :\n");
        numbers.forEach(num -> System.out.print(num + "\t"));
 
        // 2. sorting using Stream's sorted() method
        List<Integer> sortedIntNumbers = numbers // original source elements
                .stream() // 2.1 get sequential stream
                .sorted() // 2.2 sort acc. to natural order
                .collect(Collectors.toList()); // 2.3 collect to new list after sorting
 
        // pretty printing to console
        System.out.println("\n\n\n2. Sorted integer numbers in Ascending order : \n");
        sortedIntNumbers.forEach(num -> System.out.print(num + "\t"));
    }
}

Output:

1
2
3
4
5
6
7
8
1. Original List of Integer numbers in random order :
 
7   3   10  1   8   4   6   5   2   9
 
 
2. Sorted integer numbers in Ascending order :
 
1   2   3   4   5   6   7   8   9   10

1.2 Sorting List of String Objects

  • Here, 1st we are defining few String elements in List
  • Then we are sorting these String elements in natural order (or alphabetical order) using Java 8 Stream’s sorted() method
  • Method reference – finally, printing sorted String elements using Java 8 Stream’s forEach() method to console

SortingStringObjects.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package net.bench.resources.stream.sorted.example;
 
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
 
public class SortingStringObjects {
 
    public static void main(String[] args) {
 
        // 1. List of String elements
        List<String> companies = Arrays.asList(
                "Infosys",
                "Capgemini",
                "Hexaware",
                "LTI",
                "Accenture"
                );
 
        // pretty print to console
        System.out.println("1. Original List of String :\n");
        companies.forEach(System.out::println);
 
        // 2. sorting using Stream's sorted() method
        List<String> sortedCompanyNames = companies // original source elements
                .stream() // 2.1 get sequential stream
                .sorted() // 2.2 sorting alphabetical order of String elements
                .collect(Collectors.toList()); // 2.3 collect to new list after sorting
 
        // pretty print to console
        System.out.println("\n2. Sorted Company Names in Alphabetical order : \n");
        sortedCompanyNames.forEach(System.out::println);
    }
}

Output:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1. Original List of String :
 
Infosys
Capgemini
Hexaware
LTI
Accenture
 
2. Sorted Company Names in Alphabetical order :
 
Accenture
Capgemini
Hexaware
Infosys
LTI

2. Stream sorted(Comparator) method

  • This Stream method is an intermediate operation which sorts elements present in the stream according to Comparator provided
  • This Comparator logic can be either in natural order or reverse order depending upon our business requirement
  • For ordered streams, the sort is stable
  • For unordered streams, no stability guarantees are made.
  • Stream’s sorted(Comparator) method is stateful
  • Method signature :- Stream<T> sorted(Comparator<? super T> comparator)

2.1 Sorting List of Custom Objects

  • Here, we are adding Player objects with 4 attributes (Id, Name, Average, Rank) to List object
  • Example-1 : sorting Player objects according to Id in natural order using Comparator p1, p2 -> p1.getId() – p2.getId(); and printing to console using lambda expression
  • Example-2 : sorting Player objects according to Name in alphabetical order using Comparator p1, p2 -> p1.getName() .compare(p2.getName()); and printing to console using lambda expression
  • Example-3 : sorting Player objects according to Rank in natural order using Comparator p1, p2 -> p1.getRank() – p2.getRank(); and printing to console using lambda expression

Player.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Player {
 
    // private member variables
    private int id;
    private String name;
    private double average;
    private int rank;
 
    // public 4-arg parameterized constructor
 
    // getter and setters
 
    // override toString() method
}

SortingCustomObjects.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package net.bench.resources.stream.sorted.example;
 
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
 
public class SortingCustomObjects {
 
    public static void main(String[] args) {
 
        // 1. List of Student objects
        List<Player> fab5IndianOrder = Arrays.asList(
                new Player(1, "Dravid", 88.55, 2),
                new Player(2, "Sehwag", 55.65, 5),
                new Player(3, "Laxman", 77.75, 3),
                new Player(4, "Sachin", 99.25, 1),
                new Player(5, "Sourav", 66.15, 4)
                );
 
        // 1. unsorted players by any attributes - original list
        System.out.println("1. List of unsorted Players"
                + " in orginal list :\n");
        fab5IndianOrder.forEach(System.out::println);
 
 
        // 2. Natural sorting acc. to Player's Id
        List<Player> sortedById = fab5IndianOrder // original source
                .stream() // 2.1 get sequential stream
                .sorted((p1, p2) -> p1.getId() - p2.getId()) // 2.2 sort by Id
                .collect(Collectors.toList()); // 2.3 collect to new List
 
 
        // pretty print to console using lambda expression
        System.out.println("\n\n2. Players sorted acc. to"
                + " Natural order of Id :\n");
        sortedById.forEach(playerById -> System.out.println(playerById));
 
 
        // 3. Natural sorting acc. to Player's Name
        List<Player> sortedByName = fab5IndianOrder // original source
                .stream() // 3.1 get sequential stream
                .sorted((p1, p2) -> p1.getName()
                        .compareTo(p2.getName())) // 3.2 sort by Name
                .collect(Collectors.toList()); // 3.3 collect to new List
 
 
        // pretty print to console using lambda expression
        System.out.println("\n\n3. Players sorted acc. to"
                + " Alphabetical order of Name :\n");
        sortedByName.forEach(playerByName -> System.out.println(playerByName));
 
 
        // 4. Natural sorting acc. to Player's Rank
        List<Player> sortedByRank = fab5IndianOrder // original source
                .stream() // 4.1 get sequential stream
                .sorted((p1, p2) -> Integer
                        .compare(p1.getRank(), p2.getRank()))// 4.2 Rank sort
                .collect(Collectors.toList()); // 4.3 collect to new List
 
 
        // pretty print to console using lambda expression
        System.out.println("\n\n4. Players sorted acc. to"
                + " Natural order of Rank :\n");
        sortedByRank.forEach(playerByRank -> System.out.println(playerByRank));
    }
}

Output:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
1. List of unsorted Players in orginal list :
 
Player [id=1, name=Dravid, average=88.55, rank=2]
Player [id=2, name=Sehwag, average=55.65, rank=5]
Player [id=3, name=Laxman, average=77.75, rank=3]
Player [id=4, name=Sachin, average=99.25, rank=1]
Player [id=5, name=Sourav, average=66.15, rank=4]
 
 
2. Players sorted acc. to Natural order of Id :
 
Player [id=1, name=Dravid, average=88.55, rank=2]
Player [id=2, name=Sehwag, average=55.65, rank=5]
Player [id=3, name=Laxman, average=77.75, rank=3]
Player [id=4, name=Sachin, average=99.25, rank=1]
Player [id=5, name=Sourav, average=66.15, rank=4]
 
 
3. Players sorted acc. to Alphabetical order of Name :
 
Player [id=1, name=Dravid, average=88.55, rank=2]
Player [id=3, name=Laxman, average=77.75, rank=3]
Player [id=4, name=Sachin, average=99.25, rank=1]
Player [id=2, name=Sehwag, average=55.65, rank=5]
Player [id=5, name=Sourav, average=66.15, rank=4]
 
 
4. Players sorted acc. to Natural order of Rank :
 
Player [id=4, name=Sachin, average=99.25, rank=1]
Player [id=1, name=Dravid, average=88.55, rank=2]
Player [id=3, name=Laxman, average=77.75, rank=3]
Player [id=5, name=Sourav, average=66.15, rank=4]
Player [id=2, name=Sehwag, average=55.65, rank=5]

3. Reverse sorting

  • This section covers example for sorting primitive int, String & Custom Objects in reverse order by passing Comparator
  • We can build logic around Comparator to sort elements in either natural order or reverse order
  • Comparator.naturalOrder() helps to sort in natural order, if the objects are Comparable otherwise java.lang.ClassCastException is thrown
  • Comparator.reverseOrder() helps to sort in reverse order, if the objects are Comparable otherwise java.lang.ClassCastException is thrown

3.1 Reverse sorting List of Primitive int

  • This example has list of integer numbers
  • we are sorting in natural & reverse order using Comparator.naturalOrder() i.e.; in ascending order & Comparator.reverseOrder() i.e.; in descending order respectively
  • Lambda expression – finally, printing sorted Student objects using Java 8 Stream’s forEach() method to console

ReverseSortingPrimitiveIntNumbers.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package net.bench.resources.stream.sorted.example;
 
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
 
public class ReverseSortingPrimitiveIntNumbers {
 
    public static void main(String[] args) {
 
        // 1. List - 10 numbers in random order
        List<Integer> numbers = Arrays.asList(
                35, 15, 10, 5, 50, 20, 45, 30, 25, 40
                );
 
        // pretty print numbers in random order
        System.out.println("1. Original List of"
                + " Integer numbers in Random order :\n");
        numbers.forEach(
                randomOrderNumber -> System.out.print(randomOrderNumber + "\t"));
 
 
        // 2. Ascending sorting using Stream.sorted() method
        List<Integer> sortedIntNumbers = numbers // original source elements
                .stream() // 2.1 get sequential stream
                .sorted(Comparator.naturalOrder()) // 2.2 sort acc. to natural order
                .collect(Collectors.toList()); // 2.3 collect to new list after sorting
 
 
        // pretty printing to console
        System.out.println("\n\n\n2. Natural sorting - Ascending order : \n");
        sortedIntNumbers.forEach(
                ascendingOrderNumber -> System.out.print(ascendingOrderNumber + "\t"));
 
 
        // 3. Descending sorting using Stream.sorted() method
        List<Integer> reverseNumbers = numbers // original source elements
                .stream() // 3.1 get sequential stream
                .sorted(Comparator.reverseOrder()) // 3.2 reverse sorting
                .collect(Collectors.toList()); // 3.3 collect to new list after sorting
 
 
        // pretty printing to console
        System.out.println("\n\n\n3. Reverse sorting - Descending order : \n");
        reverseNumbers.forEach(
                descendingOrderNumber -> System.out.print(descendingOrderNumber + "\t"));
    }
}

Output:

1
2
3
4
5
6
7
8
9
10
11
12
13
1. Original List of Integer numbers in Random order :
 
35  15  10  5   50  20  45  30  25  40 
 
 
2. Natural sorting - Ascending order :
 
5   10  15  20  25  30  35  40  45  50 
 
 
3. Reverse sorting - Descending order :
 
50  45  40  35  30  25  20  15  10  5

3.2 Reverse sorting List of String elements

  • This example has list of String elements
  • we are sorting in natural & reverse order using Comparator.naturalOrder() i.e.; in alphabetical order and Comparator.reverseOrder() respectively
  • Lambda expression – finally, printing sorted Student objects using Java 8 Stream’s forEach() method to console

ReverseSortingStringObjects.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package net.bench.resources.stream.sorted.example;
 
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
 
public class ReverseSortingStringObjects {
 
    public static void main(String[] args) {
 
        // 1. List of String elements
        List<String> companies = Arrays.asList(
                "Infosys",
                "Capgemini",
                "Hexaware",
                "LTI",
                "Accenture"
                );
 
        // pretty print to console
        System.out.println("1. Original List of String :\n");
        companies.forEach(System.out::println);
 
 
        // 2. natural sorting using Stream's sorted() method
        List<String> sortedCompanyNames = companies // original source
                .stream() // 2.1 get sequential stream
                .sorted(Comparator.naturalOrder()) // 2.2 sorting alphabetical order
                .collect(Collectors.toList()); // 2.3 collect to new list
 
 
        // pretty print to console
        System.out.println("\n2. Sorted by Company Names in Alphabetical order : \n");
        sortedCompanyNames.forEach(System.out::println);
 
 
        // 3. reverse sorting using Stream's sorted() method
        List<String> reverseSorting = companies // original source
                .stream() // 3.1 get sequential stream
                .sorted(Comparator.reverseOrder()) // 3.2 reverse sorting
                .collect(Collectors.toList()); // 3.3 collect to new list
 
 
        // pretty print to console
        System.out.println("\n3. Reverse Sorting of String elements : \n");
        reverseSorting.forEach(System.out::println);
    }
}

Output:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1. Original List of String :
 
Infosys
Capgemini
Hexaware
LTI
Accenture
 
2. Sorted by Company Names in Alphabetical order :
 
Accenture
Capgemini
Hexaware
Infosys
LTI
 
3. Reverse Sorting of String elements :
 
LTI
Infosys
Hexaware
Capgemini
Accenture

3.3 Reverse sorting List of Custom Objects

  • This example has list of Student objects
  • We are sorting Student objects based on all 4 attributes Id, Name, Rank & Average in reverse order
  • Reverse Id sorting – (p1, p2) -> p2.getId() – p1.getId();
  • Reverse Name sorting – (p1, p2) -> p2.getName().compareTo(p1.getName());
  • Reverse Rank sorting – (p1, p2) -> Integer.compare(p2.getRank(), p1.getRank());
  • Reverse Average sorting – (p1, p2) -> Double.compare(p2.getAverage(), p1.getAverage());
  • Lambda expression – finally, printing sorted Student objects using Java 8 Stream’s forEach() method to console

ReverseSortingCustomObjects.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package net.bench.resources.stream.sorted.example;
 
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
 
public class ReverseSortingCustomObjects {
 
    public static void main(String[] args) {
 
        // 1. List of Student objects
        List<Player> fab5IndianOrder = Arrays.asList(
                new Player(4, "Sachin", 99.25, 1),
                new Player(1, "Dravid", 88.55, 2),
                new Player(2, "Sehwag", 55.65, 5),
                new Player(5, "Sourav", 66.15, 4),
                new Player(3, "Laxman", 77.75, 3)
                );
 
        // 1. unsorted players by any attributes - original list
        System.out.println("1. UNSORTED Players in orginal list :\n");
        fab5IndianOrder.forEach(System.out::println);
 
 
        // 2. REVERSE sorting acc. to Player's Id
        List<Player> sortedById = fab5IndianOrder // original source
                .stream() // 2.1 get sequential stream
                .sorted((p1, p2) -> p2.getId() - p1.getId()) // 2.2 Id sort
                .collect(Collectors.toList()); // 2.3 collect to new List
 
 
        // pretty print to console using lambda expression
        System.out.println("\n\n2. REVERSE sorting of Players by Id :\n");
        sortedById.forEach(playerById -> System.out.println(playerById));
 
 
        // 3. REVERSE sorting acc. to Player's Name
        List<Player> sortedByName = fab5IndianOrder // original source
                .stream() // 3.1 get sequential stream
                .sorted((p1, p2) -> p2.getName()
                        .compareTo(p1.getName())) // 3.2 Name sort
                .collect(Collectors.toList()); // 3.3 collect to new List
 
 
        // pretty print to console using lambda expression
        System.out.println("\n\n3. REVERSE sorting of Players by Name :\n");
        sortedByName.forEach(playerByName -> System.out.println(playerByName));
 
        // 4. REVERSE sorting acc. to Player's Rank
        List<Player> sortedByRank = fab5IndianOrder // original source
                .stream() // 4.1 get sequential stream
                .sorted((p1, p2) -> Integer
                        .compare(p2.getRank(), p1.getRank())) // 4.2 Rank sort
                .collect(Collectors.toList()); // 4.3 collect to new List
 
 
        // pretty print to console using lambda expression
        System.out.println("\n\n4. REVERSE sorting of Players by Rank :\n");
        sortedByRank.forEach(playerByRank -> System.out.println(playerByRank));
 
 
        // 5. REVERSE sorting acc. to Player's Average
        List<Player> sortedByAverage = fab5IndianOrder // original source
                .stream() // 5.1 get sequential stream
                .sorted((p1, p2) -> Double
                        .compare(p2.getAverage(), p1.getAverage())) // 5.2 Average sort
                .collect(Collectors.toList()); // 5.3 collect to new List
 
 
        // pretty print to console using lambda expression
        System.out.println("\n\n5. REVERSE sorting of Players by Average :\n");
        sortedByAverage.forEach(playerByRank -> System.out.println(playerByRank));
    }
}

Output:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
1. UNSORTED Players in orginal list :
 
Player [id=4, name=Sachin, average=99.25, rank=1]
Player [id=1, name=Dravid, average=88.55, rank=2]
Player [id=2, name=Sehwag, average=55.65, rank=5]
Player [id=5, name=Sourav, average=66.15, rank=4]
Player [id=3, name=Laxman, average=77.75, rank=3]
 
 
2. REVERSE sorting of Players by Id :
 
Player [id=5, name=Sourav, average=66.15, rank=4]
Player [id=4, name=Sachin, average=99.25, rank=1]
Player [id=3, name=Laxman, average=77.75, rank=3]
Player [id=2, name=Sehwag, average=55.65, rank=5]
Player [id=1, name=Dravid, average=88.55, rank=2]
 
 
3. REVERSE sorting of Players by Name :
 
Player [id=5, name=Sourav, average=66.15, rank=4]
Player [id=2, name=Sehwag, average=55.65, rank=5]
Player [id=4, name=Sachin, average=99.25, rank=1]
Player [id=3, name=Laxman, average=77.75, rank=3]
Player [id=1, name=Dravid, average=88.55, rank=2]
 
 
4. REVERSE sorting of Players by Rank :
 
Player [id=2, name=Sehwag, average=55.65, rank=5]
Player [id=5, name=Sourav, average=66.15, rank=4]
Player [id=3, name=Laxman, average=77.75, rank=3]
Player [id=1, name=Dravid, average=88.55, rank=2]
Player [id=4, name=Sachin, average=99.25, rank=1]
 
 
5. REVERSE sorting of Players by Average :
 
Player [id=4, name=Sachin, average=99.25, rank=1]
Player [id=1, name=Dravid, average=88.55, rank=2]
Player [id=3, name=Laxman, average=77.75, rank=3]
Player [id=5, name=Sourav, average=66.15, rank=4]
Player [id=2, name=Sehwag, average=55.65, rank=5]

References:

Happy Coding !!
Happy Learning !!

Java 8 - Stream count() method with examples
Java 8 - Stream forEachOrdered() method