diff --git a/src/main/java/data/Generator.java b/src/main/java/data/Generator.java index cbd46ea..f5e76d1 100644 --- a/src/main/java/data/Generator.java +++ b/src/main/java/data/Generator.java @@ -60,7 +60,11 @@ public static Employee generateEmployee() { } public static List generateEmployeeList() { - // TODO - throw new UnsupportedOperationException(); + int maxLength = 10; + final int length = ThreadLocalRandom.current().nextInt(maxLength) + 1; + + return Stream.generate(Generator::generateEmployee) + .limit(length) + .collect(toList()); } } diff --git a/src/test/java/part1/exercise/StreamsExercise1.java b/src/test/java/part1/exercise/StreamsExercise1.java index 02dd2da..d29ec6a 100755 --- a/src/test/java/part1/exercise/StreamsExercise1.java +++ b/src/test/java/part1/exercise/StreamsExercise1.java @@ -7,6 +7,7 @@ import java.util.*; import java.util.concurrent.ThreadLocalRandom; +import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; @@ -15,6 +16,9 @@ import static java.util.stream.Collectors.groupingBy; import static java.util.stream.Collectors.mapping; import static java.util.stream.Collectors.toList; +import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; public class StreamsExercise1 { // https://youtu.be/kxgo7Y4cdA8 Сергей Куксенко и Алексей Шипилёв — Через тернии к лямбдам, часть 1 @@ -25,16 +29,60 @@ public class StreamsExercise1 { @Test public void getAllEpamEmployees() { - List epamEmployees = null;// TODO all persons with experience in epam - throw new UnsupportedOperationException(); + final List employees = generateEmployeeList(); + + List expected = new ArrayList<>(); + + for (Employee e : employees){ + for (JobHistoryEntry j : e.getJobHistory()) + if (j.getEmployer().equals("epam")){ + expected.add(e.getPerson()); + break; + } + } + + List actual = employees.stream() + .filter(this::hasExperienceInEpam) + .map(Employee::getPerson) + .collect(toList()); + + + assertThat(actual, equalTo(expected)); + } + + private boolean hasExperienceInEpam(Employee employee){ + return employee.getJobHistory().stream() + .filter(j -> j.getEmployer().equals("epam")) + .count() > 0; } @Test public void getEmployeesStartedFromEpam() { - List epamEmployees = null;// TODO all persons with first experience in epam - throw new UnsupportedOperationException(); + final List employees = generateEmployeeList(); + + List expected = new ArrayList<>(); + + for (Employee e : employees){ + if (e.getJobHistory().size() > 0 && e.getJobHistory().get(0).getEmployer().equals("epam")) + expected.add(e.getPerson()); + } + + List actual = employees.stream() + .filter(this::startExperienceInEpam) + .map(Employee::getPerson) + .collect(toList()); + + assertThat(actual, equalTo(expected)); + } + + private boolean startExperienceInEpam(Employee employee) { + return employee.getJobHistory().stream() + .limit(1) + .filter(j -> j.getEmployer().equals("epam")) + .count() > 0; } + @Test public void sumEpamDurations() { final List employees = generateEmployeeList(); @@ -49,11 +97,13 @@ public void sumEpamDurations() { } } - // TODO - throw new UnsupportedOperationException(); - - // int result = ??? - // assertEquals(expected, result); + int result = employees.stream() + .flatMap(employee -> employee.getJobHistory().stream()) + .filter(j -> j.getEmployer().equals("epam")) + .mapToInt(JobHistoryEntry::getDuration) + .sum(); + + assertEquals(expected, result); } } diff --git a/src/test/java/part1/exercise/StreamsExercise2.java b/src/test/java/part1/exercise/StreamsExercise2.java index 5be9d38..af09ada 100755 --- a/src/test/java/part1/exercise/StreamsExercise2.java +++ b/src/test/java/part1/exercise/StreamsExercise2.java @@ -5,15 +5,13 @@ import data.Person; import org.junit.Test; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Stream; -import static data.Generator.generateEmployeeList; import static java.util.stream.Collectors.*; +import static org.hamcrest.core.IsEqual.equalTo; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; public class StreamsExercise2 { // https://youtu.be/kxgo7Y4cdA8 Сергей Куксенко и Алексей Шипилёв — Через тернии к лямбдам, часть 1 @@ -23,26 +21,120 @@ public class StreamsExercise2 { // https://youtu.be/i0Jr2l3jrDA Сергей Куксенко — Stream API, часть 2 // TODO class PersonEmployerPair + public static class PersonEmployerPair { + private Person person; + private String employer; + private int duration; + + public PersonEmployerPair(Person person, String employer) { + this.person = person; + this.employer = employer; + } + + public PersonEmployerPair(Person person, String employer, int duration) { + this(person, employer); + this.duration = duration; + } + + public Person getPerson() { + return person; + } + + public String getEmployer() { + return employer; + } + + public int getDuration() { + return duration; + } + } + @Test public void employersStuffLists() { - Map> employersStuffLists = null;// TODO - throw new UnsupportedOperationException(); + List employees = getEmployees(); + + Map> expected = new HashMap<>(); + for (Employee employee : employees) { + for (JobHistoryEntry j : employee.getJobHistory()) { + if (!expected.containsKey(j.getEmployer())) { + expected.put(j.getEmployer(), new ArrayList()); + } + expected.get(j.getEmployer()).add(employee.getPerson()); + } + } + + Map> actual = employees.stream() + .flatMap(this::getPersonEmployerPairs) + .collect(groupingBy( + PersonEmployerPair::getEmployer, + mapping(PersonEmployerPair::getPerson, toList()) + )); + + assertThat(actual, equalTo(expected)); + } + + private Stream getPersonEmployerPairs(Employee employee) { + return employee.getJobHistory().stream() + .map(j -> new PersonEmployerPair(employee.getPerson(), j.getEmployer())); } @Test public void indexByFirstEmployer() { - Map> employeesIndex = null;// TODO - throw new UnsupportedOperationException(); + List employees = getEmployees(); + + Map> expected = new HashMap<>(); + for (Employee employee : employees) { + if (employee.getJobHistory().size() > 0) { + String employer = employee.getJobHistory().get(0).getEmployer(); + if (!expected.containsKey(employer)) { + expected.put(employer, new ArrayList<>()); + } + + expected.get(employer).add(employee.getPerson()); + } + } + + Map> actual = employees.stream() + .flatMap(this::getFirstPersonEmployerPairs) + .collect(groupingBy( + PersonEmployerPair::getEmployer, + mapping(PersonEmployerPair::getPerson, toList()) + )); + + + assertThat(actual, equalTo(expected)); + } + + private Stream getFirstPersonEmployerPairs(Employee employee) { + return employee.getJobHistory().stream() + .map(j -> new PersonEmployerPair(employee.getPerson(), j.getEmployer())) + .limit(1); } @Test public void greatestExperiencePerEmployer() { - Map employeesIndex = null;// TODO + List employees = getEmployees(); + + + Map employeesIndex = employees.stream() + .flatMap(this::getPersonEmployerDuration) + .collect(groupingBy( + PersonEmployerPair::getEmployer, + collectingAndThen( + maxBy(Comparator.comparingInt(PersonEmployerPair::getDuration)), + p -> p.get().getPerson() + ) + )); assertEquals(new Person("John", "White", 28), employeesIndex.get("epam")); } + private Stream getPersonEmployerDuration(Employee employee) { + return employee.getJobHistory().stream() + .map(j -> new PersonEmployerPair(employee.getPerson(), j.getEmployer(), j.getDuration())); + } + private List getEmployees() { return Arrays.asList( diff --git a/src/test/java/part2/exercise/CollectorsExercise1.java b/src/test/java/part2/exercise/CollectorsExercise1.java index 46b6765..400744c 100755 --- a/src/test/java/part2/exercise/CollectorsExercise1.java +++ b/src/test/java/part2/exercise/CollectorsExercise1.java @@ -6,25 +6,41 @@ import org.junit.Test; import java.util.*; -import java.util.concurrent.ThreadLocalRandom; import java.util.function.BiConsumer; import java.util.function.BinaryOperator; import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collector; -import java.util.stream.Collectors; -import java.util.stream.IntStream; import java.util.stream.Stream; -import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.*; +import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.Assert.assertThat; public class CollectorsExercise1 { @Test public void getTheCoolestOne() { - final Map coolestByPosition = getCoolestByPosition(getEmployees()); - coolestByPosition.forEach((position, person) -> System.out.println(position + " -> " + person)); + Person expected = new Person("John", "Doe", 30); + + final Map coolestByPosition0 = getCoolestByPosition0(getEmployees()); + + coolestByPosition0.forEach((position, person) -> System.out.println(position + " -> " + person)); + assertThat(coolestByPosition0.get("dev"), equalTo(expected)); + System.out.println(); + + final Map coolestByPosition1 = getCoolestByPosition1(getEmployees()); + + coolestByPosition0.forEach((position, person) -> System.out.println(position + " -> " + person)); + assertThat(coolestByPosition1.get("dev"), equalTo(expected)); + System.out.println(); + + final Map coolestByPositionCollector = getCoolestByPositionCollector(getEmployees()); + + coolestByPosition0.forEach((position, person) -> System.out.println(position + " -> " + person)); + assertThat(coolestByPositionCollector.get("dev"), equalTo(expected)); + System.out.println(); } private static class PersonPositionDuration { @@ -51,32 +67,118 @@ public int getDuration() { } } - // With the longest duration on single job - private Map getCoolestByPosition(List employees) { - // First option - // Collectors.maxBy - // Collectors.collectingAndThen - // Collectors.groupingBy - - // Second option - // Collectors.toMap - // iterate twice: stream...collect(...).stream()... - // TODO - throw new UnsupportedOperationException(); + + private Map getCoolestByPosition0(List employees) { + return employees.stream() + .flatMap(this::getPersonPositionDuration) + .collect(groupingBy( + PersonPositionDuration::getPosition, + collectingAndThen( + maxBy(Comparator.comparing(PersonPositionDuration::getDuration)), + pep -> pep.get().getPerson() + ) + )); + } + + private Map getCoolestByPosition1(List employees) { + return employees.stream() + .flatMap(this::getPersonPositionDuration) + .collect(toMap( + PersonPositionDuration::getPosition, + Function.identity(), + (ppd1, ppd2) -> ppd1.getDuration() > ppd2.getDuration() ? ppd1 : ppd2)) + .entrySet().stream() + .collect(toMap( + Map.Entry::getKey, + e -> e.getValue().getPerson() + )); + } + + private Map getCoolestByPositionCollector(List employees) { + return employees.stream() + .flatMap(this::getPersonPositionDuration) + .collect(collector); + } + + private Collector, Map> collector = + new Collector, Map>() { + @Override + public Supplier> supplier() { + return HashMap::new; + } + + @Override + public BiConsumer, PersonPositionDuration> accumulator() { + return (c, p) -> c.put(p.getPosition(), resolve(c, p)); + } + + private PersonPositionDuration resolve(Map c, PersonPositionDuration p2) { + return Optional.ofNullable(c.get(p2.getPosition())) + .filter(p1 -> p1.getDuration() >= p2.getDuration()) + .orElse(p2); + } + + @Override + public BinaryOperator> combiner() { + return this::combine; + } + + private Map combine(Map m1, + Map m2) { + m1.putAll(m2.entrySet().stream() + .filter(e -> + !m1.containsKey(e.getKey()) + || m1.get(e.getKey()).getDuration() < e.getValue().getDuration() + ).collect(toMap(Map.Entry::getKey, Map.Entry::getValue))); + return m1; + } + + @Override + public Function, Map> finisher() { + return m -> m.entrySet().stream() + .collect(toMap(Map.Entry::getKey, e -> e.getValue().getPerson())); + } + + @Override + public Set characteristics() { + return Collections.emptySet(); + } + }; + + + + private Stream getPersonPositionDuration(Employee employee) { + return employee.getJobHistory().stream() + .map(j -> new PersonPositionDuration(employee.getPerson(), j.getPosition(), j.getDuration())); } @Test public void getTheCoolestOne2() { final Map coolestByPosition = getCoolestByPosition2(getEmployees()); + Person expected = new Person("John", "Doe", 30); + + assertThat(coolestByPosition.get("QA"), equalTo(expected)); coolestByPosition.forEach((position, person) -> System.out.println(position + " -> " + person)); } - // With the longest sum duration on this position - // { John Doe, [{dev, google, 4}, {dev, epam, 4}] } предпочтительнее, чем { A B, [{dev, google, 6}, {QA, epam, 100}]} private Map getCoolestByPosition2(List employees) { - // TODO - throw new UnsupportedOperationException(); + return employees.stream() + .flatMap(this::getAbsolutePersonPositionDuration) + .collect(groupingBy(PersonPositionDuration::getPosition, + collectingAndThen( + maxBy(Comparator.comparing(PersonPositionDuration::getDuration)), + ppd -> ppd.get().getPerson() + ))); + } + + private Stream getAbsolutePersonPositionDuration(Employee employee) { + return employee.getJobHistory().stream() + .collect(groupingBy(JobHistoryEntry::getPosition, + summingInt(JobHistoryEntry::getDuration))) + .entrySet() + .stream() + .map(e -> new PersonPositionDuration(employee.getPerson(), e.getKey(), e.getValue())); } private List getEmployees() { @@ -145,7 +247,7 @@ private List getEmployees() { new Person("John", "Doe", 30), Arrays.asList( new JobHistoryEntry(4, "QA", "yandex"), - new JobHistoryEntry(2, "QA", "epam"), + new JobHistoryEntry(4, "QA", "epam"), new JobHistoryEntry(5, "dev", "abc") )), new Employee( diff --git a/src/test/java/part2/exercise/CollectorsExercise2.java b/src/test/java/part2/exercise/CollectorsExercise2.java index 00fda00..6764125 100755 --- a/src/test/java/part2/exercise/CollectorsExercise2.java +++ b/src/test/java/part2/exercise/CollectorsExercise2.java @@ -16,7 +16,9 @@ import java.util.stream.IntStream; import java.util.stream.Stream; +import static java.util.stream.Collectors.groupingBy; import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toMap; public class CollectorsExercise2 { @@ -167,33 +169,56 @@ BinaryOperator mapMerger(BinaryOperator mergeFunction) { public void collectKeyValueMap() { final List pairs = generatePairs(10, 100); - // В два прохода - // final Map keyMap1 = pairs.stream()... + Map keyMap1 = pairs.stream() + .collect(toMap( + p -> p.getKey().getId(), p -> p) + ); - // final Map> valuesMap1 = pairs.stream()... + Map> valuesMap1 = pairs.stream() + .collect(groupingBy( + p -> p.getValue().getKeyId(), + toList()) + ); - // В каждом Map.Entry id ключа должно совпадать с keyId для каждого значения в списке - // final Map> keyValuesMap1 = valueMap1.entrySet().stream()... + Map> keyValuesMap1 = keyMap1.entrySet().stream() + .collect(toMap( + Map.Entry::getValue, + e -> valuesMap1.get(e.getKey())) + ); - // В 1 проход в 2 Map с использованием MapPair и mapMerger final MapPair res2 = pairs.stream() .collect(new Collector() { @Override public Supplier supplier() { - // TODO - throw new UnsupportedOperationException(); + return MapPair::new; } @Override public BiConsumer accumulator() { - // TODO add key and value to maps - throw new UnsupportedOperationException(); + return (mp, p) -> { + mp.getKeyById().put(p.getKey().getId(), p.getKey()); + if (!mp.getValueById().containsKey(p.getValue().getKeyId())) + mp.getValueById().put(p.getValue().getKeyId(), new ArrayList<>()); + mp.getValueById().get(p.getValue().getKeyId()).add(p.getValue()); + }; } @Override public BinaryOperator combiner() { - // TODO use mapMerger - throw new UnsupportedOperationException(); + return (m1, m2) -> { + BinaryOperator> merger1 = mapMerger((e1, e2) -> e1); + merger1.apply(m1.getKeyById(), m2.getKeyById()); + + BinaryOperator>> merger2 = mapMerger( + (e1, e2) -> { + e1.addAll(e2.stream() + .filter(e -> !e1.contains(e)) + .collect(toList())); + return e1; + }); + merger2.apply(m1.getValueById(), m2.getValueById()); + return m1; + }; } @Override @@ -212,10 +237,14 @@ public Set characteristics() { final Map keyMap2 = res2.getKeyById(); final Map> valuesMap2 = res2.getValueById(); - // final Map> keyValuesMap2 = valueMap2.entrySet().stream()... + Map> keyValuesMap2 = valuesMap2.entrySet().stream() + .collect(toMap( + e -> keyMap2.get(e.getKey()), + Map.Entry::getValue + )); - // Получение результата сразу: + // Получение результата сразу: final SubResult res3 = pairs.stream() .collect(new Collector() { @Override diff --git a/src/test/java/part3/exercise/CollectorCombination.java b/src/test/java/part3/exercise/CollectorCombination.java index 15a42d5..1175aef 100755 --- a/src/test/java/part3/exercise/CollectorCombination.java +++ b/src/test/java/part3/exercise/CollectorCombination.java @@ -5,9 +5,14 @@ import part2.exercise.CollectorsExercise2.Key; import part2.exercise.CollectorsExercise2.Value; +import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.function.BiConsumer; +import java.util.function.BinaryOperator; import java.util.function.Function; +import java.util.function.Supplier; import java.util.stream.Collector; import static java.util.stream.Collectors.*; @@ -34,18 +39,45 @@ public B getB() { private static Collector, Pair> paired(Collector c1, Collector c2) { - // TODO - throw new UnsupportedOperationException(); + return new Collector, Pair>() { + @Override + public Supplier> supplier() { + return () -> new Pair(c1.supplier().get(), c2.supplier().get()); + } + + @Override + public BiConsumer, T> accumulator() { + return (m1m2Pair, t) -> { + c1.accumulator().accept(m1m2Pair.getA(), t); + c2.accumulator().accept(m1m2Pair.getB(), t); + }; + } + + @Override + public BinaryOperator> combiner() { + return (m1m2Pair1, m1m2Pair2) -> { + c1.combiner().apply(m1m2Pair1.getA(), m1m2Pair2.getA()); + c2.combiner().apply(m1m2Pair1.getB(), m1m2Pair2.getB()); + return m1m2Pair1; + }; + } + + @Override + public Function, Pair> finisher() { + return m1m2Pair -> new Pair( + c1.finisher().apply(m1m2Pair.getA()), + c2.finisher().apply(m1m2Pair.getB())); + } + + @Override + public Set characteristics() { + return Collections.emptySet(); + } + }; } @Test public void collectKeyValueMap() { - // TODO see CollectorsExercise1::collectKeyValueMap - // В 1 проход в 2 Map с использованием MapPair и mapMerger - // final MapPair res2 = pairs.stream() - // .collect(new Collector() { - - // Перепишите решение в слещующем виде: final List pairs = CollectorsExercise2.generatePairs(10, 100); final Pair, Map>> res2 = pairs.stream() @@ -56,9 +88,6 @@ public void collectKeyValueMap() { ) ); - - // TODO tests - throw new UnsupportedOperationException(); } } diff --git a/src/test/java/part3/exercise/lambda/LambdaExercise.java b/src/test/java/part3/exercise/lambda/LambdaExercise.java index 752e1f2..639397b 100755 --- a/src/test/java/part3/exercise/lambda/LambdaExercise.java +++ b/src/test/java/part3/exercise/lambda/LambdaExercise.java @@ -15,19 +15,21 @@ public class LambdaExercise { public void supply() { final Person person = new Person("John", "Galt", 30); - final Supplier getPerson = null; // TODO return person from Supplier + final Supplier getPerson = () -> person; assertEquals(person, getPerson.get()); } @Test public void function() { - final Function getPersonName1 = null; // TODO get the name of person using expression lambda + final Function getPersonName1 = person -> person.getFirstName(); - final Function getPersonName2 = null; // TODO get the name of person using method reference + final Function getPersonName2 = Person::getFirstName; - // TODO get the name of person and log it to System.out using statement lambda: {} - final Function getPersonNameAndLogIt = null; + final Function getPersonNameAndLogIt = person -> { + System.out.println(person.getFirstName()); + return person.getFirstName(); + }; final Person person = new Person("John", "Galt", 30); @@ -38,19 +40,17 @@ public void function() { @Test public void combineFunctions() { - final Function getPersonName = null; // TODO get the name of person + final Function getPersonName = Person::getFirstName; assertEquals("John", getPersonName.apply(new Person("John", "Galt", 30))); - final Function getStringLength = null; // TODO get string length + final Function getStringLength = String::length; assertEquals(Integer.valueOf(3), getStringLength.apply("ABC")); - // TODO get person name length using getPersonName and getStringLength without andThen - final Function getPersonNameLength1 = null; + final Function getPersonNameLength1 = person -> getStringLength.apply(getPersonName.apply(person)); - // TODO get person name length using getPersonName and getStringLength with andThen - final Function getPersonNameLength2 = null; + final Function getPersonNameLength2 = getPersonName.andThen(getStringLength); final Person person = new Person("John", "Galt", 30); @@ -68,22 +68,20 @@ private Person createPerson(PersonFactory pf) { // ((T -> R), (R -> boolean)) -> (T -> boolean) private Predicate combine(Function f, Predicate p) { - // TODO - throw new UnsupportedOperationException(); + return t -> p.test(f.apply(t)); } @Test public void methodReference() { - // TODO use only method reverences here. - final Person person = createPerson(null); // TODO + final Person person = createPerson(Person::new); assertEquals(new Person("John", "Galt", 66), person); - final Function getPersonName = null; // TODO + final Function getPersonName = Person::getFirstName; assertEquals("John", getPersonName.apply(person)); - final Predicate isJohnString = null; // TODO using method reference check that "John" equals string parameter + final Predicate isJohnString = "John"::equals; final Predicate isJohnPerson = combine(getPersonName, isJohnString); diff --git a/src/test/java/part3/exercise/stream/StreamsExercise.java b/src/test/java/part3/exercise/stream/StreamsExercise.java index 4e2d54b..92867d0 100755 --- a/src/test/java/part3/exercise/stream/StreamsExercise.java +++ b/src/test/java/part3/exercise/stream/StreamsExercise.java @@ -6,11 +6,13 @@ import org.apache.commons.lang3.builder.ToStringBuilder; import org.junit.Test; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.function.BinaryOperator; +import java.util.function.Function; +import java.util.stream.Stream; +import static java.util.Comparator.comparing; +import static java.util.stream.Collectors.*; import static org.junit.Assert.assertEquals; public class StreamsExercise { @@ -19,22 +21,27 @@ public class StreamsExercise { public void getAllJobHistoryEntries() { final List employees = getEmployees(); - final List jobHistoryEntries = null; // TODO + final List jobHistoryEntries = + employees.stream() + .flatMap(e -> e.getJobHistory().stream()) + .collect(toList()); assertEquals(22, jobHistoryEntries.size()); } @Test public void getSumDuration() { - // sum all durations for all persons final List employees = getEmployees(); - final int sumDurations = 0; // TODO + final int sumDurations = employees.stream() + .flatMap(e -> e.getJobHistory().stream()) + .mapToInt(JobHistoryEntry::getDuration) + .sum(); assertEquals(72, sumDurations); } - private static class PersonEmployer{ + private static class PersonEmployer { private final Person person; private final String employer; @@ -64,16 +71,29 @@ public String toString() { public void indexPersonsByEmployer1() { final List employees = getEmployees(); - final Map> index = null; // TODO + final Map> index = employees.stream() + .flatMap(this::getPersonEmployerPair) + .collect(groupingBy(PersonEmployer::getEmployer)); assertEquals(11, index.get("epam").size()); } + private Stream getPersonEmployerPair(Employee employee) { + return employee.getJobHistory().stream() + .map(j -> new PersonEmployer(employee.getPerson(), j.getEmployer())); + } + @Test public void indexPersonsByEmployer2() { final List employees = getEmployees(); - final Map> index = null; // TODO + final Map> index = employees.stream() + .flatMap(this::getPersonEmployerPair) + .collect(groupingBy( + PersonEmployer::getEmployer, + mapping(PersonEmployer::getPerson, + toList()) + )); assertEquals(11, index.get("epam").size()); } @@ -105,16 +125,18 @@ public String toString() { } private PersonDuration sumAllPersonDurations(Employee e) { - // TODO - throw new UnsupportedOperationException(); + int duration = e.getJobHistory().stream().mapToInt(JobHistoryEntry::getDuration).sum(); + return new PersonDuration(e.getPerson(), duration); } @Test public void getSumPersonDuration() { - // sum all durations for each person final List employees = getEmployees(); - final Map personDuration = null; // TODO use sumAllPersonDurations + final Map personDuration = employees.stream() + .map(this::sumAllPersonDurations) + .collect(toMap(PersonDuration::getPerson, PersonDuration::getDuration)); + assertEquals(Integer.valueOf(8), personDuration.get(new Person("John", "Doe", 24))); } @@ -138,15 +160,21 @@ public Map getDurationByPositionIndex() { } private static PersonPositionIndex getPersonPositionIndex(Employee e) { - // TODO - throw new UnsupportedOperationException(); + Map durationByPositionIndex = e.getJobHistory().stream() + .collect(groupingBy( + JobHistoryEntry::getPosition, + summingInt(JobHistoryEntry::getDuration) + )); + + return new PersonPositionIndex(e.getPerson(), durationByPositionIndex); } @Test public void getSumDurationsForPersonByPosition() { final List employees = getEmployees(); - final List personIndexes = null; // TODO use getPersonPositionIndex + final List personIndexes = employees.stream() + .map(StreamsExercise::getPersonPositionIndex).collect(toList()); assertEquals(1, personIndexes.get(3).getDurationByPositionIndex().size()); } @@ -179,18 +207,37 @@ public int getDuration() { public void getDurationsForEachPersonByPosition() { final List employees = getEmployees(); - final List personPositionDurations = null; // TODO + final List personPositionDuration = employees.stream() + .flatMap(this::getPersonPositionDuration) + .collect(toList()); + assertEquals(17, personPositionDuration.size()); + } + + private Stream getPersonPositionDurations(Employee employee) { + return employee.getJobHistory().stream() + .map(j -> new PersonPositionDuration(employee.getPerson(), j.getPosition(), j.getDuration())); + } - assertEquals(17, personPositionDurations.size()); + private Stream getPersonPositionDuration(Employee employee) { + return employee.getJobHistory().stream() + .collect(groupingBy(JobHistoryEntry::getPosition, + summingInt(JobHistoryEntry::getDuration))) + .entrySet().stream() + .map(e -> new PersonPositionDuration(employee.getPerson(), + e.getKey(), + e.getValue())); } @Test public void getCoolestPersonByPosition1() { - // Get person with max duration on given position final List employees = getEmployees(); - final Map coolestPersonByPosition = null;// TODO + final Map coolestPersonByPosition = employees.stream() + .flatMap(this::getPersonPositionDurations) + .collect(toMap(PersonPositionDuration::getPosition, + Function.identity(), + BinaryOperator.maxBy(comparing(PersonPositionDuration::getDuration)))); assertEquals(new Person("John", "White", 22), coolestPersonByPosition.get("QA").getPerson()); @@ -198,10 +245,17 @@ public void getCoolestPersonByPosition1() { @Test public void getCoolestPersonByPosition2() { - // Get person with max duration on given position final List employees = getEmployees(); - final Map coolestPersonByPosition = null; // TODO + final Map coolestPersonByPosition = employees.stream() + .flatMap(this::getPersonPositionDurations) + .collect(groupingBy(PersonPositionDuration::getPosition, + collectingAndThen( + maxBy(comparing( + PersonPositionDuration::getDuration + )), + ppd -> ppd.get().getPerson() + ))); assertEquals(new Person("John", "White", 22), coolestPersonByPosition.get("QA"));