web-dev-qa-db-ja.com

コレクションをリストに変換する方法

私は Apache Collections ライブラリのTreeBidiMapを使っています。これをdoublesという値でソートしたいのです。

私の方法は、以下を使用して値のCollectionを取得することです。

Collection coll = themap.values();

これは自然にうまくいきます。

主な質問:collListに変換/キャストしてソートできるようにする方法を知りたいです。

次に、ソートされたListオブジェクトを順に処理し、themap.getKey(iterator.next())を使用してTreeBidiMapthemap)から適切なキーを取得します。ここで、反復子はdoublesのリストを対象とします。

257
Ankur
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);
433
Paul Tomblin

Collectionをとる ArrayListコンストラクタ を呼び出すことで、このようなことがうまくいくはずです。

List theList = new ArrayList(coll);
84
Jack Leow

Collがすでにリストになっている場合、Paul Tomblinの答えは無駄になるかもしれません。新しいリストを作成し、すべての要素をコピーするからです。 collに多数の要素が含まれている場合、これには長い時間がかかります。

私の提案は:

List list;
if (coll instanceof List)
  list = (List)coll;
else
  list = new ArrayList(coll);
Collections.sort(list);
32

私はあなたがそのように書くことができると思います:

coll.stream().collect(Collectors.toList())
14
Eyal Ofri
Collections.sort( new ArrayList( coll ) );
7
OscarRyz

國上: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());
}
4
Nathan Perrier

あなたが要求するものはかなり高価な操作です、あなたが(例えば、サイクルで)それを頻繁にする必要がないことを確認してください。

それ以外の場合は、カスタムコレクションを作成できます。私はあなたのTreeBidiMapTreeMultisetがボンネットの下にあるものを思いつきました。必要なものだけを実装し、データの完全性を気にしてください。

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)メソッドが必要な場合)、もっと複雑なものを発明する必要があります。

1
Vlasec