回答:
を使用flatMap
して、内部リストを(ストリームに変換した後)単一のストリームにフラット化し、結果をリストに収集します。
List<List<Object>> list = ...
List<Object> flat =
list.stream()
.flatMap(List::stream)
.collect(Collectors.toList());
Class::method
最初は少し変な感じがしますが、マッピング元のオブジェクトの種類を宣言するという利点があります。そうでなければ、ストリームで失うものです。
flatMap
上の方法Stream
缶は確かにあなたのためのこれらのリストを平らにしますが、作成する必要がありStream
、その後、要素のオブジェクトをStream
結果のために。
これらすべてのStream
オブジェクトは必要ありません。これは、タスクを実行するためのシンプルで簡潔なコードです。
// listOfLists is a List<List<Object>>.
List<Object> result = new ArrayList<>();
listOfLists.forEach(result::addAll);
a List
はIterable
であるため、このコードはから継承されたforEach
メソッド(Java 8機能)を呼び出しますIterable
。
Iterable
すべての要素が処理されるか、アクションが例外をスローするまで、の各要素に対して指定されたアクションを実行します。アクションは、その順序が指定されている場合、反復の順序で実行されます。
また、List
' Iterator
はアイテムを順番に返します。
の場合Consumer
、このコードはメソッド参照(Java 8機能)をJava 8より前のメソッドに渡してList.addAll
、内部リスト要素を順番に追加します。
指定されたコレクションのすべての要素を、指定されたコレクションの反復子によって返される順序でこのリストの末尾に追加します(オプションの操作)。
EclipseコレクションのflatCollect()
パターンを使用できます。
MutableList<List<Object>> list = Lists.mutable.empty();
MutableList<Object> flat = list.flatCollect(each -> each);
リストをから変更できない場合List
:
List<List<Object>> list = new ArrayList<>();
List<Object> flat = ListAdapter.adapt(list).flatCollect(each -> each);
注:私はEclipseコレクションの寄稿者です。
@サラバナが述べたように:
フラットマップの方が良いですが、同じことを達成する他の方法があります
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);
}
私はちょうど1つのより多くのシナリオのように説明したいList<Documents>
、このリストのような他の文書のいくつかのより多くのリストが含まれていますList<Excel>
、List<Word>
、List<PowerPoint>
。したがって、構造は
class A {
List<Documents> documentList;
}
class Documents {
List<Excel> excels;
List<Word> words;
List<PowerPoint> ppt;
}
ドキュメントからのみ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.
}
これがコーディング中に誰かの問題を解決できることを願っています...
これにはフラットマップを使用できます。以下のコードを参照してください:
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);
トップの回答であったエランの回答の拡張。リストの層がたくさんある場合は、それらをフラットマッピングし続けることができます。
これには、必要に応じてレイヤーを下に移動するときにも便利なフィルタリング方法が付属しています。
だから例えば:
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ステートメントを含めるのと似ています。
a 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]
::
:) の見た目が好きではありません