Sorting of Objects

About

Sorting of objects in Java is the process of arranging object instances in a specific order typically ascending or descending based on one or more properties of the object. Unlike primitive types, sorting objects requires defining how they should be compared, as Java does not inherently know which fields or attributes determine their order.

Sorting is not limited to alphabetical or numerical order it can involve multi-level criteria, domain-specific rules, or even complex comparisons like date/time, version numbers, or locale-aware strings.

Arrays

Ascending Order

// Integer array
int[] intArray = {5, 2, 9, 1, 5, 6};
Arrays.sort(intArray);
System.out.println(Arrays.toString(intArray));

// Character array
char[] charArray = {'b', 'a', 'd', 'c'};
Arrays.sort(charArray);
System.out.println(Arrays.toString(charArray));

// Long array
long[] longArray = {5L, 2L, 9L, 1L, 5L, 6L};
Arrays.sort(longArray);
System.out.println(Arrays.toString(longArray));

// String array
String[] stringArray = {"banana", "apple", "cherry"};
Arrays.sort(stringArray);
System.out.println(Arrays.toString(stringArray));

Descending Order

// Integer array
Integer[] intArray = {5, 2, 9, 1, 5, 6};
Arrays.sort(intArray, Collections.reverseOrder());
System.out.println(Arrays.toString(intArray));

// Character array
Character[] charArray = {'b', 'a', 'd', 'c'};
Arrays.sort(charArray, Collections.reverseOrder());
System.out.println(Arrays.toString(charArray));

// Long array
Long[] longArray = {5L, 2L, 9L, 1L, 5L, 6L};
Arrays.sort(longArray, Collections.reverseOrder());
System.out.println(Arrays.toString(longArray));

// String array
String[] stringArray = {"banana", "apple", "cherry"};
Arrays.sort(stringArray, Collections.reverseOrder());
System.out.println(Arrays.toString(stringArray));

List

Wrapper Primitive

Ascending Order

// Integer list
List<Integer> intList = new ArrayList<>(List.of(5, 2, 9, 1, 5, 6));
Collections.sort(intList);
System.out.println(intList);

// Character list
List<Character> charList = new ArrayList<>(List.of('b', 'a', 'd', 'c'));
Collections.sort(charList);
System.out.println(charList);

// Long list
List<Long> longList = new ArrayList<>(List.of(5L, 2L, 9L, 1L, 5L, 6L));
Collections.sort(longList);
System.out.println(longList);

// String list
List<String> stringList = new ArrayList<>(List.of("banana", "apple", "cherry"));
Collections.sort(stringList);
System.out.println(stringList);

Descending Order

// Integer list
List<Integer> intList = new ArrayList<>(List.of(5, 2, 9, 1, 5, 6));
Collections.sort(intList, Collections.reverseOrder());
// Or intList.sort(Collections.reverseOrder());
System.out.println(intList);

// Character list
List<Character> charList = new ArrayList<>(List.of('b', 'a', 'd', 'c'));
Collections.sort(charList, Collections.reverseOrder());
System.out.println(charList);

// Long list
List<Long> longList = new ArrayList<>(List.of(5L, 2L, 9L, 1L, 5L, 6L));
Collections.sort(longList, Collections.reverseOrder());
System.out.println(longList);

// String list
List<String> stringList = new ArrayList<>(List.of("banana", "apple", "cherry"));
Collections.sort(stringList, Collections.reverseOrder());
System.out.println(stringList);

Custom Object - Using Comparator

Consider a Person class below as a custom object

public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

Ascending Order

List<Person> people = new ArrayList<>();
people.add(new Person("Alice", 30));
people.add(new Person("Bob", 25));
people.add(new Person("Charlie", 35));

// Sorting by age in ascending order
Collections.sort(people, Comparator.comparingInt(Person::getAge));
people.forEach(p -> System.out.println(p.getName() + " - " + p.getAge()));

Descending Order

List<Person> people = new ArrayList<>();
people.add(new Person("Alice", 30));
people.add(new Person("Bob", 25));
people.add(new Person("Charlie", 35));

