Warum werden HashMap-Werte nicht in die Liste umgewandelt?

Lesezeit: 3 Minuten

Benutzer-Avatar
bNd

Ich füge Werte in die Hashmap ein, die folgende Form hat:

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

Ich möchte eine Liste mit erstellen values() Methode der Karte.

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

oder

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

Es löst jedoch eine Ausnahme aus:

Ausnahme im Thread “main” java.lang.ClassCastException:
java.util.HashMap$Values ​​können nicht in java.util.List umgewandelt werden

Aber es erlaubt mir, es an die Erstellung einer Liste weiterzugeben:

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

  • Das values -Methode gibt eine Sammlung zurück, keine Liste.

    – Wahrnehmung

    20. März 2013 um 11:44 Uhr

Benutzer-Avatar
PermGenError

TL;DR

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

Erläuterung

Da HashMap#values() gibt a zurück java.util.Collection<V> und du kannst kein a wirken Collection In ein ArrayListso erhalten Sie ClassCastException.

Ich würde vorschlagen, zu verwenden ArrayList(Collection<? extends V>) Konstrukteur. Dieser Konstruktor akzeptiert ein Objekt, das implementiert Collection<? extends V> als Argument. Du wirst es nicht bekommen ClassCastException wenn Sie das Ergebnis übergeben HashMap.values() so was:

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

Gehen Sie weiter in den Java-API-Quellcode

HashMap#values(): Überprüfen Sie den Rückgabetyp in der Quelle und fragen Sie sich, ob a java.util.Collection eingegossen werden java.util.ArrayList? Nein

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

ArrayList(Sammlung): Überprüfen Sie den Argumenttyp in der Quelle. Kann eine Methode, deren Argument ein Supertyp ist, einen Subtyp akzeptieren? Ja

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

Die Antwort finden Sie im JavaDoc

Das values() Methode gibt a zurück Collection

So

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

Sollte sein

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

Sie können diese Sammlung immer noch wie eine Liste durchlaufen.

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


Das funktioniert:

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

Da ArrayList hat einen Konstruktor, der eine Auflistung akzeptiert.

Es ist, weil values() kehrt zurück Collection die laut Quellcode von HashMap ist vom Typ AbstractCollection und kann daher nicht gecastet werden List.

Sie können instanziieren ArrayList daran vorbei values() Ergebnis, weil ArrayList Konstrukteur nehmen kann Collection als sein Argument.

Wenn Sie bereits eine Instanz Ihres List-Untertyps (z. B. ArrayList, LinkedList) erstellt haben, können Sie die addAll-Methode verwenden.

z.B,

valuesToMatch.addAll(myCollection)

Viele Listenuntertypen können auch die Quellauflistung in ihrem Konstruktor aufnehmen.

Benutzer-Avatar
Abimaran Kugathasan

Haben Sie die API überprüft, was von zurückgegeben wird values() Methode? Und welche ArrayList Konstrukteur akzeptiert?

Benutzer-Avatar
Jyothirmayi Lalitha

Ich hatte das gleiche Problem, aber dann wurde mir klar, dass die values()-Rückgabesammlung und keine Liste ist. Aber wir können eine neue ArrayList wie folgt instanziieren:

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

Weil ArrayList einen Konstruktor hat, der Collection als Argument annehmen kann.

Benutzer-Avatar
Axarydax

Nun, es liegt daran, dass Ihre Werte wirklich ein HashSet sind. Sie könnten einen Code wie diesen schreiben, um über die Menge zu iterieren:

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

  • Nö, values() Methode gibt a zurück Collection und keySet() gibt a zurück Set. docs.oracle.com/javase/7/docs/api/java/util/HashMap.html

    – everton

    15. Januar 2014 um 12:06 Uhr


  • Sie fügen Elemente zu ArrayList über add hinzu, nicht über put, was für Set gilt.

    – Webcomer

    7. Oktober 2018 um 17:43 Uhr

1252590cookie-checkWarum werden HashMap-Werte nicht in die Liste umgewandelt?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy