Whether you're using arrays, lists, priority queues, or maps — sorting pairs (or objects with multiple fields) is a common task in Java. This guide will walk you through the best ways to do it, using:
- ✅ Arrays
- ✅ Lists (
ArrayList
) - ✅ PriorityQueue
- ✅ TreeMap / TreeSet
- ✅ Custom Objects
- ✅ Java 8+ functional comparators
🔹 1. Arrays of Primitive Arrays (int[][]
)
✅ Use Case:
Fastest to use in algorithm problems (e.g. LeetCode), with low overhead.
▶️ Sort by second element (ascending):
int[][] arr = { {1, 5}, {2, 3}, {3, 8}, {4, 1} };
Arrays.sort(arr, (a, b) -> Integer.compare(a[1], b[1]));
▶️ Sort by second element (descending):
Arrays.sort(arr, (a, b) -> Integer.compare(b[1], a[1]));
❌ You cannot use Comparator.comparingInt()
here because int[]
is not an object with named fields.
🔹 2. List of Arrays (List
)
Same as arrays but with Collections.sort
.
▶️ Sort by second element ascending:
List<int[]> list = new ArrayList<>();
list.add(new int[]{1, 5});
list.add(new int[]{2, 3});
Collections.sort(list, (a, b) -> Integer.compare(a[1], b[1]));
🔹 3. List of Custom Objects
Define a Pair
or any domain object with named fields.
▶️ Pair class:
class Pair {
int first, second;
Pair(int f, int s) { first = f; second = s; }
}
▶️ Ascending sort by second
:
List<Pair> list = new ArrayList<>();
list.add(new Pair(1, 5));
list.add(new Pair(2, 3));
list.sort(Comparator.comparingInt(p -> p.second));
▶️ Descending sort:
list.sort(Comparator.comparingInt((Pair p) -> p.second).reversed());
✅ Clean and readable — use this for production-quality code.
🔹 4. PriorityQueue
of Pairs
▶️ With arrays:
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> Integer.compare(a[1], b[1]));
▶️ With objects:
PriorityQueue<Pair> pq = new PriorityQueue<>(Comparator.comparingInt(p -> p.second));
🔹 5. Map.Entry
(like HashMap
or TreeMap
)
✅ Use Case:
When you want to sort a map by value or keys, use Map.Entry
.
▶️ Sort map by value ascending:
Map<String, Integer> map = new HashMap<>();
map.put("a", 3); map.put("b", 1);
List<Map.Entry<String, Integer>> entries = new ArrayList<>(map.entrySet());
entries.sort(Comparator.comparingInt(Map.Entry::getValue));
▶️ Descending:
entries.sort(Comparator.comparingInt(Map.Entry::getValue).reversed());
🔹 6. TreeMap
and TreeSet
Custom Sorting
✅ Use Case:
To maintain a continuously sorted collection.
▶️ TreeMap sorted by custom comparator on keys:
TreeMap<Integer, String> tree = new TreeMap<>(Comparator.reverseOrder());
▶️ TreeSet with custom objects:
TreeSet<Pair> set = new TreeSet<>(Comparator.comparingInt(p -> p.second));
⚠️ Note: TreeSet
requires consistent equals()
and compareTo()
logic to avoid silent rejection of duplicates.
✅ Summary of Comparator Options
Collection Type | Use Lambda |
comparingInt Works |
Needs Custom Class | Reverse Order |
---|---|---|---|---|
int[][] / List
|
✅ Yes | ❌ No | ❌ No | ✅ Yes (manually) |
List |
✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes |
PriorityQueue |
✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes |
Map.Entry |
✅ Yes | ✅ Yes | ❌ No | ✅ Yes |
TreeSet , TreeMap
|
✅ Yes | ✅ Yes | ✅ Recommended | ✅ Yes |
🚀 Pro Tips
-
Use
Comparator.comparingInt()
for clean, readable sorting when dealing with objects. - Use lambdas when working with primitive arrays or quick-and-dirty code.
- Always use
.reversed()
when sorting in descending order. - For multiple sort keys (e.g., by value then key), use
thenComparing()
:
list.sort(Comparator.comparingInt((Pair p) -> p.second)
.thenComparingInt(p -> p.first));
🧾 Closing Thoughts
Sorting in Java is a versatile tool — once you understand how to use Comparator
, comparingInt
, and method references effectively, your code becomes cleaner, safer, and easier to maintain.
Choose the right strategy based on:
- Your data structure (array, list, map)
- Whether you need ascending/descending
- Whether your data has named fields
\