如果我有一个List<List<Object>>,我如何使用Java8的特性将其转换为包含相同迭代顺序的所有对象的List<Object>?
当前回答
扩展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语句。
其他回答
我们可以使用flatmap,请参考以下代码:
List<Integer> i1= Arrays.asList(1, 2, 3, 4);
List<Integer> i2= Arrays.asList(5, 6, 7, 8);
List<List<Integer>> ii= Arrays.asList(i1, i2);
System.out.println("List<List<Integer>>"+ii);
List<Integer> flat=ii.stream().flatMap(l-> l.stream()).collect(Collectors.toList());
System.out.println("Flattened to List<Integer>"+flat);
您可以使用flatMap将内部列表(在将其转换为流之后)展平为单个流,然后将结果收集到列表中:
List<List<Object>> list = ...
List<Object> flat =
list.stream()
.flatMap(List::stream)
.collect(Collectors.toList());
正如@Saravana提到的:
flatmap更好,但也有其他方法可以实现
listStream.reduce(new ArrayList<>(), (l1, l2) -> {
l1.addAll(l2);
return l1;
});
综上所述,有以下几种方法可以实现这一点:
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);
}
以下代码应有效:-
List<Object> result = new ArrayList<>();
listOfLists.forEach(result::addAll);
将List<List>转换为List的方法:
listOfLists.stream().flatMap(List::stream).collect(Collectors.toList());
请参见以下示例:
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);
}
}
它打印:
listOfLists => [[a, b, c]]
list => [a, b, c]
在Python中,这可以使用列表理解来完成。
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]
推荐文章
- Java中枚举的命名:单数还是复数?
- JavaBean和POJO之间的区别是什么?
- 注释在Java中如何使用,在哪里使用?
- 如何在Ubuntu下安装JDK 11 ?
- Spring Boot -无法确定数据库类型为NONE的嵌入式数据库驱动程序类
- 如何转换/解析从字符串到字符在java?
- 如何在Android中动态更改菜单项文本
- 如何比较两个没有时间部分的日期?
- 有没有一种方法可以获得Rails应用程序中所有模型的集合?
- 如何在Java中找到给定类的所有子类?
- 匿名类的访问构造函数
- 从Java访问Kotlin扩展函数
- 解析LocalDateTime时无法从TemporalAccessor获取LocalDateTime (Java 8)
- 以AM/PM的12小时格式显示当前时间
- 求两个集合的差值