Java 已排序的映射未输出已排序的。我懂地图吗。

Java 已排序的映射未输出已排序的。我懂地图吗。,java,map,Java,Map,我一直在阅读地图,了解树地图和散列、排序地图的一些区别。我试图在输出地图时对其进行排序 我需要做的是: 取一个文本文件,读入内容。 把它分成几个单独的单词。将单词用作键,将值用作该键在txt文件中出现的次数。 如果单词在一个句子的末尾,我要把它作为一个单独的键。例如,我的和我的。是两个分开的钥匙。 我的问题是,无论我将它声明为树、散列还是排序映射,我都无法让它以有序的方式输出/迭代。我希望它首先以最高值输出,但我甚至不能以任何顺序用键输出 public static Map<String,

我一直在阅读地图,了解树地图和散列、排序地图的一些区别。我试图在输出地图时对其进行排序

我需要做的是:

取一个文本文件,读入内容。 把它分成几个单独的单词。将单词用作键,将值用作该键在txt文件中出现的次数。 如果单词在一个句子的末尾,我要把它作为一个单独的键。例如,我的和我的。是两个分开的钥匙。 我的问题是,无论我将它声明为树、散列还是排序映射,我都无法让它以有序的方式输出/迭代。我希望它首先以最高值输出,但我甚至不能以任何顺序用键输出

public static Map<String, Integer> createDictionary(String _filename)
{
    TreeMap<String, Integer> dictionary = new TreeMap<String, Integer>(); // Changed Hash to _______

    try {
          FileReader myFileReader=new FileReader(_filename); // File reader stream open
          BufferedReader myBuffReader=new BufferedReader(myFileReader);

          String str = "\0";

          while (str != null) { // While there are still strings in the file
              str = myBuffReader.readLine(); // We read a line into the str variable

              if (str != null) { // Make sure its not the last line/EOF 
                  // System.out.println(str); // Used for testing. 
                  StringTokenizer myTokenStr=new StringTokenizer(str," \t"); // Create a StringToken obj from the string

                  while (myTokenStr.hasMoreTokens()) {
                      String tokStr = myTokenStr.nextToken(); // Each token is put into an individual string
                      // System.out.println(tokStr);

                      if (dictionary.containsKey(tokStr)) {
                          int value = dictionary.get(tokStr); // Add one to the integer value
                          // dictionary.remove(tokStr); // Was doing this way but just using put method works 
                          // dictionary.put(tokStr, value + 1);
                          dictionary.put(tokStr, value + 1);
                      }
                      else {
                          dictionary.put(tokStr, 1); // Add the string as the key with an int value of one for the value
                      }
                  }
              }
          }

          myBuffReader.close(); // Close stream
          myFileReader.close(); // Close stream
      }
      catch (FileNotFoundException e) {
          System.out.println("File Not Found");
      }
      catch (IOException e) { }

      // System.out.println(dictionary.entrySet());

      return dictionary;
}

这是TreeMap的文档,摘自其Javadoc:

public class TreeMap extends AbstractMap implements NavigableMap, Cloneable, Serializable A Red-Black tree based NavigableMap implementation. The map is sorted according to the natural ordering of its keys, or by a Comparator provided at map creation time, depending on which constructor is used.
正如您所看到的,对映射的键进行迭代会产生有序的结果。该顺序由字符串的自然顺序定义。不幸的是,您无法实现按值排序的SortedMap,我相信这正是您想要做的。但是,您可以在地图之外对地图中的条目进行排序。请参阅另一篇SO帖子中的更多详细信息:。

这是从Javadoc中提取的TreeMap文档:

public class TreeMap extends AbstractMap implements NavigableMap, Cloneable, Serializable A Red-Black tree based NavigableMap implementation. The map is sorted according to the natural ordering of its keys, or by a Comparator provided at map creation time, depending on which constructor is used.
正如您所看到的,对映射的键进行迭代会产生有序的结果。该顺序由字符串的自然顺序定义。不幸的是,您无法实现按值排序的SortedMap,我相信这正是您想要做的。但是,您可以在地图之外对地图中的条目进行排序。请参阅另一篇SO帖子中的更多详细信息:。

您的地图是按字母顺序排序的,而不是按出现次数排序的。您需要在初始解析之后对映射进行后处理。我建议:

将文件解析为HashMap 迭代HashMap,并将元素添加到树映射中,请参见下文。 输出树映射。 您可以实现步骤2。例如:

TreeMap<Integer, Set<String> > treeMap = new TreeMap<Integer, Set<String> > ();
for (Map.Entry<String, Integer> entry: hashMap) {
    Set<String> set = treeMap.get(entry.value());
    if (set == null) {
        set = new TreeSet<String>();
        treeMap.put(entry.value(), set);
    }
    set.add(entry.key());
}

应该这样做。

您的地图是按字母顺序排序的,而不是按出现次数排序的。您需要在初始解析之后对映射进行后处理。我建议:

将文件解析为HashMap 迭代HashMap,并将元素添加到树映射中,请参见下文。 输出树映射。 您可以实现步骤2。例如:

TreeMap<Integer, Set<String> > treeMap = new TreeMap<Integer, Set<String> > ();
for (Map.Entry<String, Integer> entry: hashMap) {
    Set<String> set = treeMap.get(entry.value());
    if (set == null) {
        set = new TreeSet<String>();
        treeMap.put(entry.value(), set);
    }
    set.add(entry.key());
}
这应该就够了。

地图对于这类事情来说是一种混乱的抽象,但我要扔掉番石榴作为解决这个用例的一种方式,因为它是专门为计算事物的发生而设计的

特别是,

return Multisets.copyHighestCountFirst(HashMultiset.copyOf(listOfWords));
返回按ListofWord中的降序频率在元素上迭代的多集

顺便说一句,关于按值而不是键对地图进行排序有很多问题,但我更喜欢。

地图对于这类事情来说是一种混乱的抽象,但我将扔掉番石榴作为解决这个用例的一种方法,因为它是专为计算事情的发生而设计的

特别是,

return Multisets.copyHighestCountFirst(HashMultiset.copyOf(listOfWords));
返回按ListofWord中的降序频率在元素上迭代的多集


顺便说一句,关于按值而不是键对映射排序,有很多问题,但我更喜欢。

首先,您确定要在\t上标记吗?当您说break-into-words时,默认的标记字符串在一般情况下似乎更匹配,即StringTokenizerstr您不以标记化的方式匹配换行符。你到底是如何迭代的?另外,如果您想对HashMap进行排序,那么忘记HashMap吧,TreeMap是唯一一种可以进行排序的方法。。。它以正确的字数输出正确的单词,但除此之外,单词是按字母顺序排列的,或者值/字数是按顺序排列的。它就像散列图一样随机。伊菲。。。。tokinize on\t应该在空格和制表符上标记化。唯一的另一个问题是生产线的末端,这已经得到了解决。我可能错了,但它与C++ TokTiCy类似,它与我发送的测试用例一起工作。首先,你确定要在T上签名吗?当您说break-into-words时,默认的标记字符串在一般情况下似乎更匹配,即StringTokenizerstr您不以标记化的方式匹配换行符。你到底是如何迭代的?另外,如果您想对HashMap进行排序,那么忘记HashMap吧,TreeMap是唯一一种可以进行排序的方法。。。它以正确的字数输出正确的单词,但除此之外,单词是按字母顺序排列的,或者值/字数是按顺序排列的。它就像散列图一样随机。伊菲。。。。tokinize on\t应该在空格和制表符上标记化。唯一的另一个问题是生产线的末端,这已经得到了解决。我可能错了,但它与C++的TokTiCy类似,它与我发送的测试用例一起工作。如果两个单词的计数相同,会发生什么?好点。我想如果没有树形图和一些额外的代码来创建列表并附加到列表中(如果它存在的话),它将无法工作。如果两个单词的计数相同,会发生什么?这一点很好。我想没有Tre它是行不通的
eMap和一些额外的代码来创建列表并在它存在时附加到它。如果我将我的映射更改为TreeMap,并且使用与POST相同的方法来迭代它,它不会像您所展示的那样提供和排序输出。这是我问题的一部分。从我所读到的到我所看到的,它们是不一样的。看看我的代码,我是如何在映射中进行迭代的。我不完全理解迭代器的用法。@aaronburns-您的代码看起来基本上很好。在将字符串存储到映射中之前,请尝试调用trim。如果我将映射更改为树映射,并且使用与post相同的方式对其进行迭代,则它不会像您所展示的那样提供和排序输出。这是我问题的一部分。从我所读到的到我所看到的,它们是不一样的。看看我的代码,我是如何在映射中进行迭代的。我不完全理解迭代器的用法。@aaronburns-您的代码看起来基本上很好。在将字符串存储到映射中之前,请尝试调用trim。