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());

159voto

PermGenError Points 26936

TL;DR

List<V> al = new ArrayList<V>(hashMapVar.values());

Explication

Parce que HashMap#values() renvoie un java.util.Collection<V> et vous ne pouvez pas lancer un Collection en un ArrayList On obtient donc ClassCastException .

Je suggère d'utiliser ArrayList(Collection<? extends V>) constructeur. Ce constructeur accepte un objet qui implémente la norme Collection<? extends V> comme argument. Vous n'obtiendrez pas ClassCastException lorsque vous transmettez le résultat de HashMap.values() comme ceci :

List<V> al = new ArrayList<V>(hashMapVar.values());

Aller plus loin dans le code source de l'API Java

HashMap#values() : Vérifiez le type de retour dans la source, et demandez-vous si un java.util.Collection être jeté dans java.util.ArrayList ? Non

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

ArrayList(Collection) : Vérifier le type d'argument dans la source. Une méthode dont l'argument est un super type peut-elle accepter un sous type ? Oui

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);
}

27voto

cowls Points 10489

La réponse peut être trouvée en lisant la JavaDoc

Les values() renvoie un Collection

Donc

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

Devrait être

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

Vous pouvez toujours itérer sur cette collection comme vous le feriez sur une liste.

http://docs.oracle.com/javase/6/docs/api/java/util/HashMap.html#values%28%29


Cela fonctionne :

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

Parce que ArrayList possède un constructeur qui accepte une collection.

6voto

Andrew Logvinov Points 7291

C'est parce que values() retours Collection qui, selon le code source de HashMap est du type AbstractCollection et ne peut donc pas être injecté dans List .

Vous êtes en mesure d'instancier ArrayList le transmettre values() résultat parce que ArrayList peut prendre Collection comme argument.

5voto

Si vous avez déjà créé une instance de votre sous-type List (par exemple, ArrayList, LinkedList), vous pouvez utiliser la méthode addAll.

par exemple,

valuesToMatch.addAll(myCollection)

De nombreux sous-types de listes peuvent également prendre la collection source dans leur constructeur.

2voto

Abimaran Kugathasan Points 12318

Avez-vous vérifié l'API, ce qui est retourné par values() méthode ? Et quelle liste de tableaux (ArrayList) constructeur accepte ?

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