How to Turn a List of Lists into a List in Java 8

How can I turn a List of Lists into a List in Java 8?

You can use flatMap to flatten the internal lists (after converting them to Streams) into a single Stream, and then collect the result into a list:

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

How to convert List of Lists to single List using Java8 streams

Use flatMap here, to not stream again. Just notice that this toMap assumes that there will be no duplicate keys (or nulls)

list.stream()
.filter(e -> subjectId.equals(e.getId()))
.flatMap(subject -> subject.getTopics().stream())
.collect(Collectors.toMap(Topic::getId, Topic::getName));

How to change a list of lists into a list

public List<LocalDateTime> getallsort(){
List<LocalDateTime> elite = getElite(true);
List<LocalDateTime> recreation = getRecreation(true);
List<LocalDateTime> youth = getYouth(true);
List<List<LocalDateTime>> list = Arrays.asList(elite,recreation,youth);
list.sort((xs1, xs2) -> xs1.size() - xs2.size());
return list.stream().flatMap(List::stream).collect(Collectors.toList());
}

which answers your original question about converting a List<List<>> into a flattened List<>.

Or even

public List<LocalDateTime> getallsort(){
return Stream.of(
getElite(true),
getRecreation(true),
getYouth(true)
)
.sorted((xs1, xs2) -> xs1.size() - xs2.size())
.flatMap(List::stream)
.collect(Collectors.toList());
}

which works for your original example, but maybe does not directly answer your question.

Rewriting the sort:

public List<LocalDateTime> getallsort(){
return Stream.of(
getElite(true),
getRecreation(true),
getYouth(true)
)
.sorted(comparingInt(List::size).reversed())
.flatMap(List::stream)
.collect(Collectors.toList());
}

Java 8: How to stream a list into a list of lists?

As mentioned in a comment, referring to a question that is very similar (in fact, I nearly considered it to be a duplicate...), the groupBy call comes in different flavors, and one of them allows passing in a factory for the map that is to be created.

So there is no need to explicitly wrap the result of the "simple" groupBy call into the creation of a new TreeMap, because you can create the TreeMap directly. This map (and its values() collection!) will be ordered by the key. The values of the map are lists, which are created using the downstream collector toList(), which explicitly says that it will collect the results in encounter order.

So the following should indeed be a simple, correct and efficient solution:

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.TreeMap;
import java.util.stream.Collectors;

public class CollectToListOfList {
static class Widget {
String code;
String name;

Widget(String code, String name) {
this.code = code;
this.name = name;
}

public String getCode() {
return code;
}

public String getName() {
return name;
}

@Override
public String toString() {
return code + ": " + name;
}

}

public static void main(String[] args) {
List<Widget> widgetList = Arrays.asList(
new Widget("0", "A"),
new Widget("1", "B"),
new Widget("2", "C"),
new Widget("3", "D"),
new Widget("0", "E"),
new Widget("1", "F"),
new Widget("2", "G"),
new Widget("3", "H"),
new Widget("0", "I"),
new Widget("1", "J"));

Collection<List<Widget>> result = widgetList.stream()
.collect(Collectors.groupingBy(Widget::getCode, TreeMap::new, Collectors.toList()))
.values();

for (List<Widget> list : result) {
System.out.println(list);
}

}
}

Convert List of List into list in java

Try like this using flatMap:

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

List of lists and Java 8

rList.stream().map(R::getP).flatMap(List::stream).forEach(result::addAll);

would work if you didn't use flatMap (since addAll requires a Collection, but flatMap transforms your Stream<List<P>> to a Stream<P>.

This would work:

rList.stream().map(R::getP).forEach(result::addAll);

With flatMap it should be:

rList.stream().map(R::getP).flatMap(List::stream).forEach(result::add);

That said, the correct way is to use collect:

List<P> result = rList.stream()
.map(R::getP)
.flatMap(List::stream)
.collect(Collectors.toList());

or

List<P> result = rList.stream()
.flatMap(r -> r.getP().stream())
.collect(Collectors.toList());

Java 8: How to turn a list into a list of lists using lambda

Try this approach:

static <T> List<List<T>> listSplitter(List<T> incoming, int size) {
// add validation if needed
return incoming.stream()
.collect(Collector.of(
ArrayList::new,
(accumulator, item) -> {
if(accumulator.isEmpty()) {
accumulator.add(new ArrayList<>(singletonList(item)));
} else {
List<T> last = accumulator.get(accumulator.size() - 1);
if(last.size() == size) {
accumulator.add(new ArrayList<>(singletonList(item)));
} else {
last.add(item);
}
}
},
(li1, li2) -> {
li1.addAll(li2);
return li1;
}
));
}
System.out.println(
listSplitter(
Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9),
4
)
);

Also note that this code could be optimized, instead of:

new ArrayList<>(Collections.singletonList(item))

use this one:

List<List<T>> newList = new ArrayList<>(size);
newList.add(item);
return newList;

Flattening a List of List to a List with Java 8 stream API

You require only a "simple" map here:

List<List<String>> listOfListValues;
public List<String> getAsFlattenedList() {
return listOfListValues.stream()
.map(String::valueOf)
.collect(toList());
}

flatMap is rather used to transform one Stream to another, which makes sense if you need more entries or less then currently available (or just a newly mapped Stream to filter/map/etc it further down), e.g.:

  • count all the unique strings of all lists:

    listOfListValues.stream()
    .flatMap(List::stream) // we want to count all, also those from the "inner" list...
    .distinct()
    .count()
  • truncate entries after a certain size:

    listOfListValues.stream()
    .flatMap(list -> {
    if (list.size() > 3) // in this case we use only some of the entries
    return Stream.concat(list.subList(0, 2).stream(), Stream.of("..."));
    else
    return list.stream();
    })
    .collect(Collectors.toList());
  • flattening values of a map for several interested keys:

    Map<Key, List<Value>> map = new HashMap<>();
    Stream<Value> valueStream = interestedKeys.stream()
    .map(map::get)
    .flatMap(List::stream);

Java Streams and List of List of List

You should use flatMap:

List<String> newList =
listA.stream() // Stream<A>
.flatMap(a->a.getB().stream()) // Stream<B>
.flatMap(b->b.getC().stream()) // Stream<C>
.flatMap(c->c.gtPeople().stream()) // Stream<String>
.collect(Collectors.toList()); // List<String>

3 ways to flatten a list of lists. Is there a reason to prefer one of them?

I'm not sure about the performance of each one, but an important aspect of the builder pattern utilized by java streams is that it allows for readability. I personally find the option 2 to be the most readable. Option 3 is good, too. I would avoid option one because it kind of "cheats" the flattening of the collection.

Put each method on its own line and determine which is the most intuitive to read. I rather like the second one:

final List<Double> B = list.stream()
.map(CoreResult::getField)
.flatMap(Collection::stream)
.collect(Collectors.toList());


Related Topics



Leave a reply



Submit