Ich setze Werte in die Hashmap ein, die die 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 der values()
Methode der Karte erstellen .
List<Double> valuesToMatch=new ArrayList<>();
valuesToMatch=(List<Double>) highLowValueMap.values();
oder
List<Double> valuesToMatch=(List<Double>) highLowValueMap.values();
Es wird jedoch eine Ausnahme ausgelöst:
Ausnahme im Thread "main" java.lang.ClassCastException:
java.util.HashMap $ Werte 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());
values
Methode gibt eine Sammlung zurück, keine Liste.Antworten:
TL; DR
List<V> al = new ArrayList<V>(hashMapVar.values());
Erläuterung
Weil a
HashMap#values()
zurückgibtjava.util.Collection<V>
und man a nichtCollection
in ein werfen kannArrayList
, bekommt manClassCastException
.Ich würde vorschlagen,
ArrayList(Collection<? extends V>)
Konstruktor zu verwenden. Dieser Konstruktor akzeptiert ein Objekt, dasCollection<? extends V>
als Argument implementiert wird . Sie werden nicht bekommen,ClassCastException
wenn Sie das ErgebnisHashMap.values()
wie folgt bestehen :List<V> al = new ArrayList<V>(hashMapVar.values());
Gehen Sie weiter in den Java API-Quellcode ein
HashMap # values (): Überprüfen Sie den Rückgabetyp in der Quelle und fragen Sie sich, ob ein
java.util.Collection
Casting möglich istjava.util.ArrayList
. Neinpublic Collection<V> values() { Collection<V> vs = values; return (vs != null ? vs : (values = new Values())); }
ArrayList (Collection): Überprüfen Sie den Argumenttyp in der Quelle. Kann eine Methode, deren Argument ein Supertyp ist, einen Untertyp 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); }
quelle
Die Antwort finden Sie im JavaDoc
Die
values()
Methode gibt a zurückCollection
Damit
Sollte sein
Sie können diese Sammlung weiterhin 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() );
Weil
ArrayList
hat einen Konstruktor, der eine Sammlung akzeptiert.quelle
Dies liegt daran, dass
values()
Rückgaben,Collection
die laut QuellcodeHashMap
vom Typ sindAbstractCollection
und daher nicht umgewandelt werden könnenList
.Sie können das
ArrayList
Übergeben desvalues()
Ergebnisses instanziieren , da derArrayList
Konstruktor diesCollection
als Argument verwenden kann.quelle
Wenn Sie bereits eine Instanz Ihres List-Subtyps erstellt haben (z. B. ArrayList, LinkedList), können Sie die addAll-Methode verwenden.
z.B,
Viele Listensubtypen können auch die Quellensammlung in ihren Konstruktor übernehmen.
quelle
Haben Sie die API überprüft, was von der
values()
Methode zurückgegeben wird? Und welcher ArrayList- Konstruktor akzeptiert?quelle
Ich hatte das gleiche Problem, aber dann wurde mir klar, dass die Werte () Collection zurückgeben und keine Liste. Wir können jedoch eine neue ArrayList wie folgt instanziieren:
List valuesToMatch = new ArrayList (highLowValueMap.values ());
Weil ArrayList einen Konstruktor hat, der Collection als Argument verwenden kann.
quelle
Das 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); }
quelle
values()
Methode gibt aCollection
und akeySet()
zurückSet
. docs.oracle.com/javase/7/docs/api/java/util/HashMap.htmlValues
ist eine innere Klasse in derHashMap
Klasse (siehe $ symbol injava.util.HashMap$Values
).Die HashMap.values () -Methode gibt
Values
das Objekt der Klasse zurück, das keineList
Schnittstelle implementiert . So ist dasClassCastException
.Hier ist die
Values
innere private Klasse in HashMap, die keineList
Schnittstelle implementiert . Auch AbstractCollection implementiert keineList
Schnittstelle.AbstractCollection
implementiertCollection
Schnittstelle. Also nicht in der Lage zu besetzenList
.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(); } }
Aktualisieren
Das Folgende ist einer der Konstruktoren in 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); }
Der
hashmapObj.values()
Methodenrückgabetyp ist alsoCollection
. Welche Klasse implementiert nun diese Collection-Schnittstelle? Die Antwort ist eineValues
Klasse, die sich innerhalb der HashMap-Klasse (innere Klasse) befindet. Der zurückgegebene Wert vonhashmapObj.values()
kann an den obigen ArrayList-Konstruktor übergeben werden, der gültig ist.Auch das Folgende ist gültige Aussagen.
HashMap<String, String> map = new HashMap<String, String>(); Collection c = map.values();
Die folgenden Aussagen sind jedoch falsch
HashMap<String, String> map = new HashMap<String, String>(); List c = map.values(); //compilation error.. return type is not List
quelle
Collection<String> c = new ArrayList<>();
, konnte aber nichtvalues()
auf diesen Typ oder sogar auf diesen Typ umsteigenList
.Ich bezweifle die ausgewählte beste Antwort, in der es heißt: "Da HashMap # values () eine java.util.Collection zurückgibt und Sie eine Sammlung nicht in eine ArrayList umwandeln können, erhalten Sie ClassCastException."
Dies liegt nicht daran, dass Collection nicht in ArrayList umgewandelt werden kann, sondern daran, dass die von HashMap.values () zurückgegebene Collection von der inneren Klasse HashMap.Values gesichert wird. Und HashMap.Values ist keine Superklasse von ArrayList.
quelle