2016-05-06 2 views
2

Мне нужно отфильтровать список сотрудников на основе некоторых параметров, таких как firstName, lastName и т. Д. Эти параметры определены пользователем, и пользователь может выбрать весь фильтр или комбинацию фильтров.Добавить Фильтры на основе некоторых условий java 8

public List<Employee> getFilterList(String firstName,String lastName) 
{ 
    List<Employee> empList = empRepository.getEmployees(); 

    Stream<Employee> empStream=empList.stream(); 

    if(firstName!=null) 
    { 
    empStream= empStream.filter(e-> e.getFirstname().equals(firstName)) 
    } 

    if(lastName!=null) 
    { 
    empStream= empStream.filter(e-> e.getlastName().equals(lastName)) 
    } 

    return empStream.collect(Collectors.toList()); 
} 

Правильно ли это делается?

Примечание: приведенный выше код работает нормально. Я просто ищу другой лучший подход (если есть).

Случай 1: список getFilterList(null,null) возвращения всех сотрудников

Case 2: список getFilterList("abc",null) возвращения всех сотрудников с первым именем аЬсом.

+1

Выглядит нормально для меня, вы возникли проблемы с ним ? Вы заботитесь о сравнении случаев (I.e. Верхний и нижний регистр)? – Draken

+0

Нет, у меня нет никаких проблем с этим кодом и его работой тоже. Но я не был уверен в этом подходе. –

ответ

1

Вы также мог бы сделать это следующим образом:

List<Predicate<Employee>> predicateList = new ArrayList<>(); 

predicateList.add(emp -> firstName == null || (emp.firstName != null && emp.firstName.equals(firstName))); 
predicateList.add(emp -> lastName == null || (emp.lastName != null && emp.lastName.equals(lastName))); 

empStream.filter(emp -> { 
    Stream<Predicate<Employee>> predicateStream = predicateList.stream(); 
    return predicateStream.map(predicate -> predicate.test(emp)).reduce((a, b) -> a && b).get(); 
}).collect(Collectors.toList()); 

на основе выбора пользователя, вам нужно создать predicateList, добавив предикаты.

predicateStream.map(predicate -> predicate.test(emp)) возвращает Stream<Boolean>. Этот поток содержит значения, которые являются результатом применения предиката (т.е. predicate.test(emp)) на примере emp. Затем reduce((a, b) -> a && b) проверяет, были ли все результаты в потоке true или нет. В конце возвращается true или false, на основании которого filter определяет, должен ли быть выбран объект emp или нет.

Примечание что Stream<Predicate<Employee>> predicateStream создается для каждого объекта Employee в empStream, который может включать в себя некоторые накладные расходы.

+1

@SandeepBhardwaj Добавлено объяснение. –

+0

Код не работает для ** Случай 1: ** 'getFilterList (null, null)', в этом случае он должен возвращать все записи, ** Случай 2: ** 'getFilterList (« abc », null)' in в этом случае все emp с именем abc в качестве имени. –

+1

Как я уже говорил, вам нужно создавать динамические переменные на основе ввода пользователя, здесь я только что показал вам, как вы можете применить одно или несколько условий к списку объектов. Не используйте только предикаты, которые я добавил в 'predicateList'. Это был просто пример. –

0

Обратите внимание, что второе условие принимает presidance над первой и если оба firstName и lastName являются null, вы возвращаете перечень Employee. Поэтому многие условия, которые вы поставили, оцениваются, хотя их оценка не требуется. Я бы сделал это по следующим направлениям:

return firstName == null && lastName == null ? 
       empList : 
       (lastName != null ? 
         empList.stream().filter(emp -> emp.lastname.equals(lastName) : 
         empList.stream().filter(emp -> empfirstName.equals(firstName)) 
       ).colector(Collectors.toList()); 
1

Он показывает список empList в соответствии с параметром firstName фильтра или фильтрации в соответствии с параметром lastName, шаблон кода почти одинаковы. Поэтому я придумал следующий код.

public List<Employee> getFilterList(String firstName,String lastName){ 

    List<Employee> empList = empRepository.getEmployees(); 

    return empList.stream().filter(getPredicateBiFun.apply(firstName,Employee::getFirstName)) 
          .filter(getPredicateBiFun.apply(lastName,Employee::getLastName)) 
          .collect(Collectors.toList()); 

} 

Это похоже на стиль Java8. И вот статическое свойство getPredicateBiFun, которое вы видите, которое может получить соответствующие выражения Predicate<Employee> в соответствии с параметрами. Так что это всего лишь BiFunction и хороший образец того, что мы хотим.

private static BiFunction<String, Function<Employee, String>, Predicate<Employee>> getPredicateBiFun = (name, getNameFun) -> employee -> name == null ? true : name.equals(getNameFun.apply(employee)); 

Это все :)

0

Не уверен, что это самый оптимальный способ, но он избавляется от МФС:

List<Employee> empList = empRepository.getEmployees(); 

return empList.stream() 
      .filter(e -> firstName == null || e.getFirstname().equals(firstName)) 
      .filter(e -> lastName == null || e.getlastName().equals(lastName)) 
      .collect(Collectors.toList()); 
0

Боролся на excat одно и то же.Для всех, кто ищет другой путь:

empList.stream() 
    .filter(firstName != null ? e -> e.getFirstName().equals(firstName) : e -> true) 
    .filter(lastName != null ? e -> e.getLastName().equals(lastName) : e -> true) 
    .collect(Collectors.toList()); 

Используя операцию ternery, чтобы применить фильтр или нет (если нет, то просто установить истину в моем случае)

Смежные вопросы