簡體   English   中英

澄清 Lambda 表達式的語法

[英]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數組和一個可以比較TComparator ,其中 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();

在哪里:

  • A = 隨機選擇的不相關名稱,
  • B = 預期的類型
  • C = B 中定義的一種方法的副本(如果沒有一種方法,則不能使用此語法),
  • D = 你在 -> 之后寫的任何內容。

*) 已在 java.lang.Object 中定義的方法不計算在內,具有默認實現的方法也不計算在內。

Arrays.sort(T[] a, Comparator<? super T> c)Comparator<T>作為第二個參數,它聲明了方法int compare(T o1, T o2)

這意味着 lambda 表達式必須實現該方法,並且myArrayInteger[][]int[][] ,這意味着TInteger[]int[] ,所以ab都是Integer[]int[]

因此,該語句將按第一列對二維數組進行排序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM