如果我有一个List<List<Object>>,我如何使用Java8的特性将其转换为包含相同迭代顺序的所有对象的List<Object>?


当前回答

您可以使用Eclipse集合中的flatCollect()模式。

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

如果无法从列表中更改列表:

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

注意:我是Eclipse集合的贡献者。

其他回答

您可以使用flatMap将内部列表(在将其转换为流之后)展平为单个流,然后将结果收集到列表中:

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

您可以使用Eclipse集合中的flatCollect()模式。

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

如果无法从列表中更改列表:

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

注意:我是Eclipse集合的贡献者。

从java-16开始,您可以使用Stream#mapMulti

List<Object> result = listOfLists.stream()
                                 .mapMulti((List<Object> list, Consumer<Object> consumer) -> {
                                     list.forEach(consumer::accept);
                                 })
                                 .collect(Collectors.toList());

如果您需要一个不可变的List,您甚至可以使用toList()作为终端操作

List<Object> result = listOfLists.stream()
                                 .mapMulti((List<Object> list, Consumer<Object> consumer) -> {
                                     list.forEach(consumer::accept);
                                 })
                                 .toList();

以下代码应有效:-

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

扩展Eran的答案,这是最重要的答案,如果你有一堆层次的列表,你可以保持它们的平面映射。

如果需要的话,这还提供了一种方便的过滤方法,可以在你深入图层时进行过滤。

例如:

List<List<List<List<List<List<Object>>>>>> multiLayeredList = ...

List<Object> objectList = multiLayeredList
    .stream()
    .flatmap(someList1 -> someList1
        .stream()
        .filter(...Optional...))
    .flatmap(someList2 -> someList2
        .stream()
        .filter(...Optional...))
    .flatmap(someList3 -> someList3
        .stream()
        .filter(...Optional...))
    ...
    .collect(Collectors.toList())

这在SQL中类似于在SELECT语句中包含SELECT语句。