[英]Can someone explain PriorityQueue in this example to me?
I am trying to learn how to use a PriorityQueue, as I have never used one before. 我正在尝试学习如何使用PriorityQueue,因为我以前从未使用过。 Here is an example of one in use that I have found on LeetCode for a problem that finds the Top K elements in an array of strings
这是我在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;
}
More notably I would like to know what this line is doing: 更值得注意的是,我想知道这一行在做什么:
PriorityQueue<String> heap = new PriorityQueue<String>(
(w1, w2) -> count.get(w1).equals(count.get(w2)) ?
w2.compareTo(w1) : count.get(w1) - count.get(w2) );
Can someone explain in lame-man's terms what is happening here? 有人可以用la脚的方式解释这里发生了什么吗? Is there any way to rewrite the comparater as a regular "if" statement?
有什么方法可以将比较器重写为常规的“ if”语句?
Thanks for any help. 谢谢你的帮助。
The PriorityQueue
constructor you're using is declared as: 您使用的
PriorityQueue
构造函数声明为:
public PriorityQueue(Comparator<? super E> comparator)
It takes a comparator of object of the generic type argument. 它采用通用类型参数的对象的比较器。 The
comparator
constructor parameter is described as: comparator
构造函数参数描述为:
the comparator that will be used to order this priority queue.
用于排序此优先级队列的比较器。 If null, the natural ordering of the elements will be used.
如果为null,则将使用元素的自然顺序。
In your call, the argument is a lambda expression that provides implements Comparator<String>
. 在您的调用中,参数是一个lambda表达式 ,提供了
Comparator<String>
。 It's roughly equivalent to the following anonymous class: 它大致等效于以下匿名类:
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);
}
});
The expression you have in the constructor is a lambda expression . 构造函数中的表达式是lambda表达式 。 Because
Comparator
is a functional interface, that is, it's an interface with only one abstract method, a lambda expression can be used as shorthand for creating an anonymous class. 因为
Comparator
是一个功能接口,也就是说,它是只有一个抽象方法的接口,所以可以使用lambda表达式作为创建匿名类的简写。
In your example, 在您的示例中
new PriorityQueue<String>((w1, w2) -> count.get(w1).equals(count.get(w2)) ? w2.compareTo(w1) : count.get(w1) - count.get(w2));
is functionally equivalent to 在功能上等同于
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);
}
});
This would also be the same as making a separate class that implements Comparator<String>
, and passing an instance of that class as the parameter to the PriorityQueue
. 这也与创建实现
Comparator<String>
的单独类,并将该类的实例作为参数传递给PriorityQueue
。
As for writing the Comparator
as an if statement, the short answer is, no. 至于将
Comparator
编写为if语句,简短的答案是:不会。 The comparator has to be an instance of Comparator<String>
. 比较器必须是
Comparator<String>
的实例。 However, perhaps a more understandable version of the same comparator is as follows: 但是,相同比较器的一个更易于理解的版本如下:
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
}
});
Note: "Lexicographical ordering" is essentially alphabetical ordering, but based on ASCII codes. 注意:“词法排序”本质上是字母顺序,但是基于ASCII码。 For more information, see
String#compareTo(String)
有关更多信息,请参见
String#compareTo(String)
Hope this helps! 希望这可以帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.