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
.
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);
Quelque chose comme ceci devrait fonctionner, en appelant le constructeur ArrayList qui prend une collection:
List theList = new ArrayList(coll);
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);
Je crois que vous pouvez l'écrire comme tel:
coll.stream().collect(Collectors.toList())
Collections.sort( new ArrayList( coll ) );
@ 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());
}
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.