diff --git a/src/test/java/part2/exercise/CollectorsExercise1.java b/src/test/java/part2/exercise/CollectorsExercise1.java index 46b6765..e09d987 100755 --- a/src/test/java/part2/exercise/CollectorsExercise1.java +++ b/src/test/java/part2/exercise/CollectorsExercise1.java @@ -16,7 +16,7 @@ import java.util.stream.IntStream; import java.util.stream.Stream; -import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.*; public class CollectorsExercise1 { @@ -61,8 +61,10 @@ private Map getCoolestByPosition(List employees) { // Second option // Collectors.toMap // iterate twice: stream...collect(...).stream()... - // TODO - throw new UnsupportedOperationException(); + return getPersonPositionDurationStream(employees) + .collect(groupingBy(PersonPositionDuration::getPosition, + collectingAndThen(maxBy(Comparator.comparing(PersonPositionDuration::getDuration)), + p -> p.get().getPerson()))); } @Test @@ -72,11 +74,59 @@ public void getTheCoolestOne2() { coolestByPosition.forEach((position, person) -> System.out.println(position + " -> " + person)); } + private Stream getPersonPositionDurationStream(List employees) { + return employees.stream().flatMap(e -> e.getJobHistory().stream() + .map(j -> new PersonPositionDuration(e.getPerson(), j.getPosition(), j.getDuration()))); + } + // 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 getPersonPositionDurationStream(employees).collect( + new Collector, Map>() { + @Override + public Supplier> supplier() { + return HashMap::new; + } + + @Override + public BiConsumer, PersonPositionDuration> accumulator() { + return (map, ppd) -> { + map.putIfAbsent(ppd.getPosition(), ppd); + PersonPositionDuration currentPpd = map.get(ppd.getPosition()); + if (ppd.getDuration() > currentPpd.getDuration()) { + map.put(ppd.getPosition(), ppd); + } + }; + } + + @Override + public BinaryOperator> combiner() { + return (m1, m2) -> { + m2.forEach((k, v) -> m1.merge(k, v, (v1, v2) -> v1.getDuration() > v2.getDuration() ? v1 : v2)); + return m1; + }; + } + + @Override + public Function, Map> finisher() { + return map -> map.entrySet() + .stream() + .collect( + Collectors.toMap( + Map.Entry::getKey, + item -> item.getValue().getPerson() + ) + ); + } + + @Override + public Set characteristics() { + return Collections.unmodifiableSet(EnumSet.of(Characteristics.UNORDERED)); + } + } + ); } private List getEmployees() { diff --git a/src/test/java/part2/exercise/CollectorsExercise2.java b/src/test/java/part2/exercise/CollectorsExercise2.java index 00fda00..0347ff8 100755 --- a/src/test/java/part2/exercise/CollectorsExercise2.java +++ b/src/test/java/part2/exercise/CollectorsExercise2.java @@ -17,6 +17,9 @@ import java.util.stream.Stream; import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toMap; +import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.Assert.assertThat; public class CollectorsExercise2 { @@ -176,24 +179,61 @@ public void collectKeyValueMap() { // final Map> keyValuesMap1 = valueMap1.entrySet().stream()... // В 1 проход в 2 Map с использованием MapPair и mapMerger + + Map keyMap1 = pairs.stream() + .collect( + toMap( + p -> p.getKey().getId(), + Pair::getKey, + (v1, v2) -> v1 + ) + ); + + Map> valuesMap1 = pairs.stream() + .collect( + Collectors.groupingBy( + p -> p.getValue().getKeyId(), + Collectors.mapping(Pair::getValue, toList()) + ) + ); + + Map> keyValuesMap1 = valuesMap1.entrySet().stream() + .collect( + toMap( + p -> keyMap1.get(p.getKey()), + Map.Entry::getValue + ) + ); 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().computeIfAbsent(p.getKey().getId(), q -> p.getKey()); + mp.getValueById().computeIfAbsent(p.getValue().getKeyId(), q -> new ArrayList<>()) + .add(p.getValue()); + + }; } @Override public BinaryOperator combiner() { - // TODO use mapMerger - throw new UnsupportedOperationException(); + return (mp1,mp2) -> { + BinaryOperator> binaryOperator = mapMerger((v1,v2) -> v1); + Map map = binaryOperator.apply(mp1.getKeyById(), mp2.getKeyById()); + BinaryOperator>> mapBinaryOperator = mapMerger((v1,v2) -> { + v1.addAll(v2); + return v1; + }); + Map> listMap = mapBinaryOperator.apply(mp1.getValueById(), + mp2.getValueById()); + return new MapPair(map, listMap); + }; } @Override @@ -214,44 +254,11 @@ public Set characteristics() { // 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(); + final Map> keyValuesMap2 = valuesMap2.entrySet().stream().collect(toMap(e -> keyMap2.get(e.getKey()), Map.Entry::getValue)); // compare results + assertThat(keyMap1, equalTo(keyMap2)); + assertThat(keyValuesMap1.keySet(), equalTo(keyValuesMap2.keySet())); } }