From bfc827bcc9ab863e7b3de74ffcbc8c8df8775305 Mon Sep 17 00:00:00 2001 From: Elena_Fedorovskaia Date: Tue, 18 Jul 2017 15:50:19 +0300 Subject: [PATCH] Part 3 is done --- .../part2/exercise/CollectorsExercise2.java | 216 ++++++++++-------- .../part3/exercise/CollectorCombination.java | 120 +++++++++- .../part3/exercise/lambda/LambdaExercise.java | 45 ++-- .../exercise/stream/StreamsExercise.java | 85 +++++-- 4 files changed, 315 insertions(+), 151 deletions(-) diff --git a/src/test/java/part2/exercise/CollectorsExercise2.java b/src/test/java/part2/exercise/CollectorsExercise2.java index 00fda00..50c4e88 100755 --- a/src/test/java/part2/exercise/CollectorsExercise2.java +++ b/src/test/java/part2/exercise/CollectorsExercise2.java @@ -131,7 +131,7 @@ public Map> getKnownKeys() { } } - private static class MapPair { + public static class MapPair { private final Map keyById; private final Map> valueById; @@ -151,107 +151,121 @@ public Map getKeyById() { public Map> getValueById() { return valueById; } - } - private static > - BinaryOperator mapMerger(BinaryOperator mergeFunction) { - return (m1, m2) -> { - for (Map.Entry e : m2.entrySet()) { - m1.merge(e.getKey(), e.getValue(), mergeFunction); - } - return m1; - }; - } + public void put(Pair p) { + keyById.put(p.getKey().getId(), p.getKey()); + final ArrayList value = new ArrayList<>(); + value.add(p.getValue()); + valueById.merge(p.getValue().getKeyId(), + value, + (l1, l2) -> { + l1.addAll(l2); + return l1; + }); + - @Test - public void collectKeyValueMap() { - final List pairs = generatePairs(10, 100); - - // В два прохода - // final Map keyMap1 = pairs.stream()... - - // final Map> valuesMap1 = pairs.stream()... - - // В каждом Map.Entry id ключа должно совпадать с keyId для каждого значения в списке - // final Map> keyValuesMap1 = valueMap1.entrySet().stream()... - - // В 1 проход в 2 Map с использованием MapPair и mapMerger - final MapPair res2 = pairs.stream() - .collect(new Collector() { - @Override - public Supplier supplier() { - // TODO - throw new UnsupportedOperationException(); - } - - @Override - public BiConsumer accumulator() { - // TODO add key and value to maps - throw new UnsupportedOperationException(); - } - - @Override - public BinaryOperator combiner() { - // TODO use mapMerger - throw new UnsupportedOperationException(); - } - - @Override - public Function finisher() { - return Function.identity(); - } - - @Override - public Set characteristics() { - return Collections.unmodifiableSet(EnumSet.of( - Characteristics.UNORDERED, - Characteristics.IDENTITY_FINISH)); - } - }); - - final Map keyMap2 = res2.getKeyById(); - final Map> valuesMap2 = res2.getValueById(); - - // final Map> keyValuesMap2 = valueMap2.entrySet().stream()... - - // Получение результата сразу: - - final SubResult res3 = pairs.stream() - .collect(new Collector() { - @Override - public Supplier supplier() { - // TODO - throw new UnsupportedOperationException(); - } - - @Override - public BiConsumer accumulator() { - // TODO add key to map, then check value.keyId and add it to one of maps - throw new UnsupportedOperationException(); - } - - @Override - public BinaryOperator combiner() { - // TODO use mapMerger, then check all valuesWithoutKeys - throw new UnsupportedOperationException(); - } - - @Override - public Function finisher() { - // TODO use mapMerger, then check all valuesWithoutKeys - throw new UnsupportedOperationException(); - } - - @Override - public Set characteristics() { - return Collections.unmodifiableSet(EnumSet.of( - Characteristics.UNORDERED)); - } - }); - - final Map> keyValuesMap3 = res3.getSubResult(); - - // compare results + } } -} + public static > + BinaryOperator mapMerger(BinaryOperator mergeFunction) { + return (m1, m2) -> { + for (Map.Entry e : m2.entrySet()) { + m1.merge(e.getKey(), e.getValue(), mergeFunction); + } + return m1; + }; + } + + @Test + public void collectKeyValueMap() { + final List pairs = generatePairs(10, 100); + + // В два прохода + // final Map keyMap1 = pairs.stream()... + + // final Map> valuesMap1 = pairs.stream()... + + // В каждом Map.Entry id ключа должно совпадать с keyId для каждого значения в списке + // final Map> keyValuesMap1 = valueMap1.entrySet().stream()... + + // В 1 проход в 2 Map с использованием MapPair и mapMerger + final MapPair res2 = pairs.stream() + .collect(new Collector() { + @Override + public Supplier supplier() { + // TODO + throw new UnsupportedOperationException(); + } + + @Override + public BiConsumer accumulator() { + // TODO add key and value to maps + throw new UnsupportedOperationException(); + } + + @Override + public BinaryOperator combiner() { + // TODO use mapMerger + throw new UnsupportedOperationException(); + } + + @Override + public Function finisher() { + return Function.identity(); + } + + @Override + public Set characteristics() { + return Collections.unmodifiableSet(EnumSet.of( + Characteristics.UNORDERED, + Characteristics.IDENTITY_FINISH)); + } + }); + + final Map keyMap2 = res2.getKeyById(); + final Map> valuesMap2 = res2.getValueById(); + + // final Map> keyValuesMap2 = valueMap2.entrySet().stream()... + + // Получение результата сразу: + + final SubResult res3 = pairs.stream() + .collect(new Collector() { + @Override + public Supplier supplier() { + // TODO + throw new UnsupportedOperationException(); + } + + @Override + public BiConsumer accumulator() { + // TODO add key to map, then check value.keyId and add it to one of maps + throw new UnsupportedOperationException(); + } + + @Override + public BinaryOperator combiner() { + // TODO use mapMerger, then check all valuesWithoutKeys + throw new UnsupportedOperationException(); + } + + @Override + public Function finisher() { + // TODO use mapMerger, then check all valuesWithoutKeys + throw new UnsupportedOperationException(); + } + + @Override + public Set characteristics() { + return Collections.unmodifiableSet(EnumSet.of( + Characteristics.UNORDERED)); + } + }); + + final Map> keyValuesMap3 = res3.getSubResult(); + + // compare results + } + + } diff --git a/src/test/java/part3/exercise/CollectorCombination.java b/src/test/java/part3/exercise/CollectorCombination.java index 15a42d5..a0a61a1 100755 --- a/src/test/java/part3/exercise/CollectorCombination.java +++ b/src/test/java/part3/exercise/CollectorCombination.java @@ -5,12 +5,15 @@ import part2.exercise.CollectorsExercise2.Key; import part2.exercise.CollectorsExercise2.Value; -import java.util.List; -import java.util.Map; +import java.util.*; +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.*; +import static org.junit.Assert.assertEquals; public class CollectorCombination { @@ -34,31 +37,124 @@ 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 (pair, t) -> { + c1.accumulator().accept(pair.getA(), t); + c2.accumulator().accept(pair.getB(), t); + }; + } + + @Override + public BinaryOperator> combiner() { + return (p1, p2) -> new Pair<>( + c1.combiner().apply(p1.getA(), p2.getA()), + c2.combiner().apply(p1.getB(), p2.getB())); + } + + @Override + public Function, Pair> finisher() { + return p -> new Pair<>( + c1.finisher().apply(p.getA()), + c2.finisher().apply(p.getB())); + } + + @Override + public Set characteristics() { + Set set = new HashSet<>(); + set.addAll(c1.characteristics()); + set.addAll(c2.characteristics()); + return set; + } + }; } @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() + final Map> res1 = pairs.stream() + .collect(collectingAndThen( + new Collector() { + @Override + public Supplier supplier() { + + return CollectorsExercise2.MapPair::new; + } + + public BiConsumer accumulator() { + + return CollectorsExercise2.MapPair::put; + } + + @Override + public BinaryOperator combiner() { + + return (mapPair, mapPair2) -> { + BinaryOperator> keyMerger = CollectorsExercise2.mapMerger((v1, v2) -> v1); + keyMerger.apply(mapPair.getKeyById(), mapPair2.getKeyById()); + BinaryOperator>> valueMerger = + CollectorsExercise2.mapMerger((v1, v2) -> { + v1.addAll(v2); + return v1; + }); + valueMerger.apply(mapPair.getValueById(), mapPair2.getValueById()); + return mapPair; + }; + } + + @Override + public Function finisher() { + return Function.identity(); + } + + @Override + public Set characteristics() { + return Collections.unmodifiableSet(EnumSet.of( + Characteristics.UNORDERED, + Characteristics.IDENTITY_FINISH)); + } + }, + (CollectorsExercise2.MapPair mmp) -> mmp.getKeyById().entrySet().stream() + .map(kp -> new AbstractMap.SimpleEntry<>(kp.getValue(), mmp.getValueById().get(kp.getKey()))) + .collect(toMap( + Map.Entry::getKey, + Map.Entry::getValue + )) + ) + ); + + + final Map> res2 = pairs.stream() .collect( - paired( - mapping(CollectorsExercise2.Pair::getKey, toMap(Key::getId, Function.identity(), (x, y) -> x)), - mapping(CollectorsExercise2.Pair::getValue, groupingBy(Value::getKeyId)) + collectingAndThen( + paired( + mapping(CollectorsExercise2.Pair::getKey, + toMap(Key::getId, Function.identity(), (x, y) -> x)), + mapping(CollectorsExercise2.Pair::getValue, + groupingBy(Value::getKeyId)) + ), + mmp -> mmp.getA().entrySet().stream() + .map(kp -> new AbstractMap.SimpleEntry<>(kp.getValue(), mmp.getB().get(kp.getKey()))) + .collect(toMap( + Map.Entry::getKey, + Map.Entry::getValue + )) ) ); - // TODO tests - throw new UnsupportedOperationException(); + assertEquals(res1, res2); } } diff --git a/src/test/java/part3/exercise/lambda/LambdaExercise.java b/src/test/java/part3/exercise/lambda/LambdaExercise.java index 752e1f2..6136bed 100755 --- a/src/test/java/part3/exercise/lambda/LambdaExercise.java +++ b/src/test/java/part3/exercise/lambda/LambdaExercise.java @@ -13,23 +13,28 @@ public class LambdaExercise { @Test public void supply() { + + //Who is John Galt? :) 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 Person person = new Person("John", "Galt", 30); - final Function getPersonName2 = null; // TODO get the name of person using method reference + final Function getPersonName1 = p -> p.getFirstName(); - // TODO get the name of person and log it to System.out using statement lambda: {} - final Function getPersonNameAndLogIt = null; + final Function getPersonName2 = Person::getFirstName; - final Person person = new Person("John", "Galt", 30); + final Function getPersonNameAndLogIt = p -> { + final String name = p.getFirstName(); + System.out.println(name); + return name; + }; assertEquals(person.getFirstName(), getPersonName1.apply(person)); assertEquals(person.getFirstName(), getPersonName2.apply(person)); @@ -38,21 +43,20 @@ public void function() { @Test public void combineFunctions() { - final Function getPersonName = null; // TODO get the name of person + final Person person = new Person("John", "Galt", 30); + + 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 = p -> getStringLength.apply(getPersonName.apply(p)); - // 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); assertEquals(Integer.valueOf(4), getPersonNameLength1.apply(person)); assertEquals(Integer.valueOf(4), getPersonNameLength2.apply(person)); @@ -68,26 +72,29 @@ private Person createPerson(PersonFactory pf) { // ((T -> R), (R -> boolean)) -> (T -> boolean) private Predicate combine(Function f, Predicate p) { - // TODO - throw new UnsupportedOperationException(); + return v -> p.test(f.apply(v)); } @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 = LambdaExercise::isJohn; final Predicate isJohnPerson = combine(getPersonName, isJohnString); assertEquals(true, isJohnPerson.test(person)); } + private static boolean isJohn(String name){ + return name.equals("John"); + } + } diff --git a/src/test/java/part3/exercise/stream/StreamsExercise.java b/src/test/java/part3/exercise/stream/StreamsExercise.java index 4e2d54b..05a1809 100755 --- a/src/test/java/part3/exercise/stream/StreamsExercise.java +++ b/src/test/java/part3/exercise/stream/StreamsExercise.java @@ -6,10 +6,10 @@ 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.Collectors; import static org.junit.Assert.assertEquals; @@ -19,7 +19,8 @@ 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(Collectors.toList()); assertEquals(22, jobHistoryEntries.size()); } @@ -29,12 +30,13 @@ 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,7 +66,10 @@ public String toString() { public void indexPersonsByEmployer1() { final List employees = getEmployees(); - final Map> index = null; // TODO + final Map> index = employees.stream() + .flatMap(e -> e.getJobHistory().stream() + .map(d -> new PersonEmployer(e.getPerson(), d.getEmployer()))) + .collect(Collectors.groupingBy(PersonEmployer::getEmployer)); assertEquals(11, index.get("epam").size()); } @@ -73,7 +78,21 @@ public void indexPersonsByEmployer1() { public void indexPersonsByEmployer2() { final List employees = getEmployees(); - final Map> index = null; // TODO + final Map> index = employees.stream() + .flatMap(e -> e.getJobHistory().stream() + .map(d -> new PersonEmployer(e.getPerson(), d.getEmployer()))) + .collect(Collectors.toMap( + PersonEmployer::getEmployer, + p -> { + final List personList = new ArrayList<>(); + personList.add(p.getPerson()); + return personList; + }, + (p1, p2) -> { + p1.addAll(p2); + return p1; + } + )); assertEquals(11, index.get("epam").size()); } @@ -105,8 +124,8 @@ public String toString() { } private PersonDuration sumAllPersonDurations(Employee e) { - // TODO - throw new UnsupportedOperationException(); + return new PersonDuration(e.getPerson(), + e.getJobHistory().stream().mapToInt(JobHistoryEntry::getDuration).sum()); } @Test @@ -114,7 +133,10 @@ 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(Collectors.toMap(PersonDuration::getPerson, + PersonDuration::getDuration)); assertEquals(Integer.valueOf(8), personDuration.get(new Person("John", "Doe", 24))); } @@ -138,15 +160,17 @@ public Map getDurationByPositionIndex() { } private static PersonPositionIndex getPersonPositionIndex(Employee e) { - // TODO - throw new UnsupportedOperationException(); + return new PersonPositionIndex(e.getPerson(), e.getJobHistory().stream() + .collect(Collectors.toMap(JobHistoryEntry::getPosition, JobHistoryEntry::getDuration, Integer::sum))); } @Test public void getSumDurationsForPersonByPosition() { final List employees = getEmployees(); - final List personIndexes = null; // TODO use getPersonPositionIndex + final List personIndexes = employees.stream() + .map(StreamsExercise::getPersonPositionIndex) + .collect(Collectors.toList()); assertEquals(1, personIndexes.get(3).getDurationByPositionIndex().size()); } @@ -179,7 +203,14 @@ public int getDuration() { public void getDurationsForEachPersonByPosition() { final List employees = getEmployees(); - final List personPositionDurations = null; // TODO + final List personPositionDurations = employees.stream() + .flatMap(e -> e.getJobHistory().stream() + .map(j -> new PersonPositionDuration(e.getPerson(), j.getPosition(), j.getDuration())) + .collect(Collectors.toMap(PersonPositionDuration::getPosition, Function.identity(), + (PersonPositionDuration ppd1, PersonPositionDuration ppd2) -> + new PersonPositionDuration(ppd1.getPerson(), ppd1.getPosition(), + ppd1.getDuration() + ppd2.getDuration()))).entrySet().stream() + .map(Map.Entry::getValue)).collect(Collectors.toList()); assertEquals(17, personPositionDurations.size()); @@ -190,7 +221,16 @@ 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(e -> e.getJobHistory().stream() + .map(j -> new PersonPositionDuration(e.getPerson(), j.getPosition(), j.getDuration()))) + .collect(Collectors.groupingBy( + PersonPositionDuration::getPosition, + Collectors.collectingAndThen( + Collectors.maxBy(Comparator.comparingInt(PersonPositionDuration::getDuration)), + Optional::get + ) + )); assertEquals(new Person("John", "White", 22), coolestPersonByPosition.get("QA").getPerson()); @@ -201,8 +241,15 @@ 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(e -> e.getJobHistory().stream() + .map(j -> new PersonPositionDuration(e.getPerson(), j.getPosition(), j.getDuration()))) + .collect(Collectors.toMap( + PersonPositionDuration::getPosition, + Function.identity(), + BinaryOperator.maxBy(Comparator.comparingInt(PersonPositionDuration::getDuration)) + )).entrySet().stream() + .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getPerson())); assertEquals(new Person("John", "White", 22), coolestPersonByPosition.get("QA")); }