简体   繁体   English

为什么remove函数不适用于hashmaps?

[英]Why is the remove function not working for hashmaps?

I am working on a simple project that obtains data from an input file, gets what it needs and prints it to a file. 我正在开发一个简单的项目,从输入文件中获取数据,获取所需内容并将其打印到文件中。 I am basically getting word frequency so each key is a string and the value is its frequency in the document. 我基本上得到字频,所以每个键都是一个字符串,值是文档中的频率。 The problem however, is that I need to print out these values to a file in descending order of frequency. 但问题是,我需要按频率的降序将这些值打印到文件中。 After making my hashmap, this is the part of my program that sorts it and writes it to a file. 在制作我的hashmap之后,这是我的程序的一部分,它对它进行排序并将其写入文件。

//Hashmap I create
Map<String, Integer> map = new ConcurrentHashMap<String, Integer>();
int valueMax = -1;
//function to sort hashmap
while (map.isEmpty() == false){
            for (Entry<String, Integer> entry: map.entrySet()){
                if (entry.getValue() > valueMax){
                    max = entry.getKey();
                    System.out.println("max: " + max);
                    valueMax = entry.getValue();
                    System.out.println("value: " + valueMax);
                }
            }
            map.remove(max);
            out.write(max + "\t" + valueMax + "\n");
            System.out.println(max + "\t" + valueMax);  
        }   

When I run this i get: 当我跑这个我得到:

t 9
t 9
t 9
t 9
t 9
....

so it appears the remove function is not working as it keeps getting the same value. 所以看起来删除功能不起作用,因为它保持获得相同的值。 I'm thinking i have an issue with a scope rule or I just don't understand hashmaps very well. 我想我有一个范围规则的问题,或者我只是不太了解hashmaps。

If anyone knows of a better way to sort a hashmap and print it, I would welcome a suggestion. 如果有人知道更好的方法来排序哈希映射并打印它,我会欢迎一个建议。

thanks 谢谢

Your code doesn't work because on every subsequent iteration, entry.getValue() > valueMax is never true because you don't reset valueMax on re-entry into the while loop. 您的代码不起作用,因为在每次后续迭代中, entry.getValue() > valueMax永远不会为真,因为您在重新进入while循环时不重置valueMax

You don't need to muck around with double-looping over a concurrently accessible map though. 尽管如此,您不需要在可同时访问的地图上进行双循环。

ConcurrentSkipListMap has a lastKey method that returns the greatest key and doesn't require iteration over the entire map. ConcurrentSkipListMap有一个lastKey方法,它返回最大的键,不需要在整个映射上进行迭代。

From your code it looks like you aren't resetting valueMax at the end of your loop. 从您的代码看,您似乎没有在循环结束时重置valueMax This means the first time round the loop you'll find the maximum but you'll never find any subsequent values because you'll still be comparing to the overall maximum. 这意味着第一次循环你会找到最大值,但你永远不会找到任何后续值,因为你仍然会比较总体最大值。

Hashmap: no order. Hashmap:没有订单。 You can use ArrayList, which implements List to have an order. 您可以使用ArrayList来实现List以获得订单。

Take a look : http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html 看看: http//docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html

I guess it's because there no entries in map with key > initial value of valueMax, so condition if (entry.getValue() > valueMax) never true. 我想这是因为map中没有条目带有key> valueMax的初始值,所以条件if (entry.getValue() > valueMax)永远不为真。

Additionally, there's TreeMap which holds it's contents sorted, so you can just iterate over it's entrySet() w/o any additional logic. 另外,还有TreeMap对其内容进行了排序,因此您可以在任何其他逻辑上迭代它的entrySet()

What about something like (not tested) 怎么样(没有经过测试)

  final Map<String, Integer> map = new ConcurrentHashMap<String, Integer>();
  final Comparator <String, String> comparator = new Comparator ()
         {
             compare(String o1, String o2) 
             {
                  return map.get(o1) - map.get(o2);
             }
         };

  final TreeMap <String, Integer> sortedMap = new TreeMap (comparator);
  sortedMap.addAll(map);
  System.out.println(sortedMap);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM