Java Ordering a map or list
Categories:
Mastering Java Collections: Sorting Maps and Lists

Learn how to effectively sort Lists and Maps in Java using various techniques, including Collections.sort(), Comparators, and Stream API, for both natural and custom ordering.
Ordering data is a fundamental operation in programming, crucial for presentation, search efficiency, and data processing. In Java, Lists and Maps are two of the most commonly used collection types, and understanding how to sort them is essential for any developer. While Lists inherently support ordering, Maps do not maintain insertion order by default (except for LinkedHashMap) and require specific approaches to achieve sorted views or new sorted maps.
Sorting Java Lists
Java Lists, being ordered collections, are straightforward to sort. The primary methods involve using Collections.sort() for natural ordering or providing a custom Comparator for more complex sorting logic. The Stream API also offers a concise way to sort and collect lists.
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
public class ListSorting {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("Alice");
names.add("Charlie");
names.add("Bob");
names.add("David");
System.out.println("Original List: " + names);
// 1. Natural Order Sorting (for Comparable elements)
Collections.sort(names);
System.out.println("Sorted (Natural Order): " + names);
// 2. Custom Order Sorting (using Comparator)
Collections.sort(names, Comparator.reverseOrder());
System.out.println("Sorted (Reverse Order): " + names);
// 3. Sorting with Stream API
List<String> sortedByLength = names.stream()
.sorted(Comparator.comparingInt(String::length))
.collect(Collectors.toList());
System.out.println("Sorted (By Length): " + sortedByLength);
List<Integer> numbers = new ArrayList<>();
numbers.add(5);
numbers.add(1);
numbers.add(8);
numbers.add(3);
System.out.println("\nOriginal Numbers: " + numbers);
Collections.sort(numbers);
System.out.println("Sorted Numbers: " + numbers);
}
}
Examples of sorting a List using Collections.sort() and Stream API.
Comparator.comparing() and thenComparing() are powerful tools for creating chained comparison logic, making your code more readable and robust.Sorting Java Maps
Unlike Lists, Maps are inherently unordered collections (with the exception of LinkedHashMap which preserves insertion order, and TreeMap which sorts by keys). To 'sort' a Map, you typically need to either obtain a sorted view of its entries or create a new Map (like a TreeMap or LinkedHashMap) with the desired order. Sorting can be done based on keys or values.
flowchart TD
A[Original Map] --> B{Sort by Keys?}
B -- Yes --> C[Use TreeMap]
B -- No --> D{Sort by Values?}
D -- Yes --> E[Extract Entries]
E --> F[Sort List of Entries]
F --> G[Create New LinkedHashMap]
C --> H[Sorted Map]
G --> H[Sorted Map]Decision flow for sorting Java Maps based on keys or values.
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class MapSorting {
public static void main(String[] args) {
Map<String, Integer> fruitCounts = new HashMap<>();
fruitCounts.put("Apple", 3);
fruitCounts.put("Banana", 1);
fruitCounts.put("Orange", 5);
fruitCounts.put("Grape", 2);
System.out.println("Original Map: " + fruitCounts);
// 1. Sort Map by Keys (Natural Order) - using TreeMap
Map<String, Integer> sortedByKey = new java.util.TreeMap<>(fruitCounts);
System.out.println("Sorted by Key (TreeMap): " + sortedByKey);
// 2. Sort Map by Keys (Custom Order) - using Stream API and LinkedHashMap
Map<String, Integer> sortedByKeyCustom = fruitCounts.entrySet().stream()
.sorted(Map.Entry.comparingByKey(Comparator.reverseOrder()))
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(oldValue, newValue) -> oldValue, // Merge function for duplicate keys (not expected here)
LinkedHashMap::new // Ensure insertion order is preserved
));
System.out.println("Sorted by Key (Reverse, LinkedHashMap): " + sortedByKeyCustom);
// 3. Sort Map by Values (Custom Order) - using Stream API and LinkedHashMap
Map<String, Integer> sortedByValue = fruitCounts.entrySet().stream()
.sorted(Map.Entry.comparingByValue())
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(oldValue, newValue) -> oldValue,
LinkedHashMap::new
));
System.out.println("Sorted by Value (Ascending, LinkedHashMap): " + sortedByValue);
// 4. Sort Map by Values (Descending) and then by Key (Ascending) for ties
Map<String, Integer> sortedByValueThenKey = fruitCounts.entrySet().stream()
.sorted(Map.Entry.<String, Integer>comparingByValue(Comparator.reverseOrder())
.thenComparing(Map.Entry.comparingByKey()))
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(oldValue, newValue) -> oldValue,
LinkedHashMap::new
));
System.out.println("Sorted by Value (Desc) then Key (Asc): " + sortedByValueThenKey);
}
}
Examples of sorting a Map by keys and values using TreeMap and Stream API with LinkedHashMap.
Map by values, you are essentially sorting its entrySet() and then collecting the sorted entries into a new LinkedHashMap to maintain the order. A HashMap itself will not preserve any sorting order.Choosing the Right Approach
The best method for sorting depends on your specific requirements:
For
Lists:Collections.sort(): Simple for natural order or a singleComparator.- Stream API's
sorted(): More flexible for chaining comparators and collecting into a new list without modifying the original.
For
Maps:TreeMap: If you need a map that is always sorted by its keys, and you don't need to sort by values.- Stream API with
LinkedHashMap: When you need to sort by values, or by keys with custom logic, and want to preserve that order in a new map. This is the most flexible approach for complex sorting criteria.
Remember that sorting a Map by values always results in a new Map (typically a LinkedHashMap) because HashMap and TreeMap do not support value-based ordering directly.