web-dev-qa-db-fra.com

Performance: Création d'une ArrayList à partir de HashMap.values ​​()

La question est combien coûte la création d’une ArrayList à partir d’une collection HashMap.values ​​()? Ou créer les valeurs Collection uniquement? En supposant que Map.size ()> 100k. Les objets peuvent également être conservés dans ArrayList (au lieu de HashMap) tout le temps, ce qui a des implications dans d’autres parties (modifications de éléments, facile par la clé). Le ArrayList est utilisé pour parcourir chaque nième élément. (C'est pourquoi la collection de valeurs ne peut pas être utilisée directement). Aucune modification n'est faite pendant l'itération.

19
beginner_

HashMap.values() ne renvoie pas une ArrayList de valeurs mais une collection Values.

La source:

 public Collection<V> values() {
        Collection<V> vs = values;
        return (vs != null ? vs : (values = new Values()));
    }

Values est une AbstractCollection. La raison des valeurs est simplement de faire référence à l'itérateur de HashMap.

Ta question:

La question est de savoir combien il en coûte De créer une ArrayList à partir d’une collection HashMap.values ​​()?

C'est une complexité linéaire (comme l'a dit Bozho) depuis 

ArrayList<V> valuesList = new ArrayList<V>(hashMap.values());

arrayList, valuesList appelle la méthode collection hashMaptoArray() qui effectue essentiellement une boucle for à partir de l'élément 0..N (taille) de la collection.

J'espère que cela t'aides.

39
Buhake Sindi

HashMap stocke en interne les valeurs dans une collection values. Jetez un coup d’œil au code source de AbstractMap, le parent de HashMap.

Donc, HashMap.values() renvoie directement une Collection. Il n'y a pas de calcul ni de copie de données. C'est aussi rapide que possible.

Obtenez juste les valeurs puis faites une boucle for:

int n = 5;  // every 5th element
Object[] values = hashMap.values().toArray();
int size = values.length;
for (int i = 0; i < size; i += n){
   values[i];
   // do something
)
8
Peter Knego

Pour élaborer sur la solution de @ Bozho, vous pouvez simplement le faire.

int count = 0;
for(Value value: map.values())
   if(count++ % 5 == 0)
     // do something.
3
Peter Lawrey

Vous pouvez utiliser une Iterator pour ignorer des éléments - appelez simplement next() plusieurs fois.

Créer une liste de toutes les collections a une complexité linéaire.

2
Bozho

Vous pouvez créer votre propre HashMap, qui contient directement la collection de valeurs Arraylist (je ne crois pas que HashMap le fasse gratuitement, sa structure de données est différente). Mais cela nécessite un codage supplémentaire de votre part.

0
luckyluke