2009-03-02 6 views
0

私の問題は実際には問題の示唆よりも微妙ですが、ヘッダーを簡潔にしたいと思っていました。HashMapから抽出された値の順序付きリストを作成するにはどうすればよいですか?

私はHashMap<String, File>の値をFileとしています。キーは、Fileインスタンスの一部であるString nameフィールドです。 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クラスのフィールドである、別のFile値はint fileIDの順にStringBuilderに追加することにしたいです。

私はそれを十分に明確にしました。

+0

パフォーマンスコストがかかる場合は、SortedMap(TreeMapなど)を使用する必要があります。 – Powerlord

答えて

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);       
        } 
       }); 
+0

整数をオーバーフローさせてソートしてください! –

+0

ありがとう、私はあなたが提案した変更を実装しました。以下を参照してください。 – darrengorman

+0

return fileA.fileID - fileB.fileID; – akuhn

4

残念ながら、認識可能な順序でHashMapからデータを取得する方法はありません。すべての値を、FileIDを使用するComparatorを使用してTreeSetに格納するか、ArrayListに格納し、Collections.sortで並べ替える必要があります。

重複がある場合、TreeSetメソッドは機能しません。また、セットに物を追加したり削除したりすることがないため、余計かもしれません。 Collections.sortメソッドは、HashSet全体を取得し、結果をソートし、結果を生成するとすぐにソートされたコレクションを投げ捨てる、このような場合の良い解決策です。

+0

TreeSetの要素は、その値ではなくキーによってソートされます。 – pgras

+0

TreeSetにはキーがありません。あなたはTreeMapを考えています。 –

0

アレイで収集してソートして連結してみませんか?

- MarkusQ

0

あなたはArrayListに自分の価値観()コレクションを追加し、それを反復処理する前に、カスタムコンパレータのインスタンスでCollections.sort()を使用して、それをソートする必要があります。

ところで、コレクション要素ごとに1文字をはるかに追加するので、StringBufferをコレクションのサイズで初期化するのは意味がないことに注意してください。

0

私は、のLinkedHashMap 12回を作成しました。

あなたがやりたいことは、TreeHashMapコレクションを作成することです。

2つ目のコレクションを作成して両方に追加したものを追加することは、実際にはサイズヒットではなく、両方のパフォーマンスを得ることになります(追加する際に少し時間がかかる)。

新しいコレクションとして使用すると、コードがきれいに整えられます。コレクションクラスはちょうど数行にすぎず、既存のハッシュマップを置き換える必要があります...

あなたのコレクションを常にラップする習慣を身につけたら、このものはちょうどうまくいきます。あなたはそれについて考えることもありません。

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

file.toString()が平均して1文字でない限り、おそらくStringBufferが小さすぎる可能性があります。 (正しいのでなければ、それを設定せずにコードを単純化することもできます)サイズの倍数にすると、より良い結果を得ることができます。さらに、StringBufferは同期されていますが、ここではStringBuilderは効率的ではありません。

+0

Peterに感謝します。私はStringBuilderをStringBuilderに置き換え、コンストラクタからパラメータを削除しました。 – darrengorman

1

これは私が思いついたものです。この問題を解決すると思われ、fileIdで整理されたFileオブジェクトを含むStringを返します。

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

私は(Javaへの比較的新しい)の前にコンパレータを使ったことがないので、私は間違って何を実装した場合の任意のフィードバックをいただければ幸いです。

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); 
       } 
      }); 
関連する問題