Java Comparator Class to Sort Arrays

Java Comparator class to sort arrays

[...] How should Java Comparator class be declared to sort the arrays by their first elements in decreasing order [...]

Here's a complete example using Java 8:

import java.util.*;

public class Test {

public static void main(String args[]) {

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

Arrays.sort(twoDim, Comparator.comparingInt(a -> a[0])
.reversed());

System.out.println(Arrays.deepToString(twoDim));
}
}

Output:

[[8, 9], [5, 3], [4, 2], [3, 7], [1, 2]]

For Java 7 you can do:

Arrays.sort(twoDim, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return Integer.compare(o2[0], o1[0]);
}
});

If you unfortunate enough to work on Java 6 or older, you'd do:

Arrays.sort(twoDim, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return ((Integer) o2[0]).compareTo(o1[0]);
}
});

Arrays.sort() is not accepting the comparator type object

Signature of method is: public static <T> void sort(T[] a, Comparator<? super T> c) so the first argument is generic and you cannot put there primitive type that's why you get an error. For such sorting you have predefined sort method which can take primitive arrays

How to use Java Comparator to sort an array of arrays?

Descending:

Arrays.sort(arr, (o1, o2) -> Math.abs(o2[0] - o2[1]) - Math.abs(o1[0] - o1[1]));

Ascending:

Arrays.sort(arr, Comparator.comparingInt(o -> Math.abs(o[0] - o[1])));

How to sort an array of ints using a custom comparator?

If you can't change the type of your input array the following will work:

final int[] data = new int[] { 5, 4, 2, 1, 3 };
final Integer[] sorted = ArrayUtils.toObject(data);
Arrays.sort(sorted, new Comparator<Integer>() {
public int compare(Integer o1, Integer o2) {
// Intentional: Reverse order for this demo
return o2.compareTo(o1);
}
});
System.arraycopy(ArrayUtils.toPrimitive(sorted), 0, data, 0, sorted.length);

This uses ArrayUtils from the commons-lang project to easily convert between int[] and Integer[], creates a copy of the array, does the sort, and then copies the sorted data over the original.

Java Comparator Arrays.sort()

Comparator.comparing is implemented as follows:

public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
Function<? super T, ? extends U> keyExtractor)
{
Objects.requireNonNull(keyExtractor);
return (Comparator<T> & Serializable)
(c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}

i.e. it uses the Function you pass to it in order to transform each of the compared elements into a Comparable, and then uses the Comparable's compareTo method.

When you are passing the function p -> p[0]*p[0] + p[1]*p[1], you are converting each point to its sum of squares. Then, when the Comparator needs to compare two points, it compares the sum of squares of the two points, which is almost equivalent to computing the difference of the sums of squares of the two points (it's not exactly equivalent, since comparing two numbers by computing their difference can produce wrong output in case of numeric overflow).

That's exactly what your second Comparator - (p1, p2) -> p1[0]*p1[0] + p1[1]*p1[1] - p2[0]*p2[0] - p2[1]*p2[1] - does,

since p1[0]*p1[0] + p1[1]*p1[1] - p2[0]*p2[0] - p2[1]*p2[1] ==
(p1[0]*p1[0] + p1[1]*p1[1]) - (p2[0]*p2[0] + p2[1]*p2[1])
.

Using Comparator.comparing() is safer, since it compares the sums of squares of the two points without computing their difference. It uses Double's compareTo() instead (assuming the coordinates of your points are Double or double).

In other words, the first alternative uses a Function that needs just one point since this function tells Comprator.comparing how to transform each of the 2 points.

On the other hand, the second alternative accepts 2 points (which are the required arguments of the Comparator.compare() method) and determines the relative order of these 2 points.

Array Sorting Using A Comparator in Java

I just put together this simple example to show two different ways of using a Comparator:

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

public class ArraySort
{
public static void main(String[] args)
{
String[][] data = new String[][]
{
new String[] { "Casablanca", "Warner Brothers", "1942" },
new String[] { "Citizen Kane", "RKO Pictures", "1941" },
new String[] { "Singin' in the Rain", "MGM", "1952" },
new String[] { "The Wizard of OZ", "MGM", "1930"},
new String[] { "AaaaaThe Wizard of OZ", "MGM", "1943"}
};

Arrays.sort(data, new Comparator<String[]>() {

@Override
public int compare(final String[] entry1, final String[] entry2) {
final String field1 = entry1[0];
final String field2 = entry2[0];
return field1.compareTo(field2);
}
});

print(data);

System.out.println();

Arrays.sort(data, new SortByDate());

print(data);

System.out.println();

Arrays.sort(data, new SortByCompany());

print(data);
}

public static void print(String[][] data){
for (String[] array : data){
for (String s : array){
System.out.print(s + " ");
}
System.out.println();
}
}

}

public class SortByDate implements Comparator<String[]>{
@Override
public int compare(final String[] entry1, final String[] entry2) {
final String field1 = entry1[2];
final String field2 = entry2[2];
return field1.compareTo(field2);
}
}

public class SortByCompany implements Comparator<String[]>{
@Override
public int compare(final String[] entry1, final String[] entry2) {
final String field1 = entry1[1];
final String field2 = entry2[1];
return field1.compareTo(field2);
}
}

Output:

AaaaaThe Wizard of OZ MGM 1943 
Casablanca Warner Brothers 1942
Citizen Kane RKO Pictures 1941
Singin' in the Rain MGM 1952
The Wizard of OZ MGM 1930

The Wizard of OZ MGM 1930
Citizen Kane RKO Pictures 1941
Casablanca Warner Brothers 1942
AaaaaThe Wizard of OZ MGM 1943
Singin' in the Rain MGM 1952

The Wizard of OZ MGM 1930
AaaaaThe Wizard of OZ MGM 1943
Singin' in the Rain MGM 1952
Citizen Kane RKO Pictures 1941
Casablanca Warner Brothers 1942

How to use a separate comparator class to sort an array list

I would use

Collections.sort(list, RationalComparator.INSTANCE);

where the comparator looks like

enum RationalComparator implements Comparator<Rational> {
INSTANCE;

public int compare(Rational a, Rational b) {
// do your comparison here
}
}

java Arrays.sort 2d array

Use Overloaded Arrays#Sort(T[] a, Comparator c) which takes Comparator as the second argument.

double[][] array= {
{1, 5},
{13, 1.55},
{12, 100.6},
{12.1, .85} };

java.util.Arrays.sort(array, new java.util.Comparator<double[]>() {
public int compare(double[] a, double[] b) {
return Double.compare(a[0], b[0]);
}
});

JAVA-8: Instead of that big comparator, we can use lambda function as following-

Arrays.sort(array, Comparator.comparingDouble(o -> o[0]));

Java Comparator class to sort particular object array

ResultVoiceObject[] objects = ...
Arrays.sort(objects, new Comparator<ResultVoiceObject>() {

@Override
public int compare(ResultVoiceObject arg0, ResultVoiceObject arg1) {
return Float.compare(arg0.getRanking(), arg1.getRanking());
}

});


Related Topics



Leave a reply



Submit