Pages

Thursday, December 9, 2021

Java Arrays Sort Comparator

1. Overview

In this tutorial, we'll learn how to sort arrays in java with the comparator.

Comparator is used to write the custom sorting with the Collections or over Arrays.

If you are new arrays, read articles on Arrays.



At the end of the article, we have given the GitHub link where you can see all code at once and you can run the programs along with me.

It is easy to sort the arrays when the array is single-dimensional. Use Arrays.sort() method.

But if you have the user defined objects or two dimensional arrays then it is not possible to sort by using just the Arrays sort() method.

In this case, we need to use the Comparator interface to provide the custom logic for it.

First, we will start with the custom objects and then next show the two or more dimensional arrays.

You will see the different ways to create the comparator in jdk8, java 7 and before versions. All will produce the same output.

Java Arrays Sort Comparator



2. Java Arrays Sort of Custom Objects without Comparator


First created an array of Employee objects. Employee class has fields id, name and age.

Next, added 5 employee objects and then called Arrays.sort() method.

Observe the code that we did not use any comparator and just called sort() method. Here sort() method does not know sorting based on which property of Employee class.

Look at the output, it is thrown as an exception at the runtime saying "java.lang.ClassCastException".


Example 1
package com.javaprogramto.arrays.comparator;

import java.util.Arrays;

import com.javaprogramto.models.Employee;

public class ArraysSortComparatorExample {

	public static void main(String[] args) {

		Employee[] empArray = new Employee[5];

		empArray[0] = new Employee(100, "Malik Mona", 30);
		empArray[1] = new Employee(105, "A Z", 35);
		empArray[2] = new Employee(102, "B Z", 33);
		empArray[3] = new Employee(103, "C Z", 31);
		empArray[4] = new Employee(104, "D Z", 34);

		System.out.println("emp array before sort - ");
		Arrays.stream(empArray).forEach(emp -> System.out.println(emp));

		Arrays.sort(empArray);

		System.out.println("emp array after sort - ");
		Arrays.stream(empArray).forEach(emp -> System.out.println(emp));

	}

}

Output
emp array before sort - 
Employee{id=100, fullName='Malik Mona', age=30}
Employee{id=105, fullName='A Z', age=35}
Employee{id=102, fullName='B Z', age=33}
Employee{id=103, fullName='C Z', age=31}
Employee{id=104, fullName='D Z', age=34}
Exception in thread "main" java.lang.ClassCastException: class com.javaprogramto.models.Employee cannot be cast to class java.lang.Comparable (com.javaprogramto.models.Employee is in unnamed module of loader 'app'; java.lang.Comparable is in module java.base of loader 'bootstrap')
	at java.base/java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:320)
	at java.base/java.util.ComparableTimSort.sort(ComparableTimSort.java:188)
	at java.base/java.util.Arrays.sort(Arrays.java:1040)
	at com.javaprogramto.arrays.comparator.ArraysSortComparatorExample.main(ArraysSortComparatorExample.java:22)


3. Java Arrays Sort of Custom Objects With Custom Comparator


Next, let us add the custom comparator to the sort() method as below and observe the output.

Within the comparator logic, we provided the employee class field to be used for soring.

let us use the java 8 comparator comparing() method to create the custom comparator.


Example 2
package com.javaprogramto.arrays.comparator;

import java.util.Arrays;
import java.util.Comparator;

import com.javaprogramto.models.Employee;

public class ArraysSortCustomComparatorExample {

	public static void main(String[] args) {

		Employee[] empArray = new Employee[5];

		empArray[0] = new Employee(100, "Malik Mona", 30);
		empArray[1] = new Employee(105, "A Z", 35);
		empArray[2] = new Employee(102, "B Z", 33);
		empArray[3] = new Employee(103, "C Z", 31);
		empArray[4] = new Employee(104, "D Z", 34);

		System.out.println("emp array before sort - ");
		Arrays.stream(empArray).forEach(emp -> System.out.println(emp));

		Comparator<Employee> sortById = Comparator.comparing(Employee::getId);

		Arrays.sort(empArray, sortById);

		System.out.println("\nemp array after sort - ");
		Arrays.stream(empArray).forEach(emp -> System.out.println(emp));
	}
}

