In this article, we will examine different ways to write Comparators in java to sort the multidimensional arrays. Comparator is a functional interface in java.
java.util.Arrays class contains various utility methods to manipulate arrays one of the important methods is Sort. This method takes two parameters the array that needs to be sorted and the optional Comparator. If we don't pass the Comparator then the array will be sorted based on the natural ordering of the elements.

Sorting Array

Our Array
Let's say we want to represent multiple points with x,y coordinates in an array. The following represents one such example.
{ { 20, 25 },{ 10, 15 }, { 10, 25 }, { 20, 15 }}
We want to sort the array based on x and y-axis values.

Comparators

Comparator Implementation as a Class
Here we are implementing a Comparator called MultiDimArrayComparator and then we can use this comparator to sort Array
class MultiDimArrayComparator implements Comparator {
	@Override
	public int compare(int[] m, int[] n) {
		return m[0] == n[0] ? m[1] - n[1] : m[0] - n[0];
	}
}

Arrays.sort(arr, new MultiDimArrayComparator());
Comparator as an anonymous class
Here we are implementing Comparator as an anonymous class and providing a definition of compare method.
Arrays.sort(arr, new Comparator() {
	@Override
	public int compare(int[] m, int[] n) {
		return m[0] == n[0] ? m[1] - n[1] : m[0] - n[0];
	}
});
Comparator as lambda expression (Java 8+)
Here we are implementing Comparator as a lambda function.
Arrays.sort(arr, (m, n) -> m[0] == n[0] ? m[1] - n[1] : m[0] - n[0]);

Full Example


public class ArraysSort {

	public static void main(String[] args) {
		int arr[][] = { { 20, 25 },{ 10, 15 }, { 10, 25 }, { 20, 15 }};

		int arr1[][] = arr;
		
		Arrays.sort(arr1, new MultiDimArrayComparator());
		System.out.println("Sorted Result");
		for (int[] x : arr1) {
			System.out.println(x[0] + " " + x[1]);
		}
		
		arr1 = arr;
		Arrays.sort(arr1, new Comparator<int[]>() {
			@Override
			public int compare(int[] m, int[] n) {
				return m[0] == n[0] ? m[1] - n[1] : m[0] - n[0];
			}
		});
		System.out.println("Sorted Result");
		for (int[] x : arr1) {
			System.out.println(x[0] + " " + x[1]);
		}

		arr1 = arr;
		Arrays.sort(arr1, (m, n) -> m[0] == n[0] ? m[1] - n[1] : m[0] - n[0]);
		System.out.println("Sorted Result");
		for (int[] x : arr1) {
			System.out.println(x[0] + " " + x[1]);
		}
	}

}

class MultiDimArrayComparator implements Comparator<int[]> {
	@Override
	public int compare(int[] m, int[] n) {
		return m[0] == n[0] ? m[1] - n[1] : m[0] - n[0];
	}
}

Running the code

Sorted Result 10 15 10 25 20 15 20 25 Sorted Result 10 15 10 25 20 15 20 25 Sorted Result 10 15 10 25 20 15 20 25

Conclusion

Here we implemented the same Comparator to sort two-dimensional arrays in three different styles.

How to use custom comparator for TreeMap

This article covers some of the aspects of sorting Map in Java. Java Map comes in different flavors, like HashMap, TreeMap, LinkedHashMap etc. TreeMap for instance will sort the data based on the keys. We can also pass a custom Comparator to sort based on the keys as per the custom sort algorithm.
TreeMap sorts based on natural ordering of the keys if no custom Comparator is provided. To use a custom Comparator we need to pass the Comparator in the TreeMap Constructor.

Simple TreeMap

TreeMap without any Comparator
Following code creates a TreeMap and adds some data to it. After that we print the TreeMap. As No comparator is specified, the data is sorted by natural ordering of the keys.
TreeMap map = new TreeMap();
    map.put(1, "A");
    map.put(3, "C");
    map.put(2, "B");
    map.put(4, "D");
    map.put(5, "E");


    System.out.println("\nPrint Map ");
    map.forEach((a, b) -> {
      printKeyVal(a,b);
    });;
Print Map Key: 1 Value: A Key: 2 Value: B Key: 3 Value: C Key: 4 Value: D Key: 5 Value: E

TreeMap with Comparator

TreeMap with reverse order Comparator
In this case we are passing a built in Comparator to sort the keys reversely. From the result we can see that the data is sorted in reverse order of the keys.
System.out.println("\nPrint Map with Reverse Comparator");
TreeMap map2 = new TreeMap(Collections.reverseOrder());
    map2.putAll(map);
    map2.forEach((a, b) -> {
      printKeyVal(a, b);
 });
Print Map with Reverse Comparator Key: 5 Value: E Key: 4 Value: D Key: 3 Value: C Key: 2 Value: B Key: 1 Value: A

Custom Comparator

Following examples shows implementation of two custom Comparator, one with inner class second one with java 8 Lambda. Both the Comparator works exactly same, that is it sorts the data in reverse order.
With Inner Classes
Custom Comparator with Inner Class to sort the keys in reverse order.
Comparator orderByKeyDesc = new Comparator() {
@Override
 public int compare(Integer o1, Integer o2) {
        return o2.compareTo(o1);
      }
};
Lambda Comparator.
Java 8 Lambda to implement Comparator
Comparator orderByKeyDesc2 = (Integer o1, Integer o2) -> o2.compareTo(o1);

Full Example

TreeMapCustomComparator
Full example with Custom Comparator that is passed to the TreeMap.
public class TreeMapCustomComparator {

  public static void main(String[] args) {

    TreeMap map = new TreeMap();
    map.put(1, "A");
    map.put(3, "C");
    map.put(2, "B");
    map.put(4, "D");
    map.put(5, "E");


    System.out.println("\nPrint Map ");
    map.forEach((a, b) -> {
      printKeyVal(a, b);
    });;

   
    System.out.println("\nPrint Map with Reverse Comparator");
    TreeMap map2 = new TreeMap(Collections.reverseOrder());
    map2.putAll(map);
    map2.forEach((a, b) -> {
      printKeyVal(a, b);
    });


    //Custom Comparator with Inner Class
    Comparator orderByKeyDesc = new Comparator() {
      @Override
      public int compare(Integer o1, Integer o2) {
        return o2.compareTo(o1);
      }
    };

    //Custom Comparator with Lambda
    Comparator orderByKeyDesc2 = (Integer o1, Integer o2) -> o2.compareTo(o1);

    System.out.println("\nPrint Map with Custom Reverse Comparator Java Lambda");
    TreeMap map3 = new TreeMap(orderByKeyDesc2);
    map3.putAll(map);

    map3.forEach((a, b) -> {
      printKeyVal(a, b);
    });

  }

  /* Utility method to print key value pairs nicely */
  private static void printKeyVal(Object a, Object b) {
    System.out.print("Key: " + a + "  Value: " + b + "     ");
  }


}
Print Map Key: 1 Value: A Key: 2 Value: B Key: 3 Value: C Key: 4 Value: D Key: 5 Value: E Print Map with Reverse Comparator Key: 5 Value: E Key: 4 Value: D Key: 3 Value: C Key: 2 Value: B Key: 1 Value: A Print Map with Custom Reverse Comparator Java Lambda Key: 5 Value: E Key: 4 Value: D Key: 3 Value: C Key: 2 Value: B Key: 1 Value: A