I am using below code to sort a 2D array by column, it is taking a lambda expression in the second parameter. I don't quite understand how (a,b) is defined and how a[0] and b[0] is working in the comparator. This code is sorting correctly, but I want to understand the syntax. Thanks.
Arrays.sort(myArray, (a, b) -> Integer.compare(a[0], b[0]))
2D array by column
Java doesn't have 2D arrays. It has arrays of arrays, and some syntax sugar to let you declare an array-of-arrays and immediately initialize the outer array by creating new arrays and filling the slots.
int[][] grid = new int[10][5];
is syntax sugar for:
int[][] grid = new int[10][];
for (int i = 0; i < 10; i++) grid[i] = new int[5];
Arrays.sort(myArray, (a, b) -> Integer.compare(a[0], b[0]))
The type of myArray is int[][]
. In other words, an array of int[]
. Thus, to sort this, you need to provide an oracle: This oracle needs to be capable of giving consistent answers to the question: "Given 2 components (in this case, the component is int[]
), tell me if the first component sorts 'after' the second, or 'before' the second, or sorts equally. Do so by returning a negative number to indicate that the first is 'before', a positive number to indicate the first is 'after', and 0 to indicate they are equal or at least sort-ordering-wise at an equal level.
Ordinarily, you'd do this by creating an implementation of the Comparator<int[]>
interface, creating an instance of this, and passing it along:
class MySorter implements Comparator<int[]> {
@Override public int compare(int[] a, int[] b) {
return Integer.compare(a[0], b[0]);
}
}
MySorter mySorter = new MySorter();
Arrays.sort(myArray, mySorter);
The above code works fine - you can compile and run it.
Lambdas aren't much different from what is happening above. There is only one relevant sort
method on Arrays, and it indeed does take 2 arguments: An array of T
, and a Comparator
that can compare T
, with T being whatever you please (here, T is int[]
). So why can you pass a lambda there?
Because the compiler works outside-in. It initially just sees:
Arrays.sort(myArray, someLambdaExpressionIHaveNotLookedAtYet)
and will stop right there, and try to figure out which method is intended. It'll find that only one method 'works': public static <T> sort (T[] array, Comparator<T> comparator)
.
Only then does javac continue: First, it checks that Comparator is a so-called 'single abstract method' type (a SAM type): It is; Comparator is an interface that defines just a single method*, which means it is a SAM type, which means you can shortcut the creation of a class that implements
this interface, along with creating a new instance of this class, into a one-liner.
Now, because java already knows what the lambda is supposed to represent (namely, an implementation for Comparator<int[]>
, and it knows there is only one method that you're trying to implement (namely, public int compare(int[] a, int[] b)
), java already knows the variable types . The method you're implementing has to be int[] a, int[] b
.
That's why you don't have to specify it. You can just write (a, b)
- java fills in the int[]
for you. You CAN write it out: Give it shot, write Arrays.sort(myArray, (int[] a, int b[]) -> Integer.compare(a[0], b[0])
and you'll find it works exactly the same way.
The rest is trivial: ->
is just lambda syntax, and because you don't write a {
immediately afterwards, the single expression that follows the -> is just inserted as return value.
Thus,
(a, b) -> Integer.compare(a[0], b[0])
is 100% equivalent to:
public class A implements B {
public C {
return D;
}
}
A a = new A();
Where:
*) Methods that are already defined in java.lang.Object don't count, and methods with default impls also don't count.
Arrays.sort(T[] a, Comparator<? super T> c)
takes a Comparator<T>
as the second argument, which declares the method int compare(T o1, T o2)
.
That means the lambda expression must implement that method, and with myArray
being an Integer[][]
or int[][]
, it means that T
is an Integer[]
or int[]
, so both a
and b
are Integer[]
or int[]
.
The statement will therefore sort the 2D array by the first column.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.