¿Cómo convertir un mapa a una lista en Java?

675

¿Cuál es la mejor manera de convertir Map<key,value>a a List<value>? Simplemente repita todos los valores e insértelos en una lista o ¿estoy pasando por alto algo?

Javaa
fuente
1
Creo que no es un buen modelo si uno tiene que convertir el mapa en una lista. Uno debe escribir el código de tal manera que esta situación no llegue.
errores suceden el

Respuestas:

1299
List<Value> list = new ArrayList<Value>(map.values());

asumiendo:

Map<Key,Value> map;
cletus
fuente
77
¡Gracias! Estaba asumiendo que el elenco de Collectiona Listfuncionaría.
pide el
1
Sospecho que la razón por la que no funciona es porque la colección devuelta por los valores () depende del Mapa subyacente; al hacer una llamada de constructor de copia, asigna almacenamiento y copia los valores en ese almacenamiento, rompiendo así la conexión ...
Sheldon R.
44
Si tenemos LinkedHashMap, ¿el pedido será el mismo?
1
@ user2022068 sí, el pedido debe conservarse con LinkedHashMap.
SusanW
1
@SheldonR. sí: las colecciones devueltas por keySet()y values()generalmente son objetos de ajuste que proporcionan una vista de conjunto o colección de la estructura subyacente ( keySet()devuelve un conjunto para enfatizar que no hay engaños). Para values(), el objeto devuelto puede ser un List, pero a menudo no lo será. La creación de una Lista real, como usted dice, rompe el enlace, lo que significa que ya no depende del Mapa original. A veces sin embargo, sólo se necesita una lista debido a que algunos API requiere uno - el refuerzo de la regla de que una buena API debe requerir sólo las interfaces más abstractas que puede salirse con la suya ...
SusanW
137

El problema aquí es que Maptiene dos valores (una clave y un valor), mientras que un Listsolo tiene un valor (un elemento).

Por lo tanto, lo mejor que se puede hacer es obtener una Listde las claves o los valores. (A menos que hagamos un contenedor para mantener el par clave / valor).

Digamos que tenemos un Map:

Map<String, String> m = new HashMap<String, String>();
m.put("Hello", "World");
m.put("Apple", "3.14");
m.put("Another", "Element");

Las claves como a Listse pueden obtener creando una nueva a ArrayListpartir de una Setdevuelta por el Map.keySetmétodo:

List<String> list = new ArrayList<String>(m.keySet());

Si bien los valores como a Listse pueden obtener creando uno nuevo a ArrayListpartir de un método Collectiondevuelto Map.values:

List<String> list = new ArrayList<String>(m.values());

El resultado de obtener las Listclaves:

manzana
Otro
Hola

El resultado de obtener los Listvalores de:

3.14
Elemento
Mundo
Coobird
fuente
3
Cabe señalar que el orden de los valores devueltos por esos métodos no está definido y para implementaciones no HashMapclasificadas similares Mapserá efectivamente aleatorio.
Joachim Sauer
1
Sí, tendrías que saber que es un LinkedHashMap o algo por el estilo. El problema con la pregunta original es que la pregunta está mal expresada, es decir, necesita edición. La pregunta no es convertir un mapa en una lista, sino cómo obtener los valores del mapa como una lista. Los valores del método le dan una Colección, pero no una lista, y de ahí la necesidad de un pequeño truco.
demongolem
Creo que podría agregar a su respuesta lo que dice @ M0les: que de alguna manera necesitaría "pasar por" SortedMap. Comience con una implementación concreta de SortedMap (como TreeMap) o inserte su Mapa de entrada en un SortedMap antes de convertirlo en Lista
Ignacio Rubio
41

Usando la API de Java 8 Streams.

List<Value> values = map.values().stream().collect(Collectors.toList());
Matej Kormuth
fuente
8
Prefiero la respuesta aceptada, basada en el constructor. Las transmisiones deben ser para simplificar el código.
Aaron
1
@Aaron Sí, para la tarea de obtener una Lista de valores de Map, el constructor parece ser más simple. Sin embargo, si está utilizando Streams extensivamente en una base de código, es mejor mantenerse constante.
Matej Kormuth
1
cuando uso esto obtengo un error si estoy obteniendo una gran cantidad de datos ... el hilo se repite en java.util.stream.ReduceOps $ 3.makeSink (fuente desconocida). Si los hilos se repiten infinitamente, el consumo de CPU comenzará a aumentar. Los hilos de bucle de seguimiento de la pila se dan a continuación, examínelo
Ganesh Giri
24

map.entrySet()le ofrece una colección de Map.Entryobjetos que contienen clave y valor. luego puede transformar esto en cualquier objeto de colección que desee, como new ArrayList(map.entrySet());

java dude
fuente
23

una lista de que?

Asumiendo que mapes tu instancia deMap

  • map.values()devolverá un que Collectioncontiene todos los valores del mapa.
  • map.keySet()devolverá un que Setcontenga todas las claves del mapa.
Diego Amicabile
fuente
14

Supongo que quieres convertir los valores contenidos en el Mapalist ? Lo más fácil es llamar al values()método de la Mapinterfaz. Esto devolverá los Collectionobjetos de valor contenidos en el Map.

Tenga en cuenta que esto Collectionestá respaldado por el Mapobjeto y cualquier cambio en el Mapobjeto se reflejará aquí. Entonces, si desea una copia separada no vinculada a su Mapobjeto, simplemente cree un nuevo Listobjeto como ArrayListpasar el valor Collectioncomo se muestra a continuación.

ArrayList<String> list = new ArrayList<String>(map.values());
maneesh
fuente
6

Puedes hacerlo así

List<Value> list = new ArrayList<Value>(map.values());
usuario3752441
fuente
1
OP pregunta acerca de cómo convertir a List <value>. Cuando proporcione respuestas, es mejor incluir una buena descripción con la solución propuesta. Esta pregunta ya ha sido aceptada respondida.
HaveNoDisplayName
5

Si desea asegurarse de que los valores en la resultante List<Value>están en el orden de las claves de la entrada Map<Key, Value>, debe "ir a través de" de SortedMapalguna manera.

O bien comenzar con una concreta SortedMapaplicación (tal como TreeMap) o inserte su entrada Mapen una SortedMapantes de la conversión que a List. p.ej:

Map<Key,Value> map;
List<Value> list = new ArrayList<Value>( new TreeMap<Key Value>( map ));

De lo contrario, obtendrá el orden nativo que Mapproporciona la implementación, que a menudo puede ser algo diferente al orden de las teclas naturales (Pruebe Hashtableo ConcurrentHashMap, para variar).

M0les
fuente
5
    Map<String, Integer> map = new HashMap<String, Integer>();
    map.put("java", 20);
    map.put("C++", 45);

    Set <Entry<String, Integer>> set = map.entrySet();

    List<Entry<String, Integer>> list = new ArrayList<Entry<String, Integer>>(set);

podemos tener pares de clave y valor en la lista. También podemos obtener clave y valor usando Map.Entry iterando sobre la lista.

usuario11
fuente
4
// you can use this
List<Value> list = new ArrayList<Value>(map.values());

// or you may use 
List<Value> list = new ArrayList<Value>();
for (Map.Entry<String, String> entry : map.entrySet())
{
list.add(entry.getValue());    
}
saurabhgoyal795
fuente
1
"Map<String , String > map = new HapshMap<String , String>;
 map.add("one","java");
 map.add("two" ,"spring");
 Set<Entry<String,String>> set =  map.entrySet();
 List<Entry<String , String>> list = new ArrayList<Entry<String , String>>    (set);
 for(Entry<String , String> entry : list ) {
   System.out.println(entry.getKey());
   System.out.println(entry.getValue());
 } "
siva prasad
fuente
1

Aquí está el método genérico para obtener valores del mapa.

public static <T> List<T> ValueListFromMap(HashMap<String, T> map) {
    List<T> thingList = new ArrayList<>();

    for (Map.Entry<String, T> entry : map.entrySet()) {
        thingList.add(entry.getValue());
    }

    return thingList;
}
Hiral Pancholi
fuente
1
HashMap<Integer, List<String>> map = new HashMap<>(); 
List<String> list = new ArrayList<String>();
list.add("Java");
list.add("Primefaces");
list.add("JSF");
map.put(1,list);
if(map != null){
    return new ArrayList<String>((Collection<? extends String>) map.values());
}
Hakan Anlamaz
fuente