valores recorrer obtener example diccionario definicion declarar java arraylist collections hashmap

recorrer - map string string java



¿Por qué los valores de HashMap no se incluyen en la lista? (9)

Estoy poniendo valores en el hashmap que es de la forma,

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

Quiero crear una lista usando el método de mapa values() .

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

o

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

Sin embargo, arroja una excepción:

Excepción en el hilo "main" java.lang.ClassCastException:
java.util.HashMap $ Los valores no se pueden convertir en java.util.List

Pero me permite pasarlo a la creación de una lista:

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


TL; DR

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

Explicación

Debido a que HashMap#values() devuelve java.util.Collection<V> y no puede convertir una Collection en ArrayList , obtiene ClassCastException .

Sugeriría usar el constructor ArrayList(Collection<? extends V>) . Este constructor acepta un objeto que implementa Collection<? extends V> Collection<? extends V> como argumento. No obtendrá ClassCastException cuando pase el resultado de HashMap.values() esta manera:

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

Ir más allá en el código fuente de la API de Java

Valores de HashMap # (): compruebe el tipo de devolución en el origen y pregúntese: ¿puede un java.util.Collection insertarse en java.util.ArrayList ? No

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

ArrayList (Colección): verifica el tipo de argumento en la fuente. ¿Puede un método cuyo argumento es un súper tipo aceptar subtipo? Sí

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



Bueno, es porque tus valores son realmente un HashSet. Podría escribir un código como este para iterar sobre el conjunto:

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


Dudo la mejor respuesta seleccionada, donde dice: "Debido a que HashMap # values ​​() devuelve java.util.Collection y no se puede convertir una Collection en ArrayList, se obtiene ClassCastException".

No se debe a que Colección no se pueda convertir en ArrayList, la verdadera razón es que la Colección devuelta por HashMap.values ​​() está respaldada por la clase interna HashMap.Values. Y HashMap.Values ​​no es una súper clase de ArrayList.


Enfrenté el mismo problema, pero luego me di cuenta de que los valores () devuelven Collection y no List. Pero podemos instanciar una nueva ArrayList como esta:

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

Porque ArrayList tiene un constructor que puede tomar Collection como su argumento.


Es porque values() devuelve Collection que, de acuerdo con el código fuente de HashMap es de tipo AbstractCollection y, por lo tanto, no se puede convertir a List .

Puede instanciar ArrayList pasando su resultado values() porque el constructor ArrayList puede tomar Collection como su argumento.


La respuesta se puede encontrar leyendo el JavaDoc

El método values() devuelve una Collection

Asi que

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

Debiera ser

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

Todavía puede iterar sobre esta colección como lo haría con una lista.

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

Esto funciona:

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

Porque ArrayList tiene un constructor que acepta una colección.


Si ya ha creado una instancia de su subtipo List (por ejemplo, ArrayList, LinkedList), puede usar el método addAll.

p.ej,

valuesToMatch.addAll(myCollection)

Muchos subtipos de listas también pueden tomar la colección fuente en su constructor.


Values es una clase interna en la clase HashMap (ver $ symbol en java.util.HashMap$Values ).
El método HashMap.values ​​() devolverá el objeto de la clase Values que no está implementando la interfaz de la List . Lo mismo ClassCastException .
Aquí está la clase privada interna Values en HashMap que no está implementando la interfaz de List . Incluso AbstractCollection tampoco implementa la interfaz de List .
AbstractCollection implementa la interfaz de Collection . Por lo tanto, no se puede convertir a la 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(); } }

Actualizar

Lo siguiente es uno de los constructores en 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); }

El tipo de devolución del método hashmapObj.values() es Collection . Ahora, ¿qué clase está implementando esta interfaz de Colección? La respuesta es clase de Values que está dentro de la clase HashMap (clase interna). El valor devuelto de hashmapObj.values() se puede pasar al constructor ArrayList anterior, que es válido.

Incluso lo siguiente son declaraciones válidas.

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

Pero las siguientes declaraciones son incorrectas

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