[英]Can someone explain PriorityQueue in this example to me?
我正在嘗試學習如何使用PriorityQueue,因為我以前從未使用過。 這是我在LeetCode上發現的一個正在使用的示例,該問題在字符串數組中找到前K個元素
public List<String> topKFrequent(String[] words, int k) {
Map<String, Integer> count = new HashMap();
for (String word: words) {
count.put(word, count.getOrDefault(word, 0) + 1);
}
PriorityQueue<String> heap = new PriorityQueue<String>(
(w1, w2) -> count.get(w1).equals(count.get(w2)) ?
w2.compareTo(w1) : count.get(w1) - count.get(w2) );
for (String word: count.keySet()) {
heap.offer(word);
if (heap.size() > k) heap.poll();
}
List<String> ans = new ArrayList();
while (!heap.isEmpty()) ans.add(heap.poll());
Collections.reverse(ans);
return ans;
}
更值得注意的是,我想知道這一行在做什么:
PriorityQueue<String> heap = new PriorityQueue<String>(
(w1, w2) -> count.get(w1).equals(count.get(w2)) ?
w2.compareTo(w1) : count.get(w1) - count.get(w2) );
有人可以用la腳的方式解釋這里發生了什么嗎? 有什么方法可以將比較器重寫為常規的“ if”語句?
謝謝你的幫助。
您使用的PriorityQueue
構造函數聲明為:
public PriorityQueue(Comparator<? super E> comparator)
它采用通用類型參數的對象的比較器。 comparator
構造函數參數描述為:
用於排序此優先級隊列的比較器。 如果為null,則將使用元素的自然順序。
在您的調用中,參數是一個lambda表達式 ,提供了Comparator<String>
。 它大致等效於以下匿名類:
PriorityQueue<String> heap2 = new PriorityQueue<String>(new Comparator<String>() {
@Override
public int compare(String w1, String w2) {
if(count.get(w1).equals(count.get(w2))) {
return w2.compareTo(w1);
} else {
return count.get(w1) - count.get(w2);
}
// can also just be (without the if/else above):
//return count.get(w1).equals(count.get(w2)) ? w2.compareTo(w1) : count.get(w1) - count.get(w2);
}
});
構造函數中的表達式是lambda表達式 。 因為Comparator
是一個功能接口,也就是說,它是只有一個抽象方法的接口,所以可以使用lambda表達式作為創建匿名類的簡寫。
在您的示例中
new PriorityQueue<String>((w1, w2) -> count.get(w1).equals(count.get(w2)) ? w2.compareTo(w1) : count.get(w1) - count.get(w2));
在功能上等同於
new PriorityQueue<String>(new Comparator<String>() {
public int compare(String w1, String w2) {
return count.get(w1).equals(count.get(w2)) ? w2.compareTo(w1) : count.get(w1) - count.get(w2);
}
});
這也與創建實現Comparator<String>
的單獨類,並將該類的實例作為參數傳遞給PriorityQueue
。
至於將Comparator
編寫為if語句,簡短的答案是:不會。 比較器必須是Comparator<String>
的實例。 但是,相同比較器的一個更易於理解的版本如下:
new PriorityQueue<String>((w1, w2) -> {
if (count.get(w1).equals(count.get(w2))) { // If the counts of w1 and w2 are the same,
return w2.compareTo(w1); // Then return the reverse lexicographical ordering of w1 and w2 (e.g. "Zebra" comes before "Apple")
} else if (count.get(w1) < count.get(w2)) {
return -1; // w1 comes before w2
} else {
return 1; // w1 comes after w2
}
});
注意:“詞法排序”本質上是字母順序,但是基於ASCII碼。 有關更多信息,請參見String#compareTo(String)
希望這可以幫助!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.