HashMapから抽出した値の順序付きリストを作成するにはどうすればよいですか?
質問
私の問題は、質問が示唆するよりも実際には微妙ですが、ヘッダーを簡潔にしたかったです。
値としてHashMap<String, File>
オブジェクトのFile
があります。キーは、String name
インスタンスの一部であるHashMap
フィールドです。 String
の値を反復処理し、それらを単一のStringBuilder
として返す必要があります。
これは私が現在持っているものです:
private String getFiles()
{
Collection<File> fileCollection = files.values();
StringBuilder allFilesString = new StringBuilder();
for(File file : fileCollection) {
allFilesString.append(file.toString());
}
return allFilesString.toString();
}
これは仕事をしますが、理想的にはint fileID
クラスのフィールドである<=>の順に<=>に個別の<=>値を追加したいです。
十分に明確にしたことを願っています。
解決
次のようなものが機能するはずです:
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);
}
});
他のヒント
残念ながら、認識可能な順序でHashMapからデータを取得する方法はありません。 fileIDを使用するComparatorですべての値をTreeSetに入れるか、ArrayListに入れてCollections.sortで並べ替え、必要に応じて比較するComparatorで並べ替える必要があります。
重複がある場合、TreeSetメソッドは機能しません。また、Setに物を追加したり、Setから物を削除したりしないので、やり過ぎかもしれません。 Collections.sortメソッドは、HashSet全体を取得し、結果を並べ替え、結果を生成したらすぐに並べ替えられたコレクションを破棄するようなインスタンスに適したソリューションです。
OK、これが私が思いついたものです。問題を解決すると思われ、fileIdで適切に並べられたFileオブジェクトを含む文字列を返します。
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が比較的新しい)ため、間違って実装した場合はフィードバックをお願いします。
配列に収集してソートしてから連結しないのはなぜですか?
-MarkusQ
values()CollectionをArrayListに追加し、Collections.sort()を使用して、カスタムComparatorインスタンスを繰り返し処理する前にソートする必要があります。
ところで、コレクションの要素ごとに1文字以上を追加するため、コレクションのサイズでStringBufferを初期化することは無意味です。
一時リストを作成してから、データの各ペアをリストに追加します。カスタムコンパレータに従ってCollections.sort()でソートすると、リストが希望の順序になります。
探しているメソッドは次のとおりです。 http://java.sun.com/javase/6/docs/api/java/util/Collections.html#sort(java.util.List 、%20java.util.Comparator)
一連のコレクションに追加される前に、LinkedHashMapを数十回作成しました。
おそらくやりたいことは、TreeHashMapコレクションを作成することです。
2番目のコレクションを作成し、両方に追加されたものを追加しても、実際にはサイズに影響はなく、両方のパフォーマンスが得られます(追加すると少し時間がかかります)。
新しいコレクションとしてそれを行うと、コードがクリーンで整頓されたままになります。コレクションクラスの長さは数行で、既存のハッシュマップを置き換えるだけです...
コレクションを常にラッピングする習慣を身に付けた場合、この機能は機能するだけで、思いもよらないことです。
StringBuffer allFilesString = new StringBuffer(fileCollection.size());
すべてのfile.toString()が平均して1文字でない限り、おそらくStringBufferが小さすぎます。 (正しくない場合は、設定せずにコードを単純にすることもできます)サイズの倍数にすると、より良い結果が得られる場合があります。さらに、StringBufferは同期されますが、StringBuilderは同期されないため、ここでより効率的になります。
不要な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);
}
});