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

  1. Use Comparator.comparingInt() for clean, readable sorting when dealing with objects.
  2. Use lambdas when working with primitive arrays or quick-and-dirty code.
  3. Always use .reversed() when sorting in descending order.
  4. 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

\