首页 > 解决方案 > 使用包含具有特定属性值的项目的内部列表,Java 8

问题描述

我为特定任务创建了一个代码。但是,我认为:必须有更好的方式来执行此代码。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

public class InnerListContainingItemWithSpecificPropertyValue {

  public static void main(String[] args) {

    List<List<Person>> nestedPersonList = Arrays.asList(
        Arrays.asList(new Person("a0", 0), new Person("b0", 1)), //0
        Arrays.asList(new Person("a1", 0), new Person("b1", 1)), //1
        Arrays.asList(new Person("a2", 0), new Person("b2", 1)), //2
        Arrays.asList(new Person("a3", 0), new Person("b3", 1)) // 5
    );

    List<List<Person>> outNestedPersonList = new ArrayList<>();

    nestedPersonList.stream().flatMap(List::stream).forEach(outerPerson -> {

      //Determine if Exist Some inner List
      boolean ageFound = outNestedPersonList
          .stream()
          .flatMap(List::stream)
          .filter(innerPerson -> outerPerson.getAge() == innerPerson.getAge())
          .count() > 0L;

      List<Person> listPersonWithAge;
      if (!ageFound) {
        listPersonWithAge = new ArrayList<>();
        outNestedPersonList.add(listPersonWithAge);
      } else {
        // Get the Inner List with Specific Property Value
        listPersonWithAge = outNestedPersonList
            .stream()
            .filter(innerListPerson -> {
              return innerListPerson
                  .stream()
                  .filter(innerPerson -> outerPerson.getAge() == innerPerson.getAge())
                  .count() > 0L;
            }).findFirst().get();

      }
      listPersonWithAge.add(outerPerson);
      // Do something
      if (listPersonWithAge.size() == 4) {
        System.out.println("listPerson with age:" + outerPerson.getAge() + "\twill be removed!");
        outNestedPersonList.remove(listPersonWithAge);
      }

    });

  }

  public static class Person {

    private String name;
    private int age;

    public Person(String name, int age) {
      this.name = name;
      this.age = age;
    }

    public String getName() {
      return name;
    }

    public void setName(String name) {
      this.name = name;
    }

    public int getAge() {
      return age;
    }

    public void setAge(int age) {
      this.age = age;
    }

    @Override
    public int hashCode() {
      int hash = 5;
      hash = 73 * hash + Objects.hashCode(this.name);
      hash = 73 * hash + this.age;
      return hash;
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj) {
        return true;
      }
      if (obj == null) {
        return false;
      }
      if (getClass() != obj.getClass()) {
        return false;
      }
      final Person other = (Person) obj;
      if (this.age != other.age) {
        return false;
      }
      if (!Objects.equals(this.name, other.name)) {
        return false;
      }
      return true;
    }

    @Override
    public String toString() {
      return "Person{" + "name=" + name + ", age=" + age + '}';
    }

  }

}

输出:

listPerson with age:0   will be removed!
listPerson with age:1   will be removed!

或者我的代码:

  1. 如何知道内部列表是否包含某些具有某些属性值的项目?
  2. 我怎样才能获得该项目的内部列表?
  3. 如果外部列表不包含内部列表,如何创建一个?

标签: listlambdajava-8flatmap

解决方案


改进代码的第一步是避免使用flatMap. 它使对嵌套数据的操作更容易,但您正在尝试对其中一个子列表进行操作,而不是对所有人进行操作。

您正在尝试对一个子列表进行操作,而不是所有列表中的所有人,因此flatMap您可以嵌套两组流操作,而不是使用 。

listOfListOfPeople.stream()
    // filter out sublists that don't have anyone with the target age
    .filter(sublist ->
        // Check if the nested list contains anyone with the given age
        sublist.stream().anyMatch(p -> p.age == targetAge))
    // get one sublist out of the stream
    .findAny()
    // if there wasn't one, get an empty list
    .orElse(Collections.emptyList());

如果您希望能够在没有目标年龄的人的情况下修改获得的空列表,请将最后一行替换为.orElseGet(ArrayList::new).


推荐阅读