将 Key 和 Value 添加到优先队列中并按 Java 中的 Key 排序

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

我正在尝试接收字符串列表并将它们添加到具有键和值的优先级队列中。键是单词,值是单词的字符串值。然后我需要先对字符串值最高的队列进行排序。优先级队列不允许我添加 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;
}

问题

PriorityQueue 可以在它的每个节点中存储单个对象。所以你想做的事情不能按原样完成。

但是您可以将两个对象组合在一个 class 中,然后使用 PriorityQueue.

您需要提供一个 Comparator or rely on natural ordering by implementing Comparable 接口。


解决方案

  • 创建一个 class,其成员为 Stringint

    public class Entry {
        private String key;
        private int value;
    
        // Constructors, getters etc.
    }
    
  • 实现 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());
        }
    }
    
  • 使用此class构建PriorityQueue

    PriorityQueue<Entry> q = new PriorityQueue<>();
    
  • 添加如下元素。

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

希望这对您有所帮助。

使用Java-8

PriorityQueue<Map.Entry<String, Integer>> queue = new PriorityQueue<>(Map.Entry.comparingByValue(Comparator.reverseOrder()));

添加新条目

queue.offer(new AbstractMap.SimpleEntry<>("A", 10));

解决方案

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

说明

我认为最干净的方法是将字符串存储在您的 pq 中并使用一个小的自定义 Comparator。 在这种情况下,我们要使用 calculateStringValue 并且 pq 应该首先 return 最高 String 值。因此,制作一个 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;

Comparator 的更简单语法,替换第 1 - 6 行,是:

Queue<String> pq = new PriorityQueue<>((a, b) -> 
    calculateStringValue(b) - calculateStringValue(a));

如果您想 return 最小的 String 值优先,您可以在 Comparator 中调换 ab 的顺序:

...new PriorityQueue<>((a, b) -> calculateStringValue(a) - calculateStringValue(b));

一般来说,a - b 模式先按最小值排序,b - a 模式先按最大值排序。

添加到@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.
}

下面是更新后的代码

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

要使用这个优先级队列

CustomEntry topEntry = q.peek();
System.out.println("key : " + topEntry.getKey());
System.out.println("value : " + topEntry.getValue());

同样的逻辑也可以用java提供的Map.Entry<String, Integer> 来存储键值对

已经有很多好的答案,但我发布这个答案是因为没有人在他们的答案中使用 hashmap。


你也可以从 HashMaps 中创建优先队列,下面的例子也是一样的。我正在创建一个最大优先级队列。 请注意,我正在考虑您的哈希图仅包含一个条目

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

用于在优先级队列中插入值。

pq.add(new HashMap<>() {
            {
                put('a', 0);
            }
        });

定义一个 class 具有键字段和值字段

Class MyClass{
    int key;
    String value
}

Queue<MyClass> queue = new PriorityQueue<>(Comparotor.comparingInt(a -> a.key));