// Sorting by age in descending order
people.sort(Comparator.comparingInt(Person::getAge).reversed());
people.forEach(p -> System.out.println(p.getName() + " - " + p.getAge()));

Custom Object - Using Comparable interface

Create a Java class Pair that represents a pair of integers and provides functionality to sort a collection of its objects based on a custom-defined order.

Requirements:

  1. Attributes:

    • The Pair class should have two integer attributes: first and second.

  2. Constructor:

    • Implement a parameterized constructor that accepts two integers a and b.

    • Initialize the first attribute with a and the second attribute with b.

  3. Custom Sorting Logic:

    • The class should implement the Comparable interface.

    • Define the sorting order using the compareTo method as follows:

      • Sort by the second attribute in descending order.

      • If the second attributes are equal, sort by the first attribute in descending order.

  4. Example: Given an array or list of Pair objects, the custom sorting should work as follows:

    Input:

    Pairs: (3, 4), (1, 4), (5, 2), (2, 2), (3, 3)

    Sorted Output:

    Pairs: (3, 4), (1, 4), (3, 3), (5, 2), (2, 2)
class Pair implements Comparable<Pair> {
    private int first;
    private int second;

    // Parameterized constructor
    public Pair(int a, int b) {
        this.first = a;
        this.second = b;
    }

    // Getters for first and second
    public int getFirst() {
        return first;
    }

    public int getSecond() {
        return second;
    }

    // Override compareTo to define the custom sorting logic
    @Override
    public int compareTo(Pair other) {
        // First compare by second in descending order
        if (this.second != other.second) {
            return Integer.compare(other.second, this.second);
        }
        // If second is the same, compare by first in descending order
        return Integer.compare(other.first, this.first);
    }

    @Override
    public String toString() {
        return "(" + first + ", " + second + ")";
    }

    // Main method
    public static void main(String[] args) {
        // Create a list of Pair objects
        List<Pair> pairs = new ArrayList<>();
        pairs.add(new Pair(3, 4));
        pairs.add(new Pair(1, 4));
        pairs.add(new Pair(5, 2));
        pairs.add(new Pair(2, 2));
        pairs.add(new Pair(3, 3));

        // Sort the pairs using the Comparable interface
        Collections.sort(pairs);

        // Print the sorted list
        for (Pair pair : pairs) {
            System.out.println(pair);
        }
    }
}

Custom Object - Using Lambda expression in Method

    // Method to provide the custom comparator
    public static Comparator<Pair> getCustomComparator() {
        return (p1, p2) -> {
            // Compare by second in descending order
            if (p1.getSecond() != p2.getSecond()) {
                return Integer.compare(p2.getSecond(), p1.getSecond());
            }
            // If second is the same, compare by first in descending order
            return Integer.compare(p2.getFirst(), p1.getFirst());
        };
    }
    
    // We can use like below in the above example
    pairs.sort(Pair.getCustomComparator());

Sets

Wrapper Primitive

We usually use a TreeSet to maintain order.

Ascending Order

// Integer set
Set<Integer> intSet = new TreeSet<>(Set.of(5, 2, 9, 1, 7, 6));
System.out.println(intSet);

// Character set
Set<Character> charSet = new TreeSet<>(Set.of('b', 'a', 'd', 'c'));
System.out.println(charSet);

// Long set
Set<Long> longSet = new TreeSet<>(Set.of(5L, 2L, 9L, 1L, 7L, 6L));
System.out.println(longSet);

// String set
Set<String> stringSet = new TreeSet<>(Set.of("banana", "apple", "cherry"));
System.out.println(stringSet);

Descending Order

// Integer set
Set<Integer> intSet = new TreeSet<>(Collections.reverseOrder());
intSet.addAll(Set.of(5, 2, 9, 1, 7, 6));
System.out.println(intSet);

// Character set
Set<Character> charSet = new TreeSet<>(Collections.reverseOrder());
charSet.addAll(Set.of('b', 'a', 'd', 'c'));
System.out.println(charSet);

// Long set
Set<Long> longSet = new TreeSet<>(Collections.reverseOrder());
longSet.addAll(Set.of(5L, 2L, 9L, 1L, 7L, 6L));
System.out.println(longSet);

