Reputation: 305
I am trying to take in a List of strings and add them into a Priority Queue with Key and Value. The Key being the word and the value being the string value of the word. Then I need to sort the queue with the highest string value first. The priority queue is not letting me add 2 values.
public static List<String> pQSortStrings(List<String> strings) {
PriorityQueue<String, Integer> q = new PriorityQueue<>();
for (int x = 0; x < strings.size(); x++) {
q.add(strings.get(x),calculateStringValue(strings.get(x)));
}
return strings;
}
Upvotes: 17
Views: 65968
Reputation: 157
Define a class with a key field and a value field
Class MyClass{
int key;
String value
}
Queue<MyClass> queue = new PriorityQueue<>(Comparotor.comparingInt(a -> a.key));
Upvotes: 1
Reputation: 193
Many good answers are already present but I am posting this answer because no one has used hashmap in their answers.
You can also make the priority Queue from HashMaps bellow is the example for the same. I am creating a max priority queue. Mind well here I am considering that your hashmap contains only one Entry
PriorityQueue<HashMap<Character, Integer>> pq = new PriorityQueue<>((a, b) -> {
char keyInA = a.keySet().iterator().next(); // key of a
char keyInB = b.keySet().iterator().next(); // key of b
return b.get(keyInB) - a.get(keyInA);
});
For Insertion of the value in the priority queue.
pq.add(new HashMap<>() {
{
put('a', 0);
}
});
Upvotes: 0
Reputation: 1493
Adding to @Tanmay Patil Answer, If you are using Java 8, You can use lambda for more concise code as comparator interface is a functional interface.
public class CustomEntry {
private String key;
private int value;
public CustomEntry(String key, int value) {
this.key = key;
this.value = value;
}
// getters etc.
}
Now below is the updated code
public static List<String> pQSortStrings(List<String> strings) {
PriorityQueue<CustomEntry> q = new PriorityQueue<>((x, y) -> {
// since you want to sort by highest value first
return Integer.compare(y.getValue(), x.getValue());
});
for (int x = 0; x < strings.size(); x++) {
q.add(new CustomEntry(strings.get(x),calculateStringValue(strings.get(x))));
}
return strings;
}
To use this priority queue
CustomEntry topEntry = q.peek();
System.out.println("key : " + topEntry.getKey());
System.out.println("value : " + topEntry.getValue());
Same logic can be also be applied by using Map.Entry<String, Integer>
provided by java for storing key, pair value
Upvotes: 0
Reputation: 1654
Using Java-8
PriorityQueue<Map.Entry<String, Integer>> queue = new PriorityQueue<>(Map.Entry.comparingByValue(Comparator.reverseOrder()));
to add a new Entry
queue.offer(new AbstractMap.SimpleEntry<>("A", 10));
Upvotes: 21
Reputation: 21
public static List<String> pQSortStrings(List<String> strings) {
Queue<String> pq = new PriorityQueue<>((a, b) ->
calculateStringValue(b) - calculateStringValue(a));
for (String str : strings) {
pq.add(str);
}
return strings;
}
I believe that the cleanest way to do this is to store Strings in your pq and use a small custom Comparator
.
In this case, we want to use calculateStringValue
and the pq should return highest String
values first. Therefore, make a pq of entries and use the following Comparator
:
1 Queue<String> pq = new PriorityQueue<>(new Comparator<String>() {
2 @Override
3 public int compare(String a, String b) {
4 return calculateStringValue(b) - calculateStringValue(a);
5 }
6 });
7 for (String str : strings) {
8 pq.add(str);
9 }
10 return strings;
Simpler syntax for the Comparator
, replacing lines 1 - 6, is:
Queue<String> pq = new PriorityQueue<>((a, b) ->
calculateStringValue(b) - calculateStringValue(a));
If you wanted to return smallest String
values first, you could just switch the order around for a
and b
in the Comparator
:
...new PriorityQueue<>((a, b) -> calculateStringValue(a) - calculateStringValue(b));
In general, the pattern a - b
sorts by smallest first, and b - a
sorts by largest values first.
Upvotes: 2
Reputation: 7057
PriorityQueue
can store a single object in it's each node. So what you are trying to do can not be done as it is.
But you can compose both objects in a single class and then use the PriorityQueue
.
You would either need to supply a Comparator
or rely on natural ordering by implementing Comparable
interface.
Create a class which has String
and int
as it's members.
public class Entry {
private String key;
private int value;
// Constructors, getters etc.
}
Implement Comparable
interface and delegate comparison to String
.
public class Entry implements Comparable<Entry> {
private String key;
private int value;
public Entry(String key, int value) {
this.key = key;
this.value = value;
}
// getters
@Override
public int compareTo(Entry other) {
return this.getKey().compareTo(other.getKey());
}
}
Build the PriorityQueue
using this class.
PriorityQueue<Entry> q = new PriorityQueue<>();
Add elements as following.
q.add(new Entry(strings.get(x), calculateStringValue(strings.get(x))));
Hope this helps.
Upvotes: 27