流和过滤列表结构

时间:2016-06-16 11:49:33

标签: java java-8 java-stream

尝试从结构中获取项目列表并避免大量循环和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. 来自按姓名过滤的家庭的
  3. List<Item>
  4. 列表from house, which contain only records filtered by Item`name
  5. 到目前为止,我尝试了以下内容:

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

    2. 列表testItemsFiltered = house1.familyList.stream()。flatMap(f - &gt; f.personList.stream()。flatMap(p - &gt; p.itemList.stream()。filter(item-&gt; ; item.name.equals(&#34;锤&#34;))))     .collect(Collectors.toList());

    3. 但两者都在抛出无效点

      for 3. variant我到目前为止还不知道

      kevin编辑:
      check:familiList包含很少Item个名字 - &#34; item1&#34;,&#34; item2&#34;,&#34; item3&#34;

      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

1 个答案:

答案 0 :(得分:3)

我尝试了第一个代码:

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

并且此代码有效。您似乎没有在开头初始化列表。所以我建议在构造函数中初始化它们,NullPointer应该消失。此外,当列表为空时,不会显示NullPointer

此代码应返回每个family,其中person具有特定item

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());