简体   繁体   English

Java中将Key和Value加入优先队列并按Key排序

[英]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. Key 是单词,value 是单词的字符串值。 Then I need to sort the queue with the highest string value first.然后我需要先对具有最高字符串值的队列进行排序。 The priority queue is not letting me add 2 values.优先级队列不允许我添加 2 个值。

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

Problem问题

PriorityQueue can store a single object in it's each node. PriorityQueue可以在它的每个节点中存储单个对象。 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 .但是您可以将两个对象组合在一个类中,然后使用PriorityQueue

You would either need to supply a Comparator or rely on natural ordering by implementing Comparable interface.您需要提供Comparator或通过实现Comparable接口依赖自然排序


Solution解决方案

  • Create a class which has String and int as it's members.创建一个具有Stringint作为成员的类。

     public class Entry { private String key; private int value; // Constructors, getters etc. }
  • Implement Comparable interface and delegate comparison to String .实现Comparable接口并将比较委托给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

     PriorityQueue<Entry> q = new PriorityQueue<>();
  • Add elements as following.添加元素如下。

     q.add(new Entry(strings.get(x), calculateStringValue(strings.get(x))));

Hope this helps.希望这可以帮助。

Using Java-8使用 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));

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 .我相信最简洁的方法是将 Strings 存储在您的 pq 中并使用一个小的自定义Comparator In this case, we want to use calculateStringValue and the pq should return highest String values first.在这种情况下,我们想要使用calculateStringValue并且 pq 应该首先返回最高的String值。 Therefore, make a pq of entries and use the following Comparator :因此,制作 pq 条目并使用以下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: Comparator更简单语法(替换第 1 - 6 行)是:

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 :如果您想首先返回最小的String值,您可以在Comparator切换ab的顺序:

...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.一般来说,模式a - b先按最小值排序, b - a先按最大值排序。

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.您还可以从 HashMaps 中创建优先级队列,如下所示。 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.添加到@Tanmay Patil 回答中,如果您使用的是 Java 8,您可以使用 lambda 来获得更简洁的代码,因为比较器接口是一个功能接口。

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同样的逻辑也可以通过使用 java 提供的Map.Entry<String, Integer>来存储键,对值

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM