web-dev-qa-db-fra.com

Comment convertir une collection en liste?

J'utilise TreeBidiMap de la bibliothèque Apache Collections . Je veux trier ceci sur les valeurs qui sont doubles.

Ma méthode consiste à récupérer une Collection des valeurs en utilisant:

Collection coll = themap.values();

Ce qui fonctionne naturellement bien.

Question principale: Je veux maintenant savoir comment convertir/convertir (je ne sais pas ce qui est correct) coll en List afin qu'il puisse être trié?

J'ai ensuite l'intention d'itérer sur l'objet List trié, qui doit être en ordre et obtenir les clés appropriées de l'objet TreeBidiMap (_ [themap) à l'aide de themap.getKey(iterator.next()), où l'itérateur sera sur la liste de doubles.

264
Ankur
List list = new ArrayList(coll);
Collections.sort(list);

Comme Erel Segal Halevi indique ci-dessous, si coll est déjà une liste, vous pouvez ignorer la première étape. Mais cela dépend des éléments internes de TreeBidiMap.

List list;
if (coll instanceof List)
  list = (List)coll;
else
  list = new ArrayList(coll);
439
Paul Tomblin

Quelque chose comme ceci devrait fonctionner, en appelant le constructeur ArrayList qui prend une collection:

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

Je pense que la réponse de Paul Tomblin risque d’être inutile, au cas où coll serait déjà une liste, car cela créerait une nouvelle liste et copierait tous les éléments. Si coll contient plusieurs éléments, cela peut prendre beaucoup de temps.

Ma suggestion est:

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

Je crois que vous pouvez l'écrire comme tel:

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

@ Kunigami: Je pense que vous vous trompez peut-être sur la méthode newArrayList de Guava. Il ne vérifie pas si l'Iterable est un type de liste et renvoie simplement la liste donnée telle quelle. Il toujours crée une nouvelle liste:

@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

Ce que vous demandez est une opération assez coûteuse, assurez-vous de ne pas avoir à le faire souvent (par exemple, dans un cycle).

Sinon, vous pouvez créer une collection personnalisée. Je suis venu avec un qui a votre TreeBidiMap et TreeMultiset sous le capot. Mettez en œuvre uniquement ce dont vous avez besoin et veillez à l'intégrité des données.

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.
}

De cette façon, vous avez un triéMultiset renvoyé de values(). Toutefois, si vous avez besoin que ce soit une liste (par exemple, vous avez besoin de la méthode get(index) de type tableau), vous devrez inventer quelque chose de plus complexe.

1
Vlasec