Output
emp array before sort - 
Employee{id=100, fullName='Malik Mona', age=30}
Employee{id=105, fullName='A Z', age=35}
Employee{id=102, fullName='B Z', age=33}
Employee{id=103, fullName='C Z', age=31}
Employee{id=104, fullName='D Z', age=34}

emp array after sort - 
Employee{id=100, fullName='Malik Mona', age=30}
Employee{id=102, fullName='B Z', age=33}
Employee{id=103, fullName='C Z', age=31}
Employee{id=104, fullName='D Z', age=34}
Employee{id=105, fullName='A Z', age=35}

From the above output, we could see clearly no errors at runtime and the employee array is now sorted by its id.

3. Java Multi Dimensional Arrays Sort With Comparator



Next, create the comparator instance with comparing() method and then call Arrays.sort() method.

Example 3

From the below input, we need to sort the array by its first values in increasing order.

package com.javaprogramto.arrays.comparator;

import java.util.Arrays;
import java.util.Comparator;

public class ArraysSortCustomComparatorExample3 {

	public static void main(String[] args) {

		int[][] array = { { 1, 2 }, { 7, 8 }, { 3, 4 }, { 9, 0 }, { 5, 6 } };

		System.out.println("emp array before sort - ");
		System.out.println(Arrays.deepToString(array));

		Comparator<? super int[]> sortByFirstNumber = Comparator.comparing(innerArray -> innerArray[0]);

		Arrays.sort(array, sortByFirstNumber);

		System.out.println("\nemp array after sort - ");
		System.out.println(Arrays.deepToString(array));
	}
}

Output
emp array before sort - 
[[1, 2], [7, 8], [3, 4], [9, 0], [5, 6]]

emp array after sort - 
[[1, 2], [3, 4], [5, 6], [7, 8], [9, 0]]

From the above output, we can see that array is sorted by its first values from inner arrays in ascending order.

if you want to do in reverse order then we need to just reverse comparator using reversed() method.

Here, we can use the existing comparator object and on top of that just call reversed() method which does the reverse of the current comparator logic.

Example 4
Comparator<? super int[]> sortByFirstNumberAscending = Comparator.comparing(innerArray -> innerArray[0]);

Comparator<? super int[]> sortByFirstNumberDescending  = sortByIdAscending.reversed();

Arrays.sort(array, sortByFirstNumberDescending);

System.out.println("\nemp array after sort descending - ");
System.out.println(Arrays.deepToString(array));

Output
emp array after sort descending - 
[[9, 0], [7, 8], [5, 6], [3, 4], [1, 2]]


4. Java Arrays Sort Comparator in Jdk 7 and before versions


How custom comparators instances are created in java 7 and older versions.

Example 5

The below code is based on java 7 version.
package com.javaprogramto.arrays.comparator;

import java.util.Arrays;
import java.util.Comparator;

public class ArraysSortCustomComparatorExample4 {

	public static void main(String[] args) {

		int[][] array = { { 1, 2 }, { 7, 8 }, { 3, 4 }, { 9, 0 }, { 5, 6 } };

		// java 7
		System.out.println("emp array before sort - ");
		System.out.println(Arrays.deepToString(array));

		Comparator<? super int[]> sortByFirstValue = new Comparator<int[]>() {
			@Override
			public int compare(int[] i1, int[] i2) {
				return Integer.compare(i1[0], i2[0]);
			}
		};

		Arrays.sort(array, sortByFirstValue);

		System.out.println("\nemp array after sort - ");
		System.out.println(Arrays.deepToString(array));

	}
}


Example 6

 The below code works on the below java 7 versions.
Comparator<? super int[]> sortByFirstValue = new Comparator<int[]>() {
	@Override
	public int compare(int[] i1, int[] i2) {
		return ((Integer) i1[0]).compareTo(i2[0]);
	}
};

The above 2 programs produce the same output which is sorted by the first value from the nested array in increasing order.

emp array before sort - 
[[1, 2], [7, 8], [3, 4], [9, 0], [5, 6]]

emp array after sort - 
[[1, 2], [3, 4], [5, 6], [7, 8], [9, 0]]


5. Conclusion


In this article, we've seen how to add the custom comparator to an array in java when working with the user defined objects or muti dimensional arrays.






No comments:

Post a Comment

Please do not add any spam links in the comments section.