2016-09-02 15 views
1

SchoolDistrictという数値がSchoolsで、数値がClassesである数値がStudentsであるとします。コレクション内のコレクションの数をストリーム付きのコレクションでカウントしたい

私はSchoolDistrictで与えられたクラスの数を数えたいと思います。

のJava 7の方法は、それほどのように次のようになります。

Integer classCount = 0; 
for (School school : schoolDistrict) 
{ 
    for (Student student : school.getStudents()) 
    { 
     classCount += student.getClasses().size(); 
    } 
} 

は、私は、Java 8の目に少し簡単にこの種のものを作ることになっているのストリームをもたらすことを知っています。

しかし、私はそれを行う方法を考え出すのに苦労しています。

任意の受取人ですか?

EDIT:誰かがこれをthis postの重複としてマークしていますが、その例は2つのレベルの深さしかなかったとは思いません。私の質問は、4つのレベルに深刻な問題に関連しています(授業から学生への学校から学校へ)

+0

@azurefrogほとんどの場合、私のコレクションのクエリで一層深くする必要があります – Trevor

+0

次のようなものを試してみてください: 'schoolDistrict.stream()。mapToInt(school - > school.getStudents()。getClasses()。size )).sum(); ' – Orin

+0

@ Orin2005 getStudents()。getClasses()' getStudents()は 'Class'esを含んでいないCollectionを返します。 – Trevor

答えて

5

これは、ジョブがサンセリフのラムダを成し遂げるためにメソッド参照を使用しています各クラスの各クラスをストリーミングして反復的にクラスを数えるよりも効率的です。

+0

これは少しきれいに見えます。 – Kayaman

+0

私は '.flatMap(List :: stream)とは思えません。mapの部分は動作します – Trevor

+0

@Kayamanメソッドリファレンス(lambdasはありません)だけを使用するためにはもっと多くのステップが必要ですが、もっときれいに見えて、もっと簡単にそれに従うことができますIMHO – Bohemian

4

schoolDistrict.stream().flatMap(school -> school.getStudents().stream())を使用してStream<Student>を得ることができます。さらにflatMap()を実行してStream<YourClass>を取得することもできます。これは、ネストされたコレクションの各エンティティを処理する必要がある場合です。金額の計算が必要な場合は、mapToInt()sum()を終了操作として使用できます。

したがってflatMap()は、ネストされたコレクションのネスト解除または「平坦化」の秘密です。そして、もちろんですsum()を適用サイズ各生徒のクラスのIntStream

int classCount = schoolDistrict.stream() 
    .map(School::getStudents) 
    .flatMap(Collection::stream) 
    .map(Student::getClasses) 
    .mapToInt(Collection::size) 
    .sum(); 

も注意スイッチ:

Stream<MyClass> stream = schoolDistrict.stream().flatMap(s -> s.getStudents().stream()).flatMap(s -> s.getClasses().stream()); 
int count = stream.count(); 
+0

私はflatMapがそれと関係があると知っていました...しかし、私が欠けていたflapMapラムダ関数の中の余分な '.stream()'に追加していました。多くの感謝 – Trevor

関連する問題