91 votes

Pourquoi les valeurs de HashMap ne sont-elles pas converties en listes ?

Je mets des valeurs dans le hashmap qui est de la forme,

Map<Long, Double> highLowValueMap=new HashMap<Long, Double>();
highLowValueMap.put(1l, 10.0);
highLowValueMap.put(2l, 20.0);

Je veux créer une liste en utilisant values() de la carte.

List<Double> valuesToMatch=new ArrayList<>();
valuesToMatch=(List<Double>) highLowValueMap.values();

ou

List<Double> valuesToMatch=(List<Double>) highLowValueMap.values();

Cependant, une exception est levée :

Exception dans le thread "main" java.lang.ClassCastException :
java.util.HashMap$Values ne peut pas être casté en java.util.List

Mais il me permet de l'intégrer dans la création d'une liste :

List<Double> valuesToMatch  = new ArrayList<Double>( highLowValueMap.values());

2voto

J'ai rencontré le même problème, mais je me suis rendu compte que values() renvoie une collection et non une liste. Mais nous sommes en mesure d'instancier un nouveau ArrayList comme ceci :

Liste valuesToMatch = new ArrayList(highLowValueMap.values()) ;

Parce que ArrayList a un constructeur qui peut prendre Collection comme argument.

1voto

Axarydax Points 7787

C'est parce que vos valeurs sont en réalité des HashSet. Vous pourriez écrire un code comme celui-ci pour itérer sur l'ensemble :

List<Double> valuesToMatch=new ArrayList<>();
for(Double d : highLowValueMap.values(){
  valuesToMatch.put(d);
}

1voto

AmitG Points 2060

Values est une classe interne dans HashMap (voir le symbole $ dans java.util.HashMap$Values ).
La méthode HashMap.values() renverra Values l'objet de la classe qui n'implémente pas List l'interface. Il en va de même pour l'interface ClassCastException .
Voici le Values classe privée interne dans HashMap qui n'implémente pas List l'interface. Même AbstractCollection n'implémente pas non plus l'interface List l'interface.
AbstractCollection met en œuvre Collection l'interface. Il n'est donc pas possible d'effectuer un casting vers List .

private final class Values extends AbstractCollection<V> {
        public Iterator<V> iterator() {
            return newValueIterator();
        }
        public int size() {
            return size;
        }
        public boolean contains(Object o) {
            return containsValue(o);
        }
        public void clear() {
            HashMap.this.clear();
        }
    }

Mise à jour

Voici l'un des constructeurs d'ArrayList.

public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();
        size = elementData.length;
        // c.toArray might (incorrectly) not return Object[] (see 6260652)
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, size, Object[].class);
    }

Donc hashmapObj.values() Le type de retour de la méthode est Collection . Quelle est la classe qui implémente l'interface Collection ? La réponse est Values qui se trouve à l'intérieur de la classe HashMap (classe interne). La valeur renvoyée par hashmapObj.values() peut être passé au constructeur ArrayList ci-dessus, ce qui est valide.

Même les déclarations suivantes sont valables.

HashMap<String, String> map  = new HashMap<String, String>();
Collection c = map.values();

Mais les affirmations suivantes sont incorrectes

HashMap<String, String> map  = new HashMap<String, String>();
List c = map.values(); //compilation error.. return type is not List

1voto

Jin Points 11

Je doute de la meilleure réponse sélectionnée, où il est dit : "Parce que HashMap#values() renvoie une java.util.Collection et que l'on ne peut pas transformer une Collection en liste de tableaux, ce qui entraîne une ClassCastException."

Ce n'est pas parce que Collection ne peut pas être casté en ArrayList, la vraie raison est que la Collection retournée par HashMap.values() est soutenue par la classe interne HashMap.Values. Et HashMap.Values n'est pas une super classe de ArrayList.

-1voto

IT Developers Points 63

Pour convertir les valeurs d'une instance de carte en liste, vous pouvez utiliser la méthode suivante Iterable<T>.map

val yourList: List<Any> = #Map.values.map { it }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X