Java - Prioritizing Differently with PriorityQueue
Storing Elements in Reverse Order and Sorting a HashMap using a PriorityQueue
As I continue my data structures and algorithms learning, the importance of heaps are very apparent. Heaps allow us to efficiently sort and allows us to implement a priority queue. As its name suggests, a priority acts like a regular queue, but processes elements based on priority. Creating one using its default constructor will cause it to process elements in their natural order:
PriorityQueue<Integer> pq = new PriorityQueue<>();
pq.add(5);
pq.add(3);
pq.add(7);
while(!pq.isEmpty()){
System.out.println(pq.poll());
}
In the above code, integers get returned as 3 -> 5 -> 7.
Elements can be ordered differently by passing a comparator to priority queue's constructor. For example, we can process elements in reverse order:
PriorityQueue<Integer> pq = new PriorityQueue<>(Collections.reverseOrder());
This also allows us to sort HashMap values by either key or value. The Map.Entry interface provides us with two methods that returns comparators: Map.Entry.comparingByKey() and Map.Entry.comparingByValue().
Map<String, Integer> map = new HashMap<>();
map.put("Bob", 24);
map.put("Sally", 33);
map.put("Klee", 12);
PriorityQueue<Map.Entry<String, Integer>> pq = new PriorityQueue<>(Map.Entry.comparingByKey());
for(Map.Entry<String,Integer> mapEntry : map.entrySet()){
pq.add(mapEntry);
}
while(!pq.isEmpty()){
System.out.println(pq.poll());
}
The above code will process the priority queue using the natural order of the HashMap's keys.
Constructor for comparing by values (natural order):
PriorityQueue<Map.Entry<String, Integer>> pq = new PriorityQueue<>(Map.Entry.comparingByValue());
Constructor for comparing in reverse order:
PriorityQueue<Map.Entry<String, Integer>> pq = new PriorityQueue<>(Map.Entry.comparingByValue(Comparator.reverseOrder()));
Using lambdas (natural order, use b-a for reverse order):
PriorityQueue<Map.Entry<String, Integer>> pq = new PriorityQueue<>(Map.Entry.comparingByValue((a,b)->a.getValue()-b.getValue());