[英]Clarifying syntax on Lambda Expression
我使用下面的代碼按列對二維數組進行排序,它在第二個參數中采用 lambda 表達式。 我不太明白 (a,b) 是如何定義的,以及 a[0] 和 b[0] 如何在比較器中工作。 此代碼排序正確,但我想了解語法。 謝謝。
Arrays.sort(myArray, (a, b) -> Integer.compare(a[0], b[0]))
按列排列的二維數組
Java 沒有二維 arrays。 它具有 arrays 或 arrays 和一些語法糖,可讓您聲明一個數組數組並通過創建新的 arrays 並填充插槽來立即初始化外部數組。
int[][] grid = new int[10][5];
是語法糖:
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]))
myArray 的類型是int[][]
。 換句話說,一個int[]
數組。 因此,要對此進行排序,您需要提供 oracle:此 oracle 需要能夠對以下問題給出一致的答案:“給定 2 個組件(在這種情況下,該組件是int[]
),請告訴我第一個組件是否對第二個“之后”或第二個“之前”進行排序,或平均排序。通過返回一個負數來表示第一個是“之前”,一個正數表示第一個是“之后”,以及 0 到表明它們是相等的或至少在相同的級別上排序排序。
通常,您可以通過創建Comparator<int[]>
接口的實現、創建 this 的實例並傳遞它來做到這一點:
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);
上面的代碼工作正常——你可以編譯並運行它。
Lambda 與上面發生的事情並沒有太大的不同。 Arrays 上只有一種相關sort
方法,它確實需要 2 個 arguments:一個T
數組和一個可以比較T
的Comparator
,其中 T 是你喜歡的任何東西(這里, T 是int[]
)。 那么為什么你可以在那里傳遞一個 lambda 呢?
因為編譯器是由外而內工作的。 它最初只是看到:
Arrays.sort(myArray, someLambdaExpressionIHaveNotLookedAtYet)
並且會停在那里,並嘗試找出打算使用哪種方法。 它會發現只有一種方法“有效”: public static <T> sort (T[] array, Comparator<T> comparator)
。
只有這樣 javac 才會繼續:首先,它檢查 Comparator 是否是所謂的“單一抽象方法”類型(SAM 類型):它是; Comparator 是一個只定義一個方法*的接口*,這意味着它是一個 SAM 類型,這意味着您可以將implements
此接口的 class 的創建以及創建此 class 的新實例的快捷方式創建為單行.
現在,因為java 已經知道 lambda 應該代表什么(即Comparator<int[]>
的實現,並且它知道您嘗試實現的方法只有一種(即public int compare(int[] a, int[] b)
), java 已經知道變量類型。您要實現的方法必須是int[] a, int[] b
。
這就是您不必指定它的原因。 您可以只寫(a, b)
- java 為您填寫int[]
。 你可以寫出來:試一試,寫Arrays.sort(myArray, (int[] a, int b[]) -> Integer.compare(a[0], b[0])
你會找到它工作方式完全相同。
rest 是微不足道的: ->
只是 lambda 語法,並且因為您沒有立即編寫{
,所以 -> 后面的單個表達式只是作為返回值插入。
因此,
(a, b) -> Integer.compare(a[0], b[0])
100% 相當於:
public class A implements B {
public C {
return D;
}
}
A a = new A();
在哪里:
*) 已在 java.lang.Object 中定義的方法不計算在內,具有默認實現的方法也不計算在內。
Arrays.sort(T[] a, Comparator<? super T> c)
將Comparator<T>
作為第二個參數,它聲明了方法int compare(T o1, T o2)
。
這意味着 lambda 表達式必須實現該方法,並且myArray
是Integer[][]
或int[][]
,這意味着T
是Integer[]
或int[]
,所以a
和b
都是Integer[]
或int[]
。
因此,該語句將按第一列對二維數組進行排序。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.