我制作了一个函数,可以读取文本文件,并通过使用哈希图计算单词的出现频率。然后,我发现制作一个对哈希图进行排序的函数非常困难...因此,经过一些研究,我发现了一些使用集和列表对哈希图进行排序的代码。但是,此函数的输出是列表,而不是哈希图。一切正常,并且完全符合我的要求。因此,我的问题是,获取列表内容并将其放回哈希表的最有效方法是什么,以便可以与我的其余代码一起使用。
编辑
好的,所以我很清楚,这不能实现,因为它不是使用哈希图时的目的。我问这个问题的唯一原因是因为我有现有代码(在必须执行更改之前)将其输出到文件中。这在使用哈希图时有效,但是现在我有些困惑了。
欢呼
构建哈希图
private static HashMap<String, Integer> theHashMap(String inFileName) throws IOException {
// Resets collections frequency values to zero
for (Map.Entry<String, Integer> entry : collection.entrySet()) {
entry.setValue(0);
}
// Reads in the new document file to an ArrayList
Scanner textFile = new Scanner(new File(inFileName));
ArrayList<String> file = new ArrayList<String>();
while(textFile.hasNext()) {
file.add(textFile.next().trim().toLowerCase());
}
for(String word : file) {
Integer dict = collection.get(word);
if (!collection.containsKey(word)) {
collection.put(word, 1);
} else {
collection.put(word, dict + 1);
}
}
textFile.close();
return collection;
}
排序哈希图
private static List<Map.Entry<String, Integer>> sortTheHashMap(HashMap<String, Integer> values) {
Set<Entry<String, Integer>> set = values.entrySet();
List<Entry<String, Integer>> list = new ArrayList<Entry<String, Integer>>(set);
Collections.sort( list, new Comparator<Map.Entry<String, Integer>>()
{
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2)
{
return (o2.getValue()).compareTo(o1.getValue());
}
} );
for(Map.Entry<String, Integer> entry:list){
System.out.println(entry.getKey()+" = "+entry.getValue());
}
return list;
}
输出到文件
FileWriter fw;
File fileName;
fileName = new File("test.txt");
fw = new FileWriter(fileName, true);
for (String word : document.getKey()) {
String key = word.toString();
String value = document.get(word);
fw.write(key + " " + value + "\n\n");
}
fw.close()
答案 0 :(得分:2)
未对Java HashMap进行排序。它明确地写在Javadoc:
此类不保证地图的顺序;在 特别是,它不能保证订单将保持不变 随着时间的流逝。
如果您希望地图按其键排序,请使用TreeMap:
根据地图键的自然顺序或通过 地图创建时提供的比较器,具体取决于哪个 使用构造函数。
但是,我不确定地图是否真的是您想要的。映射用于通过键查找值。排序后的映射对键进行排序,看起来您想对值(出现次数)进行排序。如果您有两个单词出现次数相同,应该在哪个键下出现呢?
这就是Collections.sort()
返回列表的原因-它对给定的集合进行排序,并将元素按所需的顺序放置。
答案 1 :(得分:0)
如果您将已排序的条目添加到LinkedHashMap
,由于LinkedHashMap
保持插入顺序,它们将保持排序状态(只要您不添加新键)。
鉴于您的List<Map.Entry<String, Integer>>
,您可以按以下方式生成Map
:
List<Map.Entry<String, Integer>> entries = ...;
Map<String,Integer> map = entries.stream()
.collect(Collectors.toMap(Map.Entry::getKey,
Map.Entry::getValue,
(v1,v2)->v1,
LinkedHashMap::new));
如果您的排序是由键(而不是值)决定的,则可以使用TreeMap
代替[Linked]HashMap
,这样可以解决排序问题。
答案 2 :(得分:0)
@Test
public void convert_list_to_map_with_java8_lambda () {
List<Movie> movies = new ArrayList<Movie>();
movies.add(new Movie(1, "The Shawshank Redemption"));
movies.add(new Movie(2, "The Godfather"));
Map<Integer, Movie> mappedMovies = movies.stream().collect(
Collectors.toMap(Movie::getRank, (p) -> p));
logger.info(mappedMovies);
assertTrue(mappedMovies.size() == 2);
assertEquals("The Shawshank Redemption", mappedMovies.get(1).getDescription());
}