Как отфильтровать список объектов по нескольким полям в Java? - PullRequest
0 голосов
/ 21 октября 2019

Я бы хотел отфильтровать список объектов по нескольким полям, но эти поля, которые используются для фильтрации, могут измениться. Например:

Предположим, что у нас есть класс Employee с некоторыми свойствами:

@Data
public class Employee {
   private Integer id;
   private Integer age;
   private String gender;
   private String firstName;
   private String lastName;

}

Каков наилучший способ кодирования метода, который фильтрует иногда по возрасту и полу, а иногда только по firstName? (Образцы могут быть воспроизведены, т. Е. Для этого примера он имеет 5 свойств, поэтому существует 5 возможностей = 120). Может ли он быть закодирован с использованием лямбды или чего-то еще в Java?

PS: Любые возможности не определены заранее. Что бы ни исходило из запроса, оно должно фильтроваться по нему. Я полагаю, что приведенный ниже пример прояснит эту проблему:

Предположим, что у нас есть объект Filter с теми же свойствами, что и у Employee. Если указан возраст, а остальные не заданы, эта служба будет фильтровать только по возрасту. Или указываются только пол и имя, это должны быть сотрудники по критериям.

Ответы [ 3 ]

0 голосов
/ 21 октября 2019

Вы, вероятно, хотите использовать функцию filter. Эта функция работает так, что если ваше выражение оценивается как true, оно вернет его в результирующий поток.

Пример фрагмента будет:

//Assuming employeeList is an ArrayList of Employee:
employeeList.stream().filter((e) -> e.age>25 && "M".equals(e.gender)); //Gives you a stream with all the male employees older than 25.

Вот некоторые материал для чтения для вас! Специально «2.3 для нескольких условий». раздел.

Надеюсь, это поможет!

0 голосов
/ 21 октября 2019

Вы можете реализовать определенные функции поиска для каждого атрибута, например

  • для возраста возможных фильтров 'Equal', 'Greater than' или 'Less than'

  • Для фамилии фильтр 'is equal', 'begins with' или 'ends with'.

  • Для пола 'is male'

Вы можете добавитьчто-то вроде ниже для вашего класса Employee:

public static Predicate<Employee> ageEQ(int a) {
    return e -> e.getAge() == a;
}
public static Predicate<Employee> ageGT(int a) {
    return e -> e.getAge() > a;
}
public static Predicate<Employee> ageLT(int a) {
    return e -> e.getAge() < a;
}
public static Predicate<Employee> isMale() {
    return e -> e.getGender().equals("M");
}
public static Predicate<Employee> lastNameEQ(String name) {
    return e -> e.getLastName().equals(name);
}
public static Predicate<Employee> lastNameStartsWith(String name) {
    return e -> e.getLastName().startsWith(name);
}

И список сотрудников:

List<Employee> list = new ArrayList<>();
    list.add(new Employee(1,22,"M","Aaa","Bar"));
    list.add(new Employee(2,33,"F","Ccc","Ddd"));
    list.add(new Employee(3,44,"M","Eee","Fff"));
    list.add(new Employee(4,55,"F","Ggg","Hhh"));
    list.add(new Employee(5,66,"F","Mmm","Nnn"));

, чтобы отфильтровать, например, всех сотрудников старше 40 лет и женщин:

list.stream()
    .filter(Employee.ageGT(40).and(Employee.isMale().negate()))
    .forEach(System.out::println);

Предположим, что ваш запрос похож на? Age> 40 & male = false ...

0 голосов
/ 21 октября 2019

Если вы знаете, что вам нужно фильтровать, вы можете комбинировать предикаты. Допустим, вы хотите отфильтровать сотрудников с именами, начинающимися с J, которым более 37 лет.

Predicate<Employee> p = e -> e.getFirstName().startsWith("J");
p = p.and(e -> e.getAge() > 37);

Теперь вы можете использовать предикат p в фильтре. Вам просто нужно построить окончательный предикат в зависимости от требуемых условий.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...