public Collection<V> values() {
if (values == null) {
values = new AbstractCollection<V>() {
public Iterator<V> iterator() {
return new Iterator<V>() {
private Iterator<Entry<K,V>> i = entrySet().iterator();
public boolean hasNext() {
return i.hasNext();
}
public V next() {
return i.next().getValue();
}
public void remove() {
i.remove();
}
};
}
public int size() {
return AbstractMap.this.size();
}
public boolean isEmpty() {
return AbstractMap.this.isEmpty();
}
public void clear() {
AbstractMap.this.clear();
}
public boolean contains(Object v) {
return AbstractMap.this.containsValue(v);
}
};
}
return values;
}
3 Réponses :
Je ne sais pas quelle version de Java vous utilisez, mais je ne vois pas d'instance de classe abstraite renvoyée par values () . Il renvoie une instance de TreeMap.Values , qui est une classe qui étend AbstractCollection .
Quant à savoir pourquoi il ne renvoie pas un Set - c'est simplement dû au fait que la collection de valeurs peut contenir des doublons, ce qu'un Set ne permet pas .
Une Liste n'est pas non plus idéale, car elle impliquerait que les valeurs sont ordonnées, ce qui n'est pas vrai pour toutes les implémentations de Map (telles que HashMap code>).
BTW, au lieu d'imprimer des choses comme map.values () instanceof Set , vous auriez pu simplement imprimer map.value (). getClass (). getName () pour voir la classe d'implémentation réelle.
Cela vient de java8 .
Une raison simplement en regardant l'implémentation: contains et iterator regardent tous les deux le contenu actuel de la carte par opposition au contenu de la carte lorsque values () a été appelée.
Si vous appelez values () puis modifiez quelque chose dans la carte, ce changement sera reflété dans la Collection renvoyée à l'origine depuis values().
Map<String, String> map = new HashMap<String, String>();
map.put("some", "thing");
Collection<String> values = map.values();
System.out.println(values.size()); // 1
map.put("foo", "bar");
System.out.println(values.size()); // 2
Hashset utilise HashMap en interne, il n'y a donc pas beaucoup de copie des valeurs dans le scénario.
Vous pouvez voir le lien associé pour en savoir plus. Lien de référence .
d'où vient la collection abstraite, voici quelques informations connexes extraites de Java Doc:
1] Cette classe fournit une implémentation squelettique de la Collection interface, afin de minimiser l'effort requis pour implémenter cette interface.
2] Pour implémenter une collection non modifiable, le programmeur n'a qu'à
étendre cette classe et fournir des implémentations pour le iterator et
Méthodes size . (L'itérateur renvoyé par le iterator
La méthode doit implémenter hasNext et next .
3] Pour implémenter une collection modifiable, le programmeur doit en plus
écraser la méthode add de cette classe (qui
UnsupportedOperationException ) et l'itérateur renvoyé par le
La méthode iterator doit en plus implémenter son remove
méthode.
J'espère que cela vous a été utile.
De cette façon, la représentation interne est rendue accessible sans avoir à copier la carte / l'ensemble dans une nouvelle collection ou à vous rendre dépendant des détails d'implémentation.