2016-06-16 113 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