Sar*_*abo 470 java collections java-8
如果我有一个List<List<Object>>
,我如何List<Object>
通过使用Java 8的功能将其转换为包含相同迭代顺序中的所有对象?
Era*_*ran 857
您可以使用flatMap
内部列表(将它们转换为Streams后)展平为单个Stream,然后将结果收集到列表中:
List<List<Object>> list = ...
List<Object> flat =
list.stream()
.flatMap(List::stream)
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
Sou*_*tta 64
List<List>
将 a 转换为 的方法List
:
listOfLists.stream().flatMap(List::stream).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
看这个例子:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
它打印:
listOfLists => [[a, b, c]]
list => [a, b, c]
Run Code Online (Sandbox Code Playgroud)
在 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)
Run Code Online (Sandbox Code Playgroud)
['Roopa', 'Roopi', 'Tabu', 'Soudipta', 180.0, 1231, 2112, 3112, 130, 158.2, 220.2]
Run Code Online (Sandbox Code Playgroud)
Sar*_*ana 43
flatmap
更好,但还有其他方法来实现同样的目标
List<List<Object>> listOfList = ... // fill
List<Object> collect =
listOfList.stream()
.collect(ArrayList::new, List::addAll, List::addAll);
Run Code Online (Sandbox Code Playgroud)
rge*_*man 23
该flatMap
方法上Stream
肯定可以拼合那些列出了你,但它必须创建Stream
的元素对象,那么Stream
该结果.
您不需要所有这些Stream
对象.这是执行任务的简单,简洁的代码.
// listOfLists is a List<List<Object>>.
List<Object> result = new ArrayList<>();
listOfLists.forEach(result::addAll);
Run Code Online (Sandbox Code Playgroud)
由于List
是Iterable
,这个代码调用的forEach
方法(爪哇8功能),它是从继承Iterable
.
对每个元素执行给定操作,
Iterable
直到处理完所有元素或操作引发异常.如果指定了该顺序,则按迭代顺序执行操作.
和List
的Iterator
返回顺序的项目.
对于Consumer
此代码,此代码将方法引用(Java 8功能)传递给Java 8之前的方法,List.addAll
以按顺序添加内部列表元素.
将指定集合中的所有元素按指定集合的迭代器(可选操作)返回的顺序追加到此列表的末尾.
Nik*_*kar 12
您可以使用Eclipse Collections中的flatCollect()
模式.
MutableList<List<Object>> list = Lists.mutable.empty();
MutableList<Object> flat = list.flatCollect(each -> each);
Run Code Online (Sandbox Code Playgroud)
如果您无法更改列表List
:
List<List<Object>> list = new ArrayList<>();
List<Object> flat = ListAdapter.adapt(list).flatCollect(each -> each);
Run Code Online (Sandbox Code Playgroud)
注意:我是Eclipse Collections的贡献者.
就像@Saravana提到的那样:
平面图更好,但还有其他方法可以实现相同的效果
listStream.reduce(new ArrayList<>(), (l1, l2) -> {
l1.addAll(l2);
return l1;
});
Run Code Online (Sandbox Code Playgroud)
总结起来,有几种方法可以达到以下目的:
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);
}
Run Code Online (Sandbox Code Playgroud)
我只是想说明一个更喜欢的场景List<Documents>
,这个列表中包含像其他文件的几个表List<Excel>
,List<Word>
,List<PowerPoint>
。所以结构是
class A {
List<Documents> documentList;
}
class Documents {
List<Excel> excels;
List<Word> words;
List<PowerPoint> ppt;
}
Run Code Online (Sandbox Code Playgroud)
现在,如果您只想从文档中迭代Excel,请执行以下操作。
所以代码是
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.
}
Run Code Online (Sandbox Code Playgroud)
我希望这可以解决编码时某人的问题...
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())
Run Code Online (Sandbox Code Playgroud)
这在 SQL 中类似于在 SELECT 语句中包含 SELECT 语句。
归档时间: |
|
查看次数: |
243193 次 |
最近记录: |