如何形成从HashMap中提取的有序值列表?

时间:2009-03-02 20:02:39

标签: java iterator hashmap

我的问题实际上比问题所暗示的更微妙,但是想要保持标题简短。

我有HashMap<String, File>File个对象作为值。密钥是String name个字段,它们是File个实例的一部分。我需要迭代HashMap中的值并将它们作为单个String返回。

这就是我目前的情况:

private String getFiles()
{   
    Collection<File> fileCollection = files.values();
    StringBuilder allFilesString = new StringBuilder();

    for(File file : fileCollection) {
        allFilesString.append(file.toString());
    }
    return allFilesString.toString();
}

这可以完成这项工作,但理想情况下,我希望将单独的File值按StringBuilder的顺序附加到int fileID,这是File的字段类。

希望我已经说清楚了。

9 个答案:

答案 0 :(得分:6)

这样的事情应该有效:

List<File> fileCollection = new ArrayList<File>(files.values());

Collections.sort(fileCollection, 
                 new Comparator<File>() 
                 {
                     public int compare(File fileA, File fileB) 
                     {
                         final int retVal;

                         if(fileA.fileID > fileB.fileID)
                         {
                             retVal = 1;
                         }
                         else if(fileA.fileID < fileB.fileID)
                         {
                             retVal = -1;
                         }
                         else
                         {
                             retVal = 0;
                         }

                         return (retVal);                         
                     }
                 });

答案 1 :(得分:4)

不幸的是,无法以任何可识别的顺序从HashMap中获取数据。您必须使用使用fileID的Comparator将所有值放入TreeSet中,或者将它们放入ArrayList并使用Collections.sort对它们进行排序,再次使用比较您所需方式的Comparator进行排序。

如果存在任何重复项,则TreeSet方法不起作用,并且由于您不打算向Set中添加内容或从中删除内容,因此它可能过度。 Collections.sort方法对于像这样的实例来说是一个很好的解决方案,你将获取整个HashSet,对结果进行排序,然后在生成结果后立即抛弃已排序的集合。

答案 2 :(得分:1)

好的,这就是我想出来的。似乎解决了这个问题,返回一个String,其File对象按其fileId排序很好。

public String getFiles()
{   
    List<File> fileList = new ArrayList<File>(files.values());

    Collections.sort(fileList, new Comparator<File>()
                               {
                                   public int compare(File fileA, File fileB)
                                   {
                                       if(fileA.getFileId() > fileB.getFileId()) 
                                       {
                                           return 1;
                                       }
                                       else if(fileA.getFileId() < fileB.getFileId()) 
                                       {
                                           return -1;
                                       }
                                       return 0;
                                   }
                               });

    StringBuilder allFilesString = new StringBuilder();

    for(File file : fileList) {
        allFilesString.append(file.toString());
    }
    return allFilesString.toString();
}

我之前从未使用过Comparator(相对较新的Java),如果我没有错误地实现任何反馈,我将不胜感激。

答案 3 :(得分:0)

为什么不在数组中收集它,对它进行排序,然后连接它?

- MarkusQ

答案 4 :(得分:0)

您必须将您的values()Collection添加到ArrayList,并在迭代之前使用Collections.sort()和自定义Comparator实例对其进行排序。

BTW,请注意,使用集合的大小初始化StringBuffer是没有意义的,因为每个集合元素将添加远超过1个字符。

答案 5 :(得分:0)

创建临时列表,然后将每对数据添加到其中。根据您的自定义比较器,使用Collections.sort()对其进行排序,然后按所需顺序排列List。

以下是您要查找的方法:http://java.sun.com/javase/6/docs/api/java/util/Collections.html#sort(java.util.List,%20java.util.Comparator)

答案 6 :(得分:0)

我在将LinkedHashMap添加到集合集之前已经创建了十几次。

您可能想要做的是创建一个TreeHashMap集合。

创建第二个集合并附加添加到这两个集合中的任何内容并不是真正的大小,并且您可以获得两者的性能(添加时会花费一点时间)。

将其作为新的集合来帮助您的代码保持干净整洁。集合类应该只有几行,并且应该只替换现有的hashmap ...

如果你养成了总是包装你的收藏品的习惯,这些东西就可以了,你甚至都不会想到它。

答案 7 :(得分:0)

StringBuffer allFilesString = new StringBuffer(fileCollection.size());

除非你的所有file.toString()平均是一个字符,否则你可能会使StringBuffer太小。 (如果不对,你也可以不设置它并使代码更简单)如果你把它设置为大小的倍数,你可能会得到更好的结果。另外StringBuffer是同步的,但StringBuilder不是,并且在这里效率更高。

答案 8 :(得分:0)

删除不必要的if声明。

List<File> fileCollection = new ArrayList<File>(files.values());
Collections.sort(fileCollection, 
             new Comparator<File>() {
                 public int compare(File a, File b) {
                     return (a.fileID - b.fileID);
                 }
             });