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()));