// String set
Set<String> stringSet = new TreeSet<>(Collections.reverseOrder());
stringSet.addAll(Set.of("banana", "apple", "cherry"));
System.out.println(stringSet);

Custom Objects

Ascending Order

Set<Person> people = new TreeSet<>(Comparator.comparingInt(Person::getAge));
people.add(new Person("Alice", 30));
people.add(new Person("Bob", 25));
people.add(new Person("Charlie", 35));

people.forEach(p -> System.out.println(p.getName() + " - " + p.getAge()));
Set<Person> personSet = new HashSet<>();
personSet.add(new Person("Alice", 30));
personSet.add(new Person("Bob", 25));
personSet.add(new Person("Charlie", 35));

List<Person> personList = new ArrayList<>(personSet);
personList.sort(Comparator.comparingInt(Person::getAge));

personList.forEach(p -> System.out.println(p.getName() + " - " + p.getAge()));

Descending Order

Set<Person> personSet = new HashSet<>();
personSet.add(new Person("Alice", 30));
personSet.add(new Person("Bob", 25));
personSet.add(new Person("Charlie", 35));

List<Person> personList = new ArrayList<>(personSet);
personList.sort(Comparator.comparingInt(Person::getAge).reversed());

personList.forEach(p -> System.out.println(p.getName() + " - " + p.getAge()));
Set<Person> people = new TreeSet<>(Comparator.comparingInt(Person::getAge).reversed());
people.add(new Person("Alice", 30));
people.add(new Person("Bob", 25));
people.add(new Person("Charlie", 35));

people.forEach(p -> System.out.println(p.getName() + " - " + p.getAge()));

Maps

Maps in Java do not have a natural order, so to sort them we often sort their keys or values and then create a new LinkedHashMap to maintain the order.

Wrapper Primitives

Ascending Order by Keys

Map<Integer, String> map = new HashMap<>();
map.put(5, "five");
map.put(2, "two");
map.put(8, "eight");

Map<Integer, String> sortedMap = new TreeMap<>(map);

for (Map.Entry<Integer, String> entry : sortedMap.entrySet())
System.out.println("Entry Key - " + entry.getKey() + " Entry Value - " + entry.getValue());

Ascending Order by Values

Map<Integer, String> map = new HashMap<>();
map.put(5, "five");
map.put(2, "two");
map.put(8, "eight");

List<Map.Entry<Integer, String>> entries = new ArrayList<>(map.entrySet());
entries.sort(Map.Entry.comparingByValue());

Map<Integer, String> sortedMapByValue = new LinkedHashMap<>();
for (Map.Entry<Integer, String> entry : entries) {
    sortedMapByValue.put(entry.getKey(), entry.getValue());
}

for (Map.Entry<Integer, String> entry : sortedMapByValue.entrySet()) {
    System.out.println("Entry Key - " + entry.getKey() + " Entry Value - " + entry.getValue());
}

Descending Order by Keys

Map<Integer, String> map = new HashMap<>();
map.put(5, "five");
map.put(2, "two");
map.put(8, "eight");

Map<Integer, String> sortedMap = new TreeMap<>(Collections.reverseOrder());
sortedMap.putAll(map);

for (Map.Entry<Integer, String> entry : sortedMap.entrySet()) {
    System.out.println("Entry Key - " + entry.getKey() + " Entry Value - " + entry.getValue());
}

Descending Order by Values

Map<Integer, String> map = new HashMap<>();
map.put(5, "five");
map.put(2, "two");
map.put(8, "eight");

List<Map.Entry<Integer, String>> entries = new ArrayList<>(map.entrySet());
entries.sort(Map.Entry.comparingByValue(Comparator.reverseOrder()));

Map<Integer, String> sortedMapByValue = new LinkedHashMap<>();
for (Map.Entry<Integer, String> entry : entries) {
    sortedMapByValue.put(entry.getKey(), entry.getValue());
}

for (Map.Entry<Integer, String> entry : sortedMapByValue.entrySet()) {
    System.out.println("Entry Key - " + entry.getKey() + " Entry Value - " + entry.getValue());
}

Custom Object

Person Class

class Person {
    private String id;
    private String name;
    private int age;

    public Person(String id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

Ascending Order by Keys

Map<String, Person> personMap = new HashMap<>();
personMap.put("2", new Person("2", "Bob", 25));
personMap.put("1", new Person("1", "Alice", 30));
personMap.put("3", new Person("3", "Charlie", 35));

Map<String, Person> sortedByKeyMap = new TreeMap<>(personMap);

// Print sorted map
sortedByKeyMap.forEach((key, value) -> System.out.println(key + ": " + value));

Descending Order by Keys

Map<String, Person> personMap = new HashMap<>();
personMap.put("2", new Person("2", "Bob", 25));
personMap.put("1", new Person("1", "Alice", 30));
personMap.put("3", new Person("3", "Charlie", 35));

Map<String, Person> sortedByKeyDescMap = new TreeMap<>(Collections.reverseOrder());
sortedByKeyDescMap.putAll(personMap);

// Print sorted map
sortedByKeyDescMap.forEach((key, value) -> System.out.println(key + ": " + value));

Ascending Order by Values (Person's Age)

Map<String, Person> personMap = new HashMap<>();
personMap.put("2", new Person("2", "Bob", 25));
personMap.put("1", new Person("1", "Alice", 30));
personMap.put("3", new Person("3", "Charlie", 35));

List<Map.Entry<String, Person>> entries = new ArrayList<>(personMap.entrySet());
entries.sort(Map.Entry.comparingByValue(Comparator.comparingInt(Person::getAge)));

Map<String, Person> sortedByValueMap = new LinkedHashMap<>();
for (Map.Entry<String, Person> entry : entries) {
        sortedByValueMap.put(entry.getKey(), entry.getValue());
}

// Print sorted map
sortedByValueMap.forEach((key, value) -> System.out.println(key + ": " + value));

Descending Order by Values (Person's Age)

Map<String, Person> personMap = new HashMap<>();
personMap.put("2", new Person("2", "Bob", 25));
personMap.put("1", new Person("1", "Alice", 30));
personMap.put("3", new Person("3", "Charlie", 35));

List<Map.Entry<String, Person>> entries = new ArrayList<>(personMap.entrySet());
entries.sort(Map.Entry.comparingByValue(Comparator.comparingInt(Person::getAge).reversed()));

Map<String, Person> sortedByValueMap = new LinkedHashMap<>();
for (Map.Entry<String, Person> entry : entries) {
        sortedByValueMap.put(entry.getKey(), entry.getValue());
}

// Print sorted map
sortedByValueMap.forEach((key, value) -> System.out.println(key + ": " + value));

Nested List

Wrapper Primitives

Ascending Order

List<List<Integer>> nestedList = new ArrayList<>();
nestedList.add(Arrays.asList(3, 5, 4));
nestedList.add(Arrays.asList(8, 2, 6));

// Sort inner lists
for (List<Integer> list : nestedList) {
        Collections.sort(list);
}

// Sort outer list based on the first element of each inner list
nestedList.sort(Comparator.comparingInt(list -> list.get(0)));

nestedList.forEach(System.out::println);

Descending Order

List<List<Integer>> nestedList = new ArrayList<>();
nestedList.add(Arrays.asList(3, 5, 4));
nestedList.add(Arrays.asList(8, 2, 6));

// Sort inner lists in reverse order
for (List<Integer> list : nestedList) {
        Collections.sort(list, Collections.reverseOrder());
}

// Sort outer list in reverse order based on the first element of each inner list
nestedList.sort(Comparator.comparingInt((List<Integer> list) -> list.get(0)).reversed());

nestedList.forEach(System.out::println);

Custom Object

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

Ascending Order by Age

List<List<Person>> nestedPersonList = new ArrayList<>();
nestedPersonList.add(Arrays.asList(new Person("Alice", 30), new Person("Bob", 25)));
nestedPersonList.add(Arrays.asList(new Person("Charlie", 35), new Person("Dave", 28)));

// Sort inner lists by age
for (List<Person> list : nestedPersonList) {
        list.sort(Comparator.comparingInt(Person::getAge));
}

// Sort outer list by the first person's age in each inner list
nestedPersonList.sort(Comparator.comparingInt(list -> list.get(0).getAge()));

nestedPersonList.forEach(System.out::println);

Descending Order by Age

List<List<Person>> nestedPersonList = new ArrayList<>();
nestedPersonList.add(Arrays.asList(new Person("Alice", 30), new Person("Bob", 25)));
nestedPersonList.add(Arrays.asList(new Person("Charlie", 35), new Person("Dave", 28)));

// Sort inner lists by age in reverse order
for (List<Person> list : nestedPersonList) {
        list.sort(Comparator.comparingInt(Person::getAge).reversed());
}

// Sort outer list by the first person's age in reverse order
nestedPersonList.sort(Comparator.comparingInt((List<Person> list) -> list.get(0).getAge()).reversed());

nestedPersonList.forEach(System.out::println);

Nested Map

Wrapper Primitives

Ascending Order

Map<Integer, Map<Integer, String>> nestedMap = new HashMap<>();
nestedMap.put(1, new HashMap<>(Map.of(3, "three", 1, "one", 2, "two")));
nestedMap.put(2, new HashMap<>(Map.of(6, "six", 5, "five", 4, "four")));

// Sort inner maps
for (Map.Entry<Integer, Map<Integer, String>> entry : nestedMap.entrySet()) {
        Map<Integer, String> sortedInnerMap = new TreeMap<>(entry.getValue());
        nestedMap.put(entry.getKey(), sortedInnerMap);
}

// Sort outer map
Map<Integer, Map<Integer, String>> sortedNestedMap = new TreeMap<>(nestedMap);
sortedNestedMap.forEach((key, value) -> System.out.println(STR."Key: \{key} Value: \{value}"));

Descending Order

Map<Integer, Map<Integer, String>> nestedMap = new HashMap<>();
nestedMap.put(1, new HashMap<>(Map.of(3, "three", 1, "one", 2, "two")));
nestedMap.put(2, new HashMap<>(Map.of(6, "six", 5, "five", 4, "four")));

// Sort inner maps in reverse order
for (Map.Entry<Integer, Map<Integer, String>> entry : nestedMap.entrySet()) {
    Map<Integer, String> sortedInnerMap = new TreeMap<>(Collections.reverseOrder());
    sortedInnerMap.putAll(entry.getValue());
    nestedMap.put(entry.getKey(), sortedInnerMap);
}

// Sort outer map in reverse order
Map<Integer, Map<Integer, String>> sortedNestedMap = new TreeMap<>(Collections.reverseOrder());
sortedNestedMap.putAll(nestedMap);

sortedNestedMap.forEach((key, value) -> System.out.println(STR."Key: \{key} Value: \{value}"));

Custom Object

Assuming Person as keys in nested maps.

Ascending Order

Map<Person, Map<Person, String>> nestedPersonMap = new HashMap<>();
nestedPersonMap.put(new Person("Group1", 50), new HashMap<>(Map.of(new Person("Alice", 30), "Alice", new Person("Bob", 25), "Bob")));
nestedPersonMap.put(new Person("Group2", 60), new HashMap<>(Map.of(new Person("Charlie", 35), "Charlie", new Person("Dave", 28), "Dave")));

// Sort inner maps by age
for (Map.Entry<Person, Map<Person, String>> entry : nestedPersonMap.entrySet()) {
    Map<Person, String> sortedInnerMap = new TreeMap<>(Comparator.comparingInt(Person::getAge));
    sortedInnerMap.putAll(entry.getValue());
    nestedPersonMap.put(entry.getKey(), sortedInnerMap);
}

// Sort outer map by age
Map<Person, Map<Person, String>> sortedNestedPersonMap = new TreeMap<>(Comparator.comparingInt(Person::getAge));
sortedNestedPersonMap.putAll(nestedPersonMap);

sortedNestedPersonMap.forEach((key, value) -> System.out.println(STR."Key: \{key} Value: \{value}"));

Descending Order

Map<Person, Map<Person, String>> nestedPersonMap = new HashMap<>();
nestedPersonMap.put(new Person("Group1", 50), new HashMap<>(Map.of(new Person("Alice", 30), "Alice", new Person("Bob", 25), "Bob")));
nestedPersonMap.put(new Person("Group2", 60), new HashMap<>(Map.of(new Person("Charlie", 35), "Charlie", new Person("Dave", 28), "Dave")));

// Sort inner maps by age in reverse order
for (Map.Entry<Person, Map<Person, String>> entry : nestedPersonMap.entrySet()) {
        Map<Person, String> sortedInnerMap = new TreeMap<>(Comparator.comparingInt(Person::getAge).reversed());
        sortedInnerMap.putAll(entry.getValue());
        nestedPersonMap.put(entry.getKey(), sortedInnerMap);
}

// Sort outer map by age in reverse order
Map<Person, Map<Person, String>> sortedNestedPersonMap = new TreeMap<>(Comparator.comparingInt(Person::getAge).reversed());
sortedNestedPersonMap.putAll(nestedPersonMap);

sortedNestedPersonMap.forEach((key, value) -> System.out.println(STR."Key: \{key} Value: \{value}"));

Nested Set

Since Set does not maintain order, we'll use a sorted Set implementation like TreeSet.

Wrapper Primitives

Ascending Order

Set<Set<Integer>> nestedSet = new HashSet<>();
nestedSet.add(new HashSet<>(Arrays.asList(3, 5, 1)));
nestedSet.add(new HashSet<>(Arrays.asList(8, 2, 6)));

// Sort inner sets
Set<Set<Integer>> sortedNestedSet = new TreeSet<>(Comparator.comparingInt(set -> set.iterator().next()));
for (Set<Integer> set : nestedSet) {
        sortedNestedSet.add(new TreeSet<>(set));
}

sortedNestedSet.forEach(System.out::println);

Descending Order

Set<Set<Integer>> nestedSet = new HashSet<>();
nestedSet.add(new HashSet<>(Arrays.asList(3, 5, 1)));
nestedSet.add(new HashSet<>(Arrays.asList(8, 2, 6)));

// Sort inner sets
Set<Set<Integer>> sortedNestedSet = new TreeSet<>(Comparator.comparingInt((Set<Integer> set) -> set.iterator().next()).reversed());
for (Set<Integer> set : nestedSet) {
        sortedNestedSet.add(new TreeSet<>(set).descendingSet());
}

sortedNestedSet.forEach(System.out::println);

Custom Object

Assuming Person as elements in sets.

Ascending Order

Set<Set<Person>> nestedPersonSet = new HashSet<>();
nestedPersonSet.add(new HashSet<>(Arrays.asList(new Person("Alice", 30), new Person("Bob", 25))));
nestedPersonSet.add(new HashSet<>(Arrays.asList(new Person("Charlie", 35), new Person("Dave", 28))));

// Sort inner sets by age
Set<Set<Person>> sortedNestedPersonSet = new TreeSet<>(Comparator.comparingInt(set -> set.iterator().next().getAge()));
for (Set<Person> set : nestedPersonSet) {
        Set<Person> sortedInnerSet = new TreeSet<>(Comparator.comparingInt(Person::getAge));
        sortedInnerSet.addAll(set);
        sortedNestedPersonSet.add(sortedInnerSet);
}

sortedNestedPersonSet.forEach(System.out::println);

Descending Orde

Set<Set<Person>> nestedPersonSet = new HashSet<>();
nestedPersonSet.add(new HashSet<>(Arrays.asList(new Person("Alice", 30), new Person("Bob", 25))));
nestedPersonSet.add(new HashSet<>(Arrays.asList(new Person("Charlie", 35), new Person("Dave", 28))));

// Sort inner sets by age
Set<Set<Person>> sortedNestedPersonSet = new TreeSet<>(Comparator.comparingInt((Set<Person> set) -> set.iterator().next().getAge()).reversed());
for (Set<Person> set : nestedPersonSet) {
    Set<Person> sortedInnerSet = new TreeSet<>(Comparator.comparingInt(Person::getAge).reversed());
    sortedInnerSet.addAll(set);
    sortedNestedPersonSet.add(sortedInnerSet);
}

sortedNestedPersonSet.forEach(System.out::println);

Nested List of Set

Wrapper Primitives

Ascending Order

List<Set<Integer>> nestedListSet = new ArrayList<>();
nestedListSet.add(new HashSet<>(Arrays.asList(3, 5, 1)));
nestedListSet.add(new HashSet<>(Arrays.asList(8, 2, 6)));

// Sort inner sets
List<Set<Integer>> sortedNestedListSet = new ArrayList<>();
for (Set<Integer> set : nestedListSet) {
        Set<Integer> sortedSet = new TreeSet<>(set);
        sortedNestedListSet.add(sortedSet);
}

// Sort outer list based on the first element of each inner set
sortedNestedListSet.sort(Comparator.comparingInt(set -> set.iterator().next()));

// Print sorted nested list of sets
System.out.println("Ascending Order:");
sortedNestedListSet.forEach(System.out::println);

Descending Order

List<Set<Integer>> nestedListSet = new ArrayList<>();
nestedListSet.add(new HashSet<>(Arrays.asList(3, 5, 1)));
nestedListSet.add(new HashSet<>(Arrays.asList(8, 2, 6)));

// Sort inner sets in reverse order
List<Set<Integer>> sortedNestedListSet = new ArrayList<>();
for (Set<Integer> set : nestedListSet) {
        Set<Integer> sortedSet = new TreeSet<>(Collections.reverseOrder());
        sortedSet.addAll(set);
        sortedNestedListSet.add(sortedSet);
}

// Sort outer list based on the first element of each inner set in reverse order
sortedNestedListSet.sort(Comparator.comparingInt((Set<Integer> set) -> set.iterator().next()).reversed());

// Print sorted nested list of sets
System.out.println("Descending Order:");
sortedNestedListSet.forEach(System.out::println);

Custom Objects

Person Class

class Person {
    private String id;
    private String name;
    private int age;

    public Person(String id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Person{id='" + id + "', name='" + name + "', age=" + age + '}';
    }
}

Ascending Order

List<Set<Person>> nestedListSet = new ArrayList<>();
nestedListSet.add(new HashSet<>(Arrays.asList(new Person("1", "Alice", 30), new Person("2", "Bob", 25))));
nestedListSet.add(new HashSet<>(Arrays.asList(new Person("3", "Charlie", 35), new Person("4", "Dave", 28))));

// Sort inner sets by age
List<Set<Person>> sortedNestedListSet = new ArrayList<>();
for (Set<Person> set : nestedListSet) {
        Set<Person> sortedSet = new TreeSet<>(Comparator.comparingInt(Person::getAge));
        sortedSet.addAll(set);
        sortedNestedListSet.add(sortedSet);
}

// Sort outer list based on the first person's age in each inner set
sortedNestedListSet.sort(Comparator.comparingInt(set -> set.iterator().next().getAge()));

// Print sorted nested list of sets
System.out.println("Ascending Order by Age:");
sortedNestedListSet.forEach(System.out::println);

Descending Order

List<Set<Person>> nestedListSet = new ArrayList<>();
nestedListSet.add(new HashSet<>(Arrays.asList(new Person("1", "Alice", 30), new Person("2", "Bob", 25))));
nestedListSet.add(new HashSet<>(Arrays.asList(new Person("3", "Charlie", 35), new Person("4", "Dave", 28))));

// Sort inner sets by age in reverse order
List<Set<Person>> sortedNestedListSet = new ArrayList<>();
for (Set<Person> set : nestedListSet) {
        Set<Person> sortedSet = new TreeSet<>(Comparator.comparingInt(Person::getAge).reversed());
        sortedSet.addAll(set);
        sortedNestedListSet.add(sortedSet);
}

// Sort outer list based on the first person's age in each inner set in reverse order
sortedNestedListSet.sort(Comparator.comparingInt((Set<Person> set) -> set.iterator().next().getAge()).reversed());

// Print sorted nested list of sets
System.out.println("Descending Order by Age:");
sortedNestedListSet.forEach(System.out::println);

Nested List of Map

Wrapper Primitives

Ascending Order

List<Map<Integer, String>> nestedListMap = new ArrayList<>();
nestedListMap.add(new HashMap<>(Map.of(3, "three", 1, "one", 2, "two")));
nestedListMap.add(new HashMap<>(Map.of(6, "six", 5, "five", 4, "four")));

// Sort inner maps
List<Map<Integer, String>> sortedNestedListMap = new ArrayList<>();
for (Map<Integer, String> map : nestedListMap) {
        Map<Integer, String> sortedMap = new TreeMap<>(map);
        sortedNestedListMap.add(sortedMap);
}

// Sort outer list based on the first key in each inner map
sortedNestedListMap.sort(Comparator.comparingInt(map -> map.keySet().iterator().next()));

// Print sorted nested list of maps
System.out.println("Ascending Order:");
sortedNestedListMap.forEach(System.out::println);

Descending Order

List<Map<Integer, String>> nestedListMap = new ArrayList<>();
nestedListMap.add(new HashMap<>(Map.of(3, "three", 1, "one", 2, "two")));
nestedListMap.add(new HashMap<>(Map.of(6, "six", 5, "five", 4, "four")));

// Sort inner maps in reverse order
List<Map<Integer, String>> sortedNestedListMap = new ArrayList<>();
for (Map<Integer, String> map : nestedListMap) {
        Map<Integer, String> sortedMap = new TreeMap<>(Collections.reverseOrder());
        sortedMap.putAll(map);
        sortedNestedListMap.add(sortedMap);
}

// Sort outer list based on the first key in each inner map in reverse order
sortedNestedListMap.sort(Comparator.comparingInt((Map<Integer, String> map) -> map.keySet().iterator().next()).reversed());

// Print sorted nested list of maps
System.out.println("Descending Order:");
sortedNestedListMap.forEach(System.out::println);

Custom Object

Ascending Order

List<Map<String, Person>> nestedListMap = new ArrayList<>();
nestedListMap.add(new HashMap<>(Map.of("2", new Person("2", "Bob", 25), "1", new Person("1", "Alice", 30))));
nestedListMap.add(new HashMap<>(Map.of("4", new Person("4", "Dave", 28), "3", new Person("3", "Charlie", 35))));

// Sort inner maps by key
List<Map<String, Person>> sortedNestedListMap = new ArrayList<>();
for (Map<String, Person> map : nestedListMap) {
        Map<String, Person> sortedMap = new TreeMap<>(map);
        sortedNestedListMap.add(sortedMap);
}

// Sort outer list based on the first key in each inner map
sortedNestedListMap.sort(Comparator.comparing(map -> map.keySet().iterator().next()));

// Print sorted nested list of maps
System.out.println("Ascending Order by Key:");
sortedNestedListMap.forEach(System.out::println);

Descending Order

List<Map<String, Person>> nestedListMap = new ArrayList<>();
nestedListMap.add(new HashMap<>(Map.of("2", new Person("2", "Bob", 25), "1", new Person("1", "Alice", 30))));
nestedListMap.add(new HashMap<>(Map.of("4", new Person("4", "Dave", 28), "3", new Person("3", "Charlie", 35))));

// Sort inner maps by key in reverse order
List<Map<String, Person>> sortedNestedListMap = new ArrayList<>();
for (Map<String, Person> map : nestedListMap) {
        Map<String, Person> sortedMap = new TreeMap<>(Collections.reverseOrder());
        sortedMap.putAll(map);
        sortedNestedListMap.add(sortedMap);
}

// Sort outer list based on the first key in each inner map in reverse order
sortedNestedListMap.sort(Comparator.comparing((Map<String, Person> map) -> map.keySet().iterator().next()).reversed());

// Print sorted nested list of maps
System.out.println("Descending Order by Key:");
sortedNestedListMap.forEach(System.out::println);

Last updated