I am creating a Min-Heap using PriorityQueue
populated from a HashMap
. Where Entry
objects of the Map
are pairs of Integer
& Integer
.
And I'm implementing it with a help of Comparator
. To use Value of HashMap
for comparison.
My question is - How to make comparison of HashMap
entries on Value of type Integer
?
PriorityQueue<Map.Entry<Integer, Integer>> minHeap = new PriorityQueue<>(new Comparator<Map.Entry<Integer, Integer>>() {
@Override
public int compare(Entry<Integer, Integer> o1, Entry<Integer, Integer> o2) {
return o1.getValue() - o2.getValue();
}
});
CodePudding user response:
Defining a Comparator
Defining a Comparator
using an anonymous class isn't a good approach.
Since Java 8 which was released more than 8 years ago we have an alternative, or even a bunch of alternatives like in this case.
A simple and straightforward lambda expression:
Comparator<Map.Entry<Integer, Integer>> byValueAsc =
(entry1, entry2) -> entry1.getValue() - entry2.getValue();
Java 8 static method comparingInt()
from the Comparator
interface:
Comparator<Map.Entry<Integer, Integer>> byValueAsc =
Comparator.comparingInt(Map.Entry::getValue);
And the most suitable option it this case comparingByValue()
from the Entry
interface :
PriorityQueue<Map.Entry<Integer, Integer>> minHeap =
new PriorityQueue<>(Map.Entry.comparingByValue());
Populating the Queue
To populate the queue with entries from a map, you can use a plain for
loop:
Map<Integer, Integer> map = new HashMap<>();
for (Map.Entry<Integer, Integer> entry: map.entrySet()) {
minHeap.add(entry);
}
Or by making use of forEach()
from Collection
interface invoked on the entry set:
PriorityQueue<Map.Entry<Integer, Integer>> minHeap = new PriorityQueue<>(Map.Entry.comparingByValue());
map.entrySet().forEach(minHeap::add);
CodePudding user response:
You could combine the comparison by first comparing the value and then the key like so:
final var queue = new PriorityQueue<>(
Map.Entry.<Integer, Integer>comparingByValue()
.thenComparing(Map.Entry.comparingByKey()));