7

The following code (written in Kotlin) extracts the elements from a list of lists. It works, but looks rather ugly and difficult to read.

Is there a nicer way to write the same with the java stream api? (Examples can be given in Kotlin or Java)

val listOfLists: List<Any> = ...
val outList: MutableList<Any> = mutableListOf()

listOfLists.forEach {
    list ->
    if (list is ArrayList<*>) list.forEach {
        l ->
        outList.add(l)
    }
}

return outList;
Grzegorz Piwowarek
  • 13,172
  • 8
  • 62
  • 93
Fabian
  • 1,982
  • 4
  • 25
  • 35

3 Answers3

18

In Kotlin it's super easy without any excessive boilerplate:

val listOfLists: List<List<String>> = listOf()

val flattened: List<String> = listOfLists.flatten()

flatten() is the same as doing flatMap { it }


In Java, you need to utilize Stream API:

List<String> flattened = listOfLists.stream()
  .flatMap(List::stream)
  .collect(Collectors.toList());

You can also use Stream API in Kotlin:

val flattened: List<String> = listOfLists.stream()
  .flatMap { it.stream() }
  .collect(Collectors.toList())
Grzegorz Piwowarek
  • 13,172
  • 8
  • 62
  • 93
8

You could flatMap each list:

List<List<Object>> listOfLists = ...;
List<Object> flatList = 
    listOfLists.stream().flatMap(List::stream).collect(Collectors.toList());
Mureinik
  • 297,002
  • 52
  • 306
  • 350
1

Use flatMap

  List<Integer> extractedList = listOfLists.stream().flatMap(Collection::stream).collect(Collectors.toList());

flatMap() creates a stream out of each list in listOfLists. collect() collects the stream elements into a list.

rohit
  • 96
  • 1
  • 6