[英]List.sort with two fields
我在 leetcode 討論部分看到了這段代碼,但我無法理解它。 請在這里幫忙。
HashMap<Character,Integer> map = new HashMap<>();
for(char ch: s.toCharArray()){
map.put(ch,map.getOrDefault(ch,0)+1);
}
List<Character> list = new ArrayList<>(map.keySet());//convert hashmap keys into list
list.sort((x,y) -> map.get(y) - map.get(x));
我無法理解以下行的含義。
list.sort((x,y) -> map.get(y) - map.get(x));
這條短線實際上發生了令人驚訝的事情: list.sort((x,y) -> map.get(y) - map.get(x));
.
List.sort( Comparator comparator )
List.sort
方法將Comparator
object 作為參數。
@FunctionalInterface
如果您查看Comparator
接口,您會看到它由@FunctionalInterface
注釋。 引用 Javadoc,“從概念上講,函數式接口只有一個抽象方法。”。
這段代碼:
(x,y) -> map.get(y) - map.get(x)
... 是 lambda 語法,充當該單一抽象方法的實現。
編譯器可以推斷出這個實現的方法是Comparator
的compare
方法,這是Comparator
上唯一的抽象方法。
Comparator#compare
Comparator#compare
方法返回一個int
integer 數字。 引用 Javadoc:返回的數字表示“負 integer、零或正 integer,因為第一個參數小於、等於或大於第二個。”。
HashMap
中的鍵值對的值側的類型為Integer
class。 因此,僅從另一個值中減去一個值Integer
object 是一種看似聰明的方法來確定要由compare
數返回的 integer 數。
但是, 如下所述,這種方法在數學上存在缺陷。 ⚠️
減法可能導致integer 溢出。 最好將比較工作委托給Integer
class: Integer.compare
中的方法。
( x , y ) -> Integer.compare( x , y )
如果對該方法的實現感到好奇,請查看OpenJDK 項目上的開源代碼。 摘抄:
public static int compare(int x, int y) {
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
另一種方法是使用由 static Comparator.comparingInt
方法返回的Comparator
器 object。
[警告:我還沒有測試過這段代碼。]
list.sort( Comparator.comparingInt( list :: get ) )
那個list:: get
部分是一個方法引用。
此外, map.get(y) - map.get(x)
部分調用auto-boxing 。
每個get
調用都會返回一個 object,類型為Integer
class。 使用減號-
Integer
對象直接沒有意義; 不能減去對象。 但是,編譯器足夠聰明,可以識別Integer
object 可以轉換為int
原語。 並且可以減去兩個int
基元。
您可以使用 Go 在 IDE 中聲明。 (例如 Intellij 中的 Ctrl + B )並查看方法:
sort(Comparator<? super E> c)
所以沒有 2 個字段,只有一個,一個比較器,如上一個答案中所述。
如果您將其提取為變量(Intellij 中的 Ctrl + Alt + V),也許它會幫助您閱讀清楚。
Comparator<Character> characterComparator = (x, y) -> map.get(y) - map.get(x);
同樣在這種情況下,它可以簡化為:
Comparator.comparingInt(map::get)
所以排序是:
list.sort(Comparator.comparingInt(map::get));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.