2016-06-16 111 views
3

試圖從結構的產品清單,並避免大量的循環和IFS的結構,所以我想用Stream流和過濾器列表

例如,讓我們有以下結構:

class House { 
List<Family> familyList; 
} 

class Family { 
List<Person> personList; 
String someInfo; 

} 

class Person { 
String name; 
int age; 
List<Item> itemList; 
} 

class Item{ 
String name;  
} 

我想創建:

  1. List<Item>從家庭
  2. List<Item>從法米爾通過名稱
  3. 列表過濾IES from house, which contain only records filtered by Item`name

到目前爲止我嘗試以下:

  1. 列表testItems = house1.familyList.stream()flatMap(F - > F。。 personList.stream()。flatMap(p - > p.itemList.stream())) .collect(Collectors.toList()); List testItems = house1.familyList.stream()。flatMap(f - > f.personList.stream())。flatMap(p-> p.itemList.stream()) .collect(Collectors.toList());

  2. List testItemsFiltered = house1.familyList.stream()。flatMap(f - > f.personList.stream()。flatMap(p - > p.itemList.stream()。filter(item-> item.name .equals(「Hammer」)))) .collect(Collectors.toList());

但兩者都扔nullpointers

爲3變種我不知道到目前爲止

凱文編輯:
檢查:familiList包含幾個Item以名字 - 「物品1」,「ITEM2 」, 「項目3」

List<Family> filteredFamilies = house1.familyList.stream() 
       .filter(f -> f.personList.stream() 
         .anyMatch(p ->p.itemList.stream() 
           .anyMatch(i -> i.name.equals("item1")))) 
       .collect(Collectors.toList()); 

for (Family family : filteredFamilies) { 
      for (Person p : family.personList) { 
       for (Item i : p.itemList) { 
        System.out.println(i.name); 
       } 
      } 
     } 

結果:

item1 
item2 
item2 
item3 
item1 
item2 
item2 
item3 

befor過濾:

F1-
_p1- IT1,IT2
_p2- IT2,IT3,IT4
F2
_p3- IT1,I2
_p4 I3
F3
_p5 i5

過濾後:

F1-
P1-IT1
F2
P3- IT1

+2

您的列表爲空或null? –

+0

..我忘了給Person對象指定列表,但仍然不知道3.點 – sala

+1

問題是,這些家庭是否有包含這些項目的人?通常你應該檢查其他方式。創建一個沒有item1的家庭,然後檢查「filteredFamilies」是否確實包含那些 –

回答

3

我嘗試的第一個代碼:

List<Item> testItems = house1.familyList.stream() 
       .flatMap(f -> f.personList.stream() 
        .flatMap(p ->p.itemList.stream())) 
       .collect(Collectors.toList()); 

與此代碼的工作。看起來你並沒有在開始時初始化列表。所以我會建議在構造函數中初始化它們,NullPointer應該消失。此外,當列表爲空時,不會出現NullPointer

此代碼應返回具有person與特定item每個family

String expectedItem = "test"; 
List<Family> families = house1.familyList.stream() 
       .filter(f -> f.personList.stream() 
         .anyMatch(p ->p.itemList.stream() 
           .anyMatch(i -> i.name.equals(expectedItem)))) 
       .collect(Collectors.toList()); 

根據這個問題的答案也被改變:

String expectedItem = "test"; 
List<Family> families = house1.familyList.stream() 
       .filter(f -> f.personList.stream() 
         .anyMatch(p ->p.itemList.stream() 
           .allMatch(i -> i.name.equals(expectedItem)))) 
       .collect(Collectors.toList()); 
+0

當我嘗試它時,它包含所有項目,不只是預期的,它適合你嗎? – sala

+1

我試過了,它工作。問題是,他們是否使用相同的「名稱」引用相同的「項目」? –

+0

看我的編輯關於檢查 – sala