From f9ad7d03397a577af8dc51a5124d442b777c333e Mon Sep 17 00:00:00 2001 From: DariaBakal Date: Sun, 29 Dec 2024 22:34:17 +0200 Subject: [PATCH 1/2] stream practice --- .../java/practice/CandidateValidator.java | 37 +++++- src/main/java/practice/StreamPractice.java | 111 ++++++++++++------ 2 files changed, 107 insertions(+), 41 deletions(-) diff --git a/src/main/java/practice/CandidateValidator.java b/src/main/java/practice/CandidateValidator.java index 8d2e56c0e..0abfd812f 100644 --- a/src/main/java/practice/CandidateValidator.java +++ b/src/main/java/practice/CandidateValidator.java @@ -1,5 +1,38 @@ package practice; -public class CandidateValidator { - //write your code here +import java.util.function.Predicate; +import model.Candidate; +/** + * Your help with a election is needed. Given list of candidates, where each element has + * Candidate.class type. Check which candidates are eligible to apply for president position and + * return their names sorted alphabetically. The requirements are: person should be older than 35 + * years, should be allowed to vote, have nationality - 'Ukrainian' and live in Ukraine for 10 + * years. For the last requirement use field periodsInUkr, which has following view: "2002-2015" We + * want to reuse our validation in future, so let's write our own impl of Predicate parametrized + * with Candidate in CandidateValidator. + */ + +public class CandidateValidator implements Predicate { + private static final int MIN_AGE = 35; + private static final String NATIONALITY = "Ukrainian"; + private static final int PERIOD_IN_UKRAINE = 10; + + @Override + public boolean test(Candidate c) { + if (c.getAge() < MIN_AGE) { + return false; + } + if (!c.isAllowedToVote()) { + return false; + } + if (!NATIONALITY.equals(c.getNationality())) { + return false; + } + String[] splitedPeriod = c.getPeriodsInUkr().split("-"); + int startYear = Integer.parseInt(splitedPeriod[0]); + int endYear = Integer.parseInt(splitedPeriod[1]); + + return (endYear - startYear) >= PERIOD_IN_UKRAINE; + } } + diff --git a/src/main/java/practice/StreamPractice.java b/src/main/java/practice/StreamPractice.java index 57b1ca2e2..0159b029a 100644 --- a/src/main/java/practice/StreamPractice.java +++ b/src/main/java/practice/StreamPractice.java @@ -1,80 +1,113 @@ package practice; -import java.util.Collections; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.stream.IntStream; import model.Candidate; +import model.Cat; import model.Person; +import model.Person.Sex; public class StreamPractice { + /** - * Given list of strings where each element contains 1+ numbers: - * input = {"5,30,100", "0,22,7", ...} - * return min integer value. One more thing - we're interested in even numbers. - * If there is no needed data throw RuntimeException with message - * "Can't get min value from list: < Here is our input 'numbers' >" + * Given list of strings where each element contains 1+ numbers: input = {"5,30,100", "0,22,7", + * ...} return min integer value. One more thing - we're interested in even numbers. If there is + * no needed data throw RuntimeException with message "Can't get min value from list: < Here is + * our input 'numbers' >" */ public int findMinEvenNumber(List numbers) { - return 0; + return numbers.stream() + .flatMap(n -> Arrays.stream(n.split(","))) + .mapToInt(Integer::parseInt) + .filter(num -> num % 2 == 0) + .min() + .orElseThrow(() -> new RuntimeException("Can't get min value from list: " + + numbers)); } /** - * Given a List of Integer numbers, - * return the average of all odd numbers from the list or throw NoSuchElementException. - * But before that subtract 1 from each element on an odd position (having the odd index). + * Given a List of Integer numbers, return the average of all odd numbers from the list or throw + * NoSuchElementException. But before that subtract 1 from each element on an odd position + * (having the odd index). */ public Double getOddNumsAverage(List numbers) { - return 0D; + List copiedList = new ArrayList<>(numbers); + IntStream.range(0, numbers.size()) + .filter(i -> i % 2 != 0) + .forEach(i -> copiedList.set(i, copiedList.get(i) - 1)); + return copiedList.stream() + .filter(num -> num % 2 != 0) + .mapToInt(num -> num) + .average() + .orElseThrow(NoSuchElementException::new); } /** - * Given a List of `Person` instances (having `name`, `age` and `sex` fields), - * for example, `Arrays.asList( new Person(«Victor», 16, Sex.MAN), - * new Person(«Helen», 42, Sex.WOMAN))`, + * Given a List of `Person` instances (having `name`, `age` and `sex` fields), for example, + * `Arrays.asList( new Person(«Victor», 16, Sex.MAN), new Person(«Helen», 42, Sex.WOMAN))`, * select from the List only men whose age is from `fromAge` to `toAge` inclusively. *

* Example: select men who can be recruited to army (from 18 to 27 years old inclusively). */ public List selectMenByAge(List peopleList, int fromAge, int toAge) { - return Collections.emptyList(); + return peopleList.stream() + .filter(Objects::nonNull) + .filter(p -> p.getSex() == Sex.MAN) + .filter(p -> p.getAge() >= fromAge && p.getAge() <= toAge) + .toList(); } /** - * Given a List of `Person` instances (having `name`, `age` and `sex` fields), - * for example, `Arrays.asList( new Person(«Victor», 16, Sex.MAN), - * new Person(«Helen», 42, Sex.WOMAN))`, - * select from the List only people whose age is from `fromAge` and to `maleToAge` (for men) - * or to `femaleToAge` (for women) inclusively. + * Given a List of `Person` instances (having `name`, `age` and `sex` fields), for example, + * `Arrays.asList( new Person(«Victor», 16, Sex.MAN), new Person(«Helen», 42, Sex.WOMAN))`, + * select from the List only people whose age is from `fromAge` and to `maleToAge` (for men) or + * to `femaleToAge` (for women) inclusively. *

- * Example: select people of working age - * (from 18 y.o. and to 60 y.o. for men and to 55 y.o. for women inclusively). + * Example: select people of working age (from 18 y.o. and to 60 y.o. for men and to 55 y.o. for + * women inclusively). */ public List getWorkablePeople(int fromAge, int femaleToAge, - int maleToAge, List peopleList) { - return Collections.emptyList(); + int maleToAge, List peopleList) { + return peopleList.stream() + .filter(Objects::nonNull) + .filter(p -> p.getAge() >= fromAge) + .filter(p -> (p.getSex() == Sex.WOMAN && p.getAge() <= femaleToAge) + || (p.getSex() == Sex.MAN && p.getAge() <= maleToAge)) + .toList(); } /** - * Given a List of `Person` instances (having `name`, `age`, `sex` and `cats` fields, - * and each `Cat` having a `name` and `age`), - * return the names of all cats whose owners are women from `femaleAge` years old inclusively. + * Given a List of `Person` instances (having `name`, `age`, `sex` and `cats` fields, and each + * `Cat` having a `name` and `age`), return the names of all cats whose owners are women from + * `femaleAge` years old inclusively. */ public List getCatsNames(List peopleList, int femaleAge) { - return Collections.emptyList(); + return peopleList.stream() + .filter(p -> p.getSex() == Sex.WOMAN && p.getAge() >= femaleAge) + .flatMap(p -> p.getCats().stream()) + .map(Cat::getName) + .toList(); } /** - * Your help with a election is needed. Given list of candidates, where each element - * has Candidate.class type. - * Check which candidates are eligible to apply for president position and return their - * names sorted alphabetically. - * The requirements are: person should be older than 35 years, should be allowed to vote, - * have nationality - 'Ukrainian' - * and live in Ukraine for 10 years. For the last requirement use field periodsInUkr, - * which has following view: "2002-2015" - * We want to reuse our validation in future, so let's write our own impl of Predicate - * parametrized with Candidate in CandidateValidator. + * Your help with a election is needed. Given list of candidates, where each element has + * Candidate.class type. Check which candidates are eligible to apply for president position and + * return their names sorted alphabetically. The requirements are: person should be older than + * 35 years, should be allowed to vote, have nationality - 'Ukrainian' and live in Ukraine for + * 10 years. For the last requirement use field periodsInUkr, which has following view: + * "2002-2015" We want to reuse our validation in future, so let's write our own impl of + * Predicate parametrized with Candidate in CandidateValidator. */ public List validateCandidates(List candidates) { - return Collections.emptyList(); + return candidates.stream() + .filter(new CandidateValidator()) + .map(Candidate::getName) + .sorted() + .toList(); } + } From 99fca055e4a246c9edbde68bab069fda12828be6 Mon Sep 17 00:00:00 2001 From: DariaBakal Date: Mon, 30 Dec 2024 23:51:30 +0200 Subject: [PATCH 2/2] stream practice --- .../java/practice/CandidateValidator.java | 15 ++++----- src/main/java/practice/StreamPractice.java | 33 ++++++++++--------- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/src/main/java/practice/CandidateValidator.java b/src/main/java/practice/CandidateValidator.java index 0abfd812f..564903353 100644 --- a/src/main/java/practice/CandidateValidator.java +++ b/src/main/java/practice/CandidateValidator.java @@ -16,23 +16,20 @@ public class CandidateValidator implements Predicate { private static final int MIN_AGE = 35; private static final String NATIONALITY = "Ukrainian"; private static final int PERIOD_IN_UKRAINE = 10; + private static final String SEPARATOR = "-"; @Override public boolean test(Candidate c) { - if (c.getAge() < MIN_AGE) { + if (c.getAge() < MIN_AGE + || !c.isAllowedToVote() + || !NATIONALITY.equals(c.getNationality())) { return false; } - if (!c.isAllowedToVote()) { - return false; - } - if (!NATIONALITY.equals(c.getNationality())) { - return false; - } - String[] splitedPeriod = c.getPeriodsInUkr().split("-"); + String[] splitedPeriod = c.getPeriodsInUkr().split(SEPARATOR); int startYear = Integer.parseInt(splitedPeriod[0]); int endYear = Integer.parseInt(splitedPeriod[1]); - return (endYear - startYear) >= PERIOD_IN_UKRAINE; } } + diff --git a/src/main/java/practice/StreamPractice.java b/src/main/java/practice/StreamPractice.java index 0159b029a..36f1c29a4 100644 --- a/src/main/java/practice/StreamPractice.java +++ b/src/main/java/practice/StreamPractice.java @@ -1,10 +1,10 @@ package practice; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.NoSuchElementException; import java.util.Objects; +import java.util.function.Predicate; import java.util.stream.IntStream; import model.Candidate; import model.Cat; @@ -12,6 +12,8 @@ import model.Person.Sex; public class StreamPractice { + public static final String SEPARATOR = ","; + private final CandidateValidator candidateValidator = new CandidateValidator(); /** * Given list of strings where each element contains 1+ numbers: input = {"5,30,100", "0,22,7", @@ -21,7 +23,7 @@ public class StreamPractice { */ public int findMinEvenNumber(List numbers) { return numbers.stream() - .flatMap(n -> Arrays.stream(n.split(","))) + .flatMap(n -> Arrays.stream(n.split(SEPARATOR))) .mapToInt(Integer::parseInt) .filter(num -> num % 2 == 0) .min() @@ -35,15 +37,12 @@ public int findMinEvenNumber(List numbers) { * (having the odd index). */ public Double getOddNumsAverage(List numbers) { - List copiedList = new ArrayList<>(numbers); - IntStream.range(0, numbers.size()) - .filter(i -> i % 2 != 0) - .forEach(i -> copiedList.set(i, copiedList.get(i) - 1)); - return copiedList.stream() - .filter(num -> num % 2 != 0) - .mapToInt(num -> num) + return IntStream.range(0, numbers.size()) + .map(i -> i % 2 != 0 ? numbers.get(i) - 1 : numbers.get(i)) + .filter(n -> n % 2 != 0) .average() - .orElseThrow(NoSuchElementException::new); + .orElseThrow(() -> new NoSuchElementException( + "Didn't find suitable numbers to calculate average")); } /** @@ -54,10 +53,11 @@ public Double getOddNumsAverage(List numbers) { * Example: select men who can be recruited to army (from 18 to 27 years old inclusively). */ public List selectMenByAge(List peopleList, int fromAge, int toAge) { + Predicate ageSexFilter = p -> p.getSex() == Sex.MAN + && p.getAge() >= fromAge && p.getAge() <= toAge; return peopleList.stream() .filter(Objects::nonNull) - .filter(p -> p.getSex() == Sex.MAN) - .filter(p -> p.getAge() >= fromAge && p.getAge() <= toAge) + .filter(ageSexFilter) .toList(); } @@ -72,11 +72,13 @@ public List selectMenByAge(List peopleList, int fromAge, int toA */ public List getWorkablePeople(int fromAge, int femaleToAge, int maleToAge, List peopleList) { + Predicate workableFilter = p -> + (p.getSex() == Sex.WOMAN && p.getAge() <= femaleToAge) + || (p.getSex() == Sex.MAN && p.getAge() <= maleToAge); return peopleList.stream() .filter(Objects::nonNull) .filter(p -> p.getAge() >= fromAge) - .filter(p -> (p.getSex() == Sex.WOMAN && p.getAge() <= femaleToAge) - || (p.getSex() == Sex.MAN && p.getAge() <= maleToAge)) + .filter(workableFilter) .toList(); } @@ -104,10 +106,9 @@ public List getCatsNames(List peopleList, int femaleAge) { */ public List validateCandidates(List candidates) { return candidates.stream() - .filter(new CandidateValidator()) + .filter(candidateValidator) .map(Candidate::getName) .sorted() .toList(); } - }