将键和值添加到优先级队列中并在 Java 中按键排序

Posted

技术标签:

【中文标题】将键和值添加到优先级队列中并在 Java 中按键排序【英文标题】:Add Key and Value into an Priority Queue and Sort by Key in Java 【发布时间】:2015-04-26 01:26:56 【问题描述】:

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

【问题讨论】:

> "key 是单词,value 是单词的字符串" 单词是字符串吗?不清楚你在做什么或为什么这样做 您没有正确使用 PQ。请参阅this 以获取适当的示例。 【参考方案1】:

问题

PriorityQueue 可以在每个节点中存储一个对象。所以你想做的事情不能照原样做。

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

您需要提供Comparator 或通过实现Comparable 接口来依赖natural ordering。


解决方案

创建一个具有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());
    

使用此类构建PriorityQueue

PriorityQueue<Entry> q = new PriorityQueue<>();

如下添加元素。

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

希望这会有所帮助。

【讨论】:

现在在Java-8之后我们可以使用java提供的Entry类来做同样的操作。这更加一致和可靠。【参考方案2】:

使用 Java-8

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

添加新条目

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

【讨论】:

请解释队列参数 我相信构造函数arg是比较器。【参考方案3】:

解决方案

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 应该首先返回最高的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));

如果您想首先返回最小的String 值,您可以在Comparator 中切换ab 的顺序:

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

一般情况下,a - b 模式先按最小值排序,b - a 按最大值先排序。

【讨论】:

【参考方案4】:

已经有很多好的答案,但我发布这个答案是因为没有人在他们的答案中使用 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);
            
        );

【讨论】:

【参考方案5】:

添加到@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&lt;String, Integer&gt; 来存储key,pair value

【讨论】:

【参考方案6】:

用一个键域和一个值域定义一个类

Class MyClass
    int key;
    String value


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

【讨论】:

以上是关于将键和值添加到优先级队列中并在 Java 中按键排序的主要内容,如果未能解决你的问题,请参考以下文章

高效的方法将键和值添加到scala中的Set Map

未能将键和值添加到javascript对象

从python字典如何将键和值保存到* .txt文件[关闭]

按键和值对地图排序

需要使用 Objective C 将新的键和值添加到 Plist 中? [复制]

如何比较两个json文件并在对象中返回不匹配的键和值