Add Key and Value into an Priority Queue and Sort by Key in Java

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;
}
2

6 Answers

Problem

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.


Solution

  • 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.

1

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

Solution

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;
}

Explanation

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.

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

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

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

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like