0

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

我有一个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类的一个字段。

希望我已经说得够清楚了。

4

9 回答 9

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);                         
                     }
                 });
于 2009-03-02T20:14:26.090 回答
4

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

如果有任何重复项,TreeSet 方法将不起作用,并且它可能会有点过分,因为您不会在 Set 中添加内容或从中删除内容。Collections.sort 方法是一个很好的解决方案,例如,您将获取整个 HashSet,对结果进行排序,然后在生成结果后立即丢弃已排序的集合。

于 2009-03-02T20:05:50.607 回答
1

好的,这就是我想出的。似乎解决了这个问题,返回一个字符串,其中的 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 来说相对较新),所以如果我实现了任何不正确的东西,我将不胜感激。

于 2009-03-04T23:55:29.430 回答
0

为什么不将它收集到一个数组中,对其进行排序,然后将其连接起来呢?

——马库斯

于 2009-03-02T20:06:45.220 回答
0

您必须将您的 values() 集合添加到 ArrayList 并使用 Collections.sort() 和自定义 Comparator 实例对其进行排序,然后再对其进行迭代。

顺便说一句,请注意,用集合的大小初始化 StringBuffer 是没有意义的,因为您将为每个集合元素添加超过 1 个字符。

于 2009-03-02T20:10:00.253 回答
0

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

这是您正在寻找的方法:http: //java.sun.com/javase/6/docs/api/java/util/Collections.html#sort (java.util.List,%20java.util.Comparator )

于 2009-03-02T20:10:21.030 回答
0

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

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

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

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

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

于 2009-03-02T20:47:17.137 回答
0
StringBuffer allFilesString = new StringBuffer(fileCollection.size());

除非您的所有 file.toString() 平均是一个字符,否则您可能会使 StringBuffer 太小。(如果不正确,你最好不要设置它,让代码更简单)如果你将它设置为大小的倍数,你可能会得到更好的结果。此外,StringBuffer 是同步的,但 StringBuilder 不是同步的,因此这里效率更高。

于 2009-03-04T07:04:31.340 回答
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);
                 }
             });
于 2009-03-12T00:59:41.620 回答