私は Apache Collections ライブラリのTreeBidiMap
を使っています。これをdoubles
という値でソートしたいのです。
私の方法は、以下を使用して値のCollection
を取得することです。
Collection coll = themap.values();
これは自然にうまくいきます。
主な質問:coll
をList
に変換/キャストしてソートできるようにする方法を知りたいです。
次に、ソートされたList
オブジェクトを順に処理し、themap.getKey(iterator.next())
を使用してTreeBidiMap
(themap
)から適切なキーを取得します。ここで、反復子はdoubles
のリストを対象とします。
List list = new ArrayList(coll);
Collections.sort(list);
Erel Segal Haleviが後述するように、collがすでにリストになっている場合は、ステップ1をスキップできます。しかし、それはTreeBidiMapの内部に依存します。
List list;
if (coll instanceof List)
list = (List)coll;
else
list = new ArrayList(coll);
Collectionをとる ArrayListコンストラクタ を呼び出すことで、このようなことがうまくいくはずです。
List theList = new ArrayList(coll);
Collがすでにリストになっている場合、Paul Tomblinの答えは無駄になるかもしれません。新しいリストを作成し、すべての要素をコピーするからです。 collに多数の要素が含まれている場合、これには長い時間がかかります。
私の提案は:
List list;
if (coll instanceof List)
list = (List)coll;
else
list = new ArrayList(coll);
Collections.sort(list);
私はあなたがそのように書くことができると思います:
coll.stream().collect(Collectors.toList())
Collections.sort( new ArrayList( coll ) );
國上:GuavaのnewArrayList
メソッドを間違えたのではないでしょうか。 IterableがList型かどうかはチェックせず、指定されたListをそのまま返します。それは常に新しいリストを作成します。
@GwtCompatible(serializable = true)
public static <E> ArrayList<E> newArrayList(Iterable<? extends E> elements) {
checkNotNull(elements); // for GWT
// Let ArrayList's sizing logic work, if possible
return (elements instanceof Collection)
? new ArrayList<E>(Collections2.cast(elements))
: newArrayList(elements.iterator());
}
あなたが要求するものはかなり高価な操作です、あなたが(例えば、サイクルで)それを頻繁にする必要がないことを確認してください。
それ以外の場合は、カスタムコレクションを作成できます。私はあなたのTreeBidiMap
とTreeMultiset
がボンネットの下にあるものを思いつきました。必要なものだけを実装し、データの完全性を気にしてください。
class MyCustomCollection implements Map<K, V> {
TreeBidiMap<K, V> map;
TreeMultiset<V> multiset;
public V put(K key, V value) {
removeValue(map.put(key, value));
multiset.add(value);
}
public boolean remove(K key) {
removeValue(map.remove(key));
}
/** removes value that was removed/replaced in map */
private removeValue(V value) {
if (value != null) {
multiset.remove(value);
}
}
public Set keySet() {
return map.keySet();
}
public Multiset values() {
return multiset;
}
// many more methods to be implemented, e.g. count, isEmpty etc.
}
このようにして、values()
からソート済みのMultiset
が返されます。ただし、リストにする必要がある場合(たとえば、配列に似たget(index)
メソッドが必要な場合)、もっと複雑なものを発明する必要があります。