HashMaps和列表

时间:2018-08-05 10:58:16

标签: java list hashmap

我制作了一个函数,可以读取文本文件,并通过使用哈希图计算单词的出现频率。然后,我发现制作一个对哈希图进行排序的函数非常困难...因此,经过一些研究,我发现了一些使用集和列表对哈希图进行排序的代码。但是,此函数的输出是列表,而不是哈希图。一切正常,并且完全符合我的要求。因此,我的问题是,获取列表内容并将其放回哈希表的最有效方法是什么,以便可以与我的其余代码一起使用。

编辑

好的,所以我很清楚,这不能实现,因为它不是使用哈希图时的目的。我问这个问题的唯一原因是因为我有现有代码(在必须执行更改之前)将其输出到文件中。这在使用哈希图时有效,但是现在我有些困惑了。

欢呼

构建哈希图

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

3 个答案:

答案 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)

JAVA8 Stream

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