¿Cómo puedo convertir una lista de listas en una lista en Java 8?

6 minutos de lectura

¿Como puedo convertir una lista de listas en una lista
Sara Szabo

si tengo un List<List<Object>>¿cómo puedo convertir eso en un List<Object> que contiene todos los objetos en el mismo orden de iteración usando las funciones de Java 8?

1646750536 173 ¿Como puedo convertir una lista de listas en una lista
Eran

Puedes usar flatMap para aplanar las listas internas (después de convertirlas en Streams) en un solo Stream y luego recopilar el resultado en una lista:

List<List<Object>> list = ...
List<Object> flat = 
    list.stream()
        .flatMap(List::stream)
        .collect(Collectors.toList());

  • @arshajii cierto, pero por alguna razón prefiero la expresión lambda. Tal vez no me gusta el aspecto de :: 🙂

    – Eran

    5 de agosto de 2014 a las 19:55

  • Class::method se siente un poco extraño al principio, pero tiene la ventaja de que declara de qué tipo de objeto se está mapeando. Eso es algo que de otro modo perderías en las transmisiones.

    – ArneHugo

    15 de marzo de 2016 a las 15:13

  • Sin embargo, es posible que desee tener un contenedor de una Lista y, en ese caso, es posible que deba usar la lambda (l->l.myList.stream()).

    – Mioquia

    22 de diciembre de 2016 a las 10:18

  • Si necesita hacer una conversión explícita (una matriz de primitivas a la Lista, por ejemplo), también puede ser necesario lambdas.

    –Michael Fulton

    28 de mayo de 2017 a las 3:58

  • funcionó para mí gracias

    –Mugeesh Husain

    14 de enero a las 3:48

¿Como puedo convertir una lista de listas en una lista
Saravana

flatmap es mejor pero hay otras formas de lograr lo mismo

List<List<Object>> listOfList = ... // fill

List<Object> collect = 
      listOfList.stream()
                .collect(ArrayList::new, List::addAll, List::addAll);

  • Tenga en cuenta que al usar flatMap no cerrará la transmisión, ya que con la recopilación deberá volver a abrirla.

    – Georgi Peev

    10 mayo 2021 a las 10:53

los flatMap método en Stream ciertamente puede aplanar esas listas para usted, pero debe crear Stream objetos por elemento, luego un Stream por el resultado

No necesitas todos esos Stream objetos. Aquí está el código simple y conciso para realizar la tarea.

// listOfLists is a List<List<Object>>.
List<Object> result = new ArrayList<>();
listOfLists.forEach(result::addAll);

Porque un List es Iterableeste código llama los forEach método (característica de Java 8), que se hereda de Iterable.

Realiza la acción dada para cada elemento del Iterable hasta que todos los elementos hayan sido procesados ​​o la acción arroje una excepción. Las acciones se realizan en el orden de iteración, si se especifica ese orden.

y un List‘s Iterator devuelve elementos en orden secuencial.

Para el Consumereste código pasa una referencia de método (característica de Java 8) al método anterior a Java 8 List.addAll para agregar los elementos de la lista interna secuencialmente.

Agrega todos los elementos de la colección especificada al final de esta lista, en el orden en que los devuelve el iterador de la colección especificada (operación opcional).

  • Buena sugerencia alternativa que evita algunas asignaciones innecesarias. Sería interesante ver el uso del montón superior de esto cuando se trabaja con algunas colecciones más grandes, para ver cómo se comparan entre sí.

    – Por Lundberg

    10 de julio de 2019 a las 12:51

1642890369 64 estatico vs Enlace dinamico en Java
Soudipta Dutta

Método para convertir un List<List> para List :

listOfLists.stream().flatMap(List::stream).collect(Collectors.toList());

Mira este ejemplo:

public class Example {

    public static void main(String[] args) {
        List<List<String>> listOfLists = Collections.singletonList(Arrays.asList("a", "b", "v"));
        List<String> list = listOfLists.stream().flatMap(List::stream).collect(Collectors.toList());

        System.out.println("listOfLists => " + listOfLists);
        System.out.println("list => " + list);
    }

}       

Imprime:

listOfLists => [[a, b, c]]
list => [a, b, c]

En Python, esto se puede hacer usando Comprensión de listas.

list_of_lists = [['Roopa','Roopi','Tabu', 'Soudipta'],[180.0, 1231, 2112, 3112], [130], [158.2], [220.2]]

flatten = [val for sublist in list_of_lists for val in sublist]

print(flatten)
['Roopa', 'Roopi', 'Tabu', 'Soudipta', 180.0, 1231, 2112, 3112, 130, 158.2, 220.2]

Tal como lo mencionó @Saravana:

flatmap es mejor pero hay otras formas de lograr lo mismo

 listStream.reduce(new ArrayList<>(), (l1, l2) -> {
        l1.addAll(l2);
        return l1;
 });

En resumen, hay varias formas de lograr lo mismo de la siguiente manera:

private <T> List<T> mergeOne(Stream<List<T>> listStream) {
    return listStream.flatMap(List::stream).collect(toList());
}

private <T> List<T> mergeTwo(Stream<List<T>> listStream) {
    List<T> result = new ArrayList<>();
    listStream.forEach(result::addAll);
    return result;
}

private <T> List<T> mergeThree(Stream<List<T>> listStream) {
    return listStream.reduce(new ArrayList<>(), (l1, l2) -> {
        l1.addAll(l2);
        return l1;
    });
}

private <T> List<T> mergeFour(Stream<List<T>> listStream) {
    return listStream.reduce((l1, l2) -> {
        List<T> l = new ArrayList<>(l1);
        l.addAll(l2);
        return l;
    }).orElse(new ArrayList<>());
}

private <T> List<T> mergeFive(Stream<List<T>> listStream) {
    return listStream.collect(ArrayList::new, List::addAll, List::addAll);
}

Solo quiero explicar un escenario más como List<Documents>esta lista contiene algunas listas más de otros documentos como List<Excel>, List<Word>, List<PowerPoint>. Entonces la estructura es

class A {
  List<Documents> documentList;
}

class Documents {
  List<Excel> excels;
  List<Word> words;
  List<PowerPoint> ppt;
}

Ahora, si desea iterar Excel solo desde documentos, haga algo como a continuación.

entonces el codigo seria

 List<Documents> documentList = new A().getDocumentList();

 //check documentList as not null

 Optional<Excel> excelOptional = documentList.stream()
                         .map(doc -> doc.getExcel())
                         .flatMap(List::stream).findFirst();
 if(excelOptional.isPresent()){
   Excel exl = optionalExcel.get();
   // now get the value what you want.
 }

Espero que esto pueda resolver el problema de alguien mientras codifica…

1646750538 346 ¿Como puedo convertir una lista de listas en una lista
Nikhil Nanivadekar

Puedes usar el flatCollect() patrón de Colecciones de Eclipse.

MutableList<List<Object>> list = Lists.mutable.empty();
MutableList<Object> flat = list.flatCollect(each -> each);

Si no puede cambiar la lista de List:

List<List<Object>> list = new ArrayList<>();
List<Object> flat = ListAdapter.adapt(list).flatCollect(each -> each);

Nota: Soy colaborador de Eclipse Collections.

  • ¿Por qué usar una dependencia de terceros cuando Java 8 proporciona la funcionalidad?

    – sierra303

    20 de octubre de 2017 a las 8:34

  • Eclipse Collections API está en la colección en sí, por lo que el código es conciso, es una de las razones principales en este caso.

    – Nikhil Nanivadekar

    21 oct 2017 a las 18:18

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad