打印使用优先级队列排序的 hashmap 实例
Printing hashmap instances ordered using priority queue
我已经插入了一个 txt 文件的不同单词以及它们在哈希图中分别作为键和值重复了多少次。问题是,我想使用 PQ 按降序打印 k 个最常用的单词,但是尽管将值插入整数优先级队列然后获取 k 个最大整数似乎很容易,但我无法弄清楚再次获取与每个值对应的键以打印它的方法(值可能不是唯一的)。一种解决方案是反转散列图,但这似乎不是 "safe" 的选择。
public static void main(int k)throws IOException{
//Create input stream & scanner
FileInputStream file = new FileInputStream("readwords.txt");
Scanner fileInput = new Scanner(file);
Map<String, Integer> frequency = new HashMap<>();
LinkedList<String> distinctWords = new LinkedList<String>();
PriorityQueue<Integer> pQueue = new PriorityQueue<Integer>();
//Read through file and find the words
while(fileInput.hasNext()){
//Get the next word
String nextWord = fileInput.next().toLowerCase();
//Determine if the word is in the HashMap
if(frequency.containsKey(nextWord)) {
frequency.put(nextWord, frequency.get(nextWord) + 1);
}
else {
frequency.put(nextWord, 1);
distinctWords.add(nextWord);
}
}
//Close
fileInput.close();
file.close();
}
可能有多种解决方案,这是我的。创建一个包含两个字段的 class
;一份用于 String
,一份用于 Integer
。使 class 实现 Comparable
并覆盖方法 compareTo
以便它比较 Integers
.
public class WordFrequency implements Comparable<WordFrequency> {
private String word;
private Integer frequency;
public WordFrequency(String word, Integer frequency) {
this.word = word;
this.frequency = frequency;
}
// descending order
@Override
public int compareTo(WordFrequency o) {
return o.getFrequency() - this.getFrequency();
}
public Integer getFrequency() {
return this.frequency;
}
@Override
public String toString() {
return word + ": " + frequency;
}
}
然后,将您的 map<String, Integer>
转换为 PriorityQueue<WordFrequency>
:
PriorityQueue<WordFrequency> pQueue = frequency.entrySet().stream()
.map(m -> new WordFrequency(m.getKey(), m.getValue()))
.collect(Collectors.toCollection(PriorityQueue::new));
如果要打印,必须使用poll()
,否则不保证顺序。
while(!pQueue.isEmpty())
System.out.println(pQueue.poll());
我已经插入了一个 txt 文件的不同单词以及它们在哈希图中分别作为键和值重复了多少次。问题是,我想使用 PQ 按降序打印 k 个最常用的单词,但是尽管将值插入整数优先级队列然后获取 k 个最大整数似乎很容易,但我无法弄清楚再次获取与每个值对应的键以打印它的方法(值可能不是唯一的)。一种解决方案是反转散列图,但这似乎不是 "safe" 的选择。
public static void main(int k)throws IOException{
//Create input stream & scanner
FileInputStream file = new FileInputStream("readwords.txt");
Scanner fileInput = new Scanner(file);
Map<String, Integer> frequency = new HashMap<>();
LinkedList<String> distinctWords = new LinkedList<String>();
PriorityQueue<Integer> pQueue = new PriorityQueue<Integer>();
//Read through file and find the words
while(fileInput.hasNext()){
//Get the next word
String nextWord = fileInput.next().toLowerCase();
//Determine if the word is in the HashMap
if(frequency.containsKey(nextWord)) {
frequency.put(nextWord, frequency.get(nextWord) + 1);
}
else {
frequency.put(nextWord, 1);
distinctWords.add(nextWord);
}
}
//Close
fileInput.close();
file.close();
}
可能有多种解决方案,这是我的。创建一个包含两个字段的 class
;一份用于 String
,一份用于 Integer
。使 class 实现 Comparable
并覆盖方法 compareTo
以便它比较 Integers
.
public class WordFrequency implements Comparable<WordFrequency> {
private String word;
private Integer frequency;
public WordFrequency(String word, Integer frequency) {
this.word = word;
this.frequency = frequency;
}
// descending order
@Override
public int compareTo(WordFrequency o) {
return o.getFrequency() - this.getFrequency();
}
public Integer getFrequency() {
return this.frequency;
}
@Override
public String toString() {
return word + ": " + frequency;
}
}
然后,将您的 map<String, Integer>
转换为 PriorityQueue<WordFrequency>
:
PriorityQueue<WordFrequency> pQueue = frequency.entrySet().stream()
.map(m -> new WordFrequency(m.getKey(), m.getValue()))
.collect(Collectors.toCollection(PriorityQueue::new));
如果要打印,必须使用poll()
,否则不保证顺序。
while(!pQueue.isEmpty())
System.out.println(pQueue.poll());