Использование filter Stream api
Подскажите, пожалуйста, как получиться отсортированный по фамилии список потенциально работоспособных людей с высшим образованием в выборке (т.е. людей с высшим образованием от 18 до 60 лет для женщин и до 65 лет для мужчин). С сортировкой проблем нет. Не понятно как с помощью метода .filter() отфильтровать мужчин по определенному возрасту и женщин по определенному возрасту. По логике напрашивается тернарный оператор, на как его использовать вместе с .filter() не понятно
persons.stream()
.filter(age -> age.getAge() > 18)
*//как отфильтровать по возрасту в заисимости о пола*
.sorted(Comparator.comparing(Person::getFamily))
.collect(Collectors.toList())
.forEach(System.out::println);
Сам список
public static void main(String[] args) {
List<String> names = Arrays.asList("Jack", "Connor", "Harry", "George", "Samuel", "John");
List<String> families = Arrays.asList("Evans", "Young", "Harris", "Wilson", "Davies", "Adamson", "Brown");
Collection<Person> persons = new ArrayList<>();
for (int i = 0; i < 10_000_000; i++) {
persons.add(new Person(
names.get(new Random().nextInt(names.size())),
families.get(new Random().nextInt(families.size())),
new Random().nextInt(100),
Sex.Sex1.values()[new Random().nextInt(Sex.Sex1.values().length)],
Education.Education1.values()[new Random().nextInt(Education.Education1.values().length)]).
Ответы (1 шт):
Автор решения: Nowhere Man
→ Ссылка
Возможны несколько вариантов решения:
- объединение несколько условий при помощи логического ИЛИ
||:
enum Sex {MALE, FEMALE;}
// ...
persons.stream()
.filter(person -> person.getAge() >= 18) // minAge
.filter(person -> (Sex.MALE == person.getSex() && person.getAge() <= 65)
|| (Sex.FEMALE == person.getSex() && person.getAge() <= 60)
)
.sorted(Comparator.comparing(Person::getFamily))
.collect(Collectors.toList())
.forEach(System.out::println);
- Использование тернарного оператора:
persons.stream()
.filter(person -> person.getAge() >= 18
&& person.getAge() <= (Sex.MALE == person.getSex() ? 65 : 60)
)
.sorted(Comparator.comparing(Person::getFamily))
.collect(Collectors.toList())
.forEach(System.out::println);
- Добавление параметра
maxAgeвenum Sex:
enum Sex {
MALE(65), FEMALE(60);
private final int maxAge;
private Sex(int maxAge) { this.maxAge = maxAge; }
public int getMaxAge() { return this.maxAge(); }
}
Тогда фильтрация может быть переписана так
persons.stream()
.filter(person -> person.getAge() >= 18
&& person.getAge() <= person.getSex().getMaxAge()
)
.sorted(Comparator.comparing(Person::getFamily))
.collect(Collectors.toList())
.forEach(System.out::println);
- Реализация соответствующей логики в классе
Personили соответствующем утилитном методе (c учётом предыдущего пункта):
public class Person {
// ...
public boolean hasValidAge() {
return getAge() >= 18 && getAge() <= getSex().getMaxAge();
}
}
persons.stream()
.filter(Person::hasValidAge)
// ...
Или так:
public class Util {
private Util() {}
public static boolean hasValidAge(@NonNull Person person) {
return person.getAge() >= 18 && person.getAge() <= getSex().getMaxAge();
}
// ...
}
// ...
persons.stream()
.filter(Util::hasValidAge)