diff --git a/src/main/java/data/Generator.java b/src/main/java/data/Generator.java index cbd46ea..8cc7467 100644 --- a/src/main/java/data/Generator.java +++ b/src/main/java/data/Generator.java @@ -60,7 +60,10 @@ 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..86abcbf 100755 --- a/src/test/java/part1/exercise/StreamsExercise1.java +++ b/src/test/java/part1/exercise/StreamsExercise1.java @@ -5,16 +5,12 @@ import data.Person; import org.junit.Test; -import java.util.*; -import java.util.concurrent.ThreadLocalRandom; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import java.util.stream.Stream; +import java.util.ArrayList; +import java.util.List; import static data.Generator.generateEmployeeList; -import static java.util.stream.Collectors.groupingBy; -import static java.util.stream.Collectors.mapping; import static java.util.stream.Collectors.toList; +import static org.junit.Assert.assertEquals; public class StreamsExercise1 { // https://youtu.be/kxgo7Y4cdA8 Сергей Куксенко и Алексей Шипилёв — Через тернии к лямбдам, часть 1 @@ -25,20 +21,56 @@ 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(e -> e.getJobHistory().stream() + .map(JobHistoryEntry::getEmployer) + .anyMatch("epam"::equals)) + .map(Employee::getPerson) + .collect(toList()); + + assertEquals(expected, actual); } @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 (isFirstEmployerEpam(e)) + expected.add(e.getPerson()); + } + List actual = employees.stream() + .filter(StreamsExercise1::isFirstEmployerEpam) + .map(Employee::getPerson) + .collect(toList()); + + assertEquals(expected, actual); + } + + private static boolean isFirstEmployerEpam(Employee e) { + return e.getJobHistory() + .stream() + .limit(1) + .anyMatch("epam"::equals); } @Test public void sumEpamDurations() { final List employees = generateEmployeeList(); - int expected = 0; for (Employee e : employees) { @@ -48,12 +80,12 @@ public void sumEpamDurations() { } } } - - // TODO - throw new UnsupportedOperationException(); - - // int result = ??? - // assertEquals(expected, result); + int result = employees.stream() + .map(Employee::getJobHistory) + .flatMap(e -> e.stream() + .filter(h -> h.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..5d5c6a0 100755 --- a/src/test/java/part1/exercise/StreamsExercise2.java +++ b/src/test/java/part1/exercise/StreamsExercise2.java @@ -5,15 +5,11 @@ 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.stream.Stream; +import java.util.*; -import static data.Generator.generateEmployeeList; import static java.util.stream.Collectors.*; -import static org.junit.Assert.assertEquals; +import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.Assert.assertThat; public class StreamsExercise2 { // https://youtu.be/kxgo7Y4cdA8 Сергей Куксенко и Алексей Шипилёв — Через тернии к лямбдам, часть 1 @@ -22,25 +18,94 @@ public class StreamsExercise2 { // https://youtu.be/O8oN4KSZEXE Сергей Куксенко — Stream API, часть 1 // https://youtu.be/i0Jr2l3jrDA Сергей Куксенко — Stream API, часть 2 - // TODO class PersonEmployerPair + // TODO class PersonEmployerDuration + private static class PersonEmployerDuration + { + private Person person; + private String employer; + private Integer duration; + + PersonEmployerDuration(Person p, String e) { + this(p,e,0); + } + + PersonEmployerDuration(Person p, String e, Integer d) { + employer = e; + person = p; + duration = d; + } + + Person getPerson() { + return person; + } + + String getEmployer() { + return employer; + } + + int getDuration() { + return duration; + } + } @Test public void employersStuffLists() { - Map> employersStuffLists = null;// TODO - throw new UnsupportedOperationException(); + Map> employersStuffLists = getEmployees().stream() + .flatMap(e -> e.getJobHistory() + .stream() + .map(j -> new PersonEmployerDuration( + e.getPerson(), + j.getEmployer()))) + .collect(groupingBy( + PersonEmployerDuration::getEmployer, + mapping(PersonEmployerDuration::getPerson, toList()))); + + assertThat(employersStuffLists.get("Microsoft"), + equalTo(Collections.singletonList(new Person("John", "White", 25)))); } @Test public void indexByFirstEmployer() { - Map> employeesIndex = null;// TODO - throw new UnsupportedOperationException(); + Map> employeesIndex = getEmployees().stream() + .map(e -> new PersonEmployerDuration( + e.getPerson(), + e.getJobHistory().get(0).getEmployer())) + .collect(groupingBy(PersonEmployerDuration::getEmployer, + mapping(PersonEmployerDuration::getPerson, toList()))); + + assertThat(employeesIndex.get("abc"), equalTo(null)); + assertThat(employeesIndex.get("yandex"), equalTo(Arrays.asList( + new Person("John", "Doe", 21), + new Person("John", "Doe", 24), + new Person("Bob", "Doe", 27), + new Person("John", "Doe", 30)))); + } + + private static Map jobHistory(List jobHistory){ + return jobHistory.stream() + .collect(groupingBy( + JobHistoryEntry::getEmployer, + summingInt(JobHistoryEntry::getDuration))); } @Test public void greatestExperiencePerEmployer() { - Map employeesIndex = null;// TODO + Map employeesIndex = getEmployees().stream() + .flatMap(e -> jobHistory(e.getJobHistory()) + .entrySet().stream() + .map(j -> new PersonEmployerDuration( + e.getPerson(), + j.getKey(), + j.getValue())) + ) + .collect(groupingBy( + PersonEmployerDuration::getEmployer, + collectingAndThen(maxBy(Comparator.comparingInt(PersonEmployerDuration::getDuration)), + p->p.get().getPerson())) + ); + - assertEquals(new Person("John", "White", 28), employeesIndex.get("epam")); + assertThat(new Person("John", "White", 28), equalTo(employeesIndex.get("epam"))); } @@ -80,7 +145,7 @@ private List getEmployees() { new Employee( new Person("John", "White", 25), Collections.singletonList( - new JobHistoryEntry(6, "QA", "epam") + new JobHistoryEntry(6, "QA", "Microsoft") )), new Employee( new Person("John", "Galt", 26), diff --git a/src/test/java/part2/exercise/CollectorsExercise1.java b/src/test/java/part2/exercise/CollectorsExercise1.java index 46b6765..f49aa27 100755 --- a/src/test/java/part2/exercise/CollectorsExercise1.java +++ b/src/test/java/part2/exercise/CollectorsExercise1.java @@ -6,25 +6,28 @@ 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.function.*; 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.Comparator.comparing; +import static java.util.stream.Collectors.*; +import static org.hamcrest.core.Is.is; +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()); + final Map coolestByPositionVersion1 = getCoolestByPositionVersion1(getEmployees()); + final Map coolestByPositionVersion2 = getCoolestByPositionVersion2(getEmployees()); + final Map coolestByPositionVersion3 = getCoolestByPositionVersion3(getEmployees()); - coolestByPosition.forEach((position, person) -> System.out.println(position + " -> " + person)); + assertThat(coolestByPositionVersion1.get("BA"), equalTo(coolestByPositionVersion2.get("BA"))); + assertThat(coolestByPositionVersion1.get("BA"), equalTo(coolestByPositionVersion3.get("BA"))); + assertThat(coolestByPositionVersion1.get("dev"), equalTo(coolestByPositionVersion2.get("dev"))); + assertThat(coolestByPositionVersion1.get("dev"), equalTo(coolestByPositionVersion3.get("dev"))); } private static class PersonPositionDuration { @@ -52,7 +55,7 @@ public int getDuration() { } // With the longest duration on single job - private Map getCoolestByPosition(List employees) { + private Map getCoolestByPositionVersion1(List employees) { // First option // Collectors.maxBy // Collectors.collectingAndThen @@ -61,22 +64,125 @@ private Map getCoolestByPosition(List employees) { // Second option // Collectors.toMap // iterate twice: stream...collect(...).stream()... - // TODO - throw new UnsupportedOperationException(); + return employees.stream() + .flatMap(e -> e.getJobHistory() + .stream() + .map(j -> new PersonPositionDuration( + e.getPerson(), + j.getPosition(), + j.getDuration())) + ) + .collect(groupingBy( + PersonPositionDuration::getPosition, + collectingAndThen(maxBy( + comparing(PersonPositionDuration::getDuration)), + p -> p.get().getPerson()))); } + private Map getCoolestByPositionVersion2(List employees) { + return employees.stream() + .flatMap(e -> e.getJobHistory() + .stream() + .map(j -> new PersonPositionDuration( + e.getPerson(), + j.getPosition(), + j.getDuration()))) + .collect(Collectors.toMap( + PersonPositionDuration::getPosition, + Function.identity(), + (d1, d2) -> d1.getDuration() > d2.getDuration() ? d1 : d2)) + .entrySet().stream() + .collect(toMap( + Map.Entry::getKey, + e -> e.getValue().getPerson())); + } + + private Map getCoolestByPositionVersion3(List employees) { + return employees.stream() + .flatMap(e -> e.getJobHistory() + .stream() + .map(j -> new PersonPositionDuration( + e.getPerson(), + j.getPosition(), + j.getDuration()))) + .collect(new Collector, Map>() { + + @Override + public Supplier> supplier() { + return HashMap::new; + } + + @Override + public BiConsumer, PersonPositionDuration> accumulator() { + return (map, p) -> map.merge( + p.getPosition(), + p, + (p1, p2) -> p1.getDuration() > p2.getDuration() ? p1 : p2); + } + + @Override + public BinaryOperator> combiner() { + return (map1, map2) -> { + map1.putAll( + map2.entrySet().stream() + .filter(el -> !map1.containsKey(el.getKey()) + || map1.get(el.getKey()).getDuration() < el.getValue().getDuration()) + .collect(toMap( + Map.Entry::getKey, + Map.Entry::getValue)) + ); + return map1; + }; + } + + @Override + public Function, Map> finisher() { + return map -> map.entrySet().stream() + .collect(toMap( + Map.Entry::getKey, + e -> e.getValue().getPerson())); + } + + @Override + public Set characteristics() { + return Collections.EMPTY_SET; + } + }); + } + + @Test public void getTheCoolestOne2() { final Map coolestByPosition = getCoolestByPosition2(getEmployees()); - coolestByPosition.forEach((position, person) -> System.out.println(position + " -> " + person)); + assertThat(coolestByPosition.size(), is(3)); + assertThat(coolestByPosition.get("BA"), equalTo(new Person("John", "White", 28))); + assertThat(coolestByPosition.get("QA"), equalTo(new Person("John", "Doe", 24))); + } + + private static Map durationOnPositions(List jobHistory) { + return jobHistory.stream() + .collect(groupingBy( + JobHistoryEntry::getPosition, + summingInt(JobHistoryEntry::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 employees.stream() + .flatMap(employee -> durationOnPositions(employee.getJobHistory()) + .entrySet().stream() + .map(position -> new PersonPositionDuration( + employee.getPerson(), + position.getKey(), + position.getValue())) + ) + .collect(groupingBy( + PersonPositionDuration::getPosition, + collectingAndThen( + maxBy(comparing(PersonPositionDuration::getDuration)), + p -> p.get().getPerson()))); } private List getEmployees() { @@ -109,7 +215,9 @@ private List getEmployees() { new Person("John", "Doe", 24), Arrays.asList( new JobHistoryEntry(4, "QA", "yandex"), + new JobHistoryEntry(2, "QA", "epam"), new JobHistoryEntry(2, "BA", "epam"), + new JobHistoryEntry(1, "QA", "abc"), new JobHistoryEntry(2, "dev", "abc") )), new Employee( diff --git a/src/test/java/part2/exercise/CollectorsExercise2.java b/src/test/java/part2/exercise/CollectorsExercise2.java index 00fda00..4536da8 100755 --- a/src/test/java/part2/exercise/CollectorsExercise2.java +++ b/src/test/java/part2/exercise/CollectorsExercise2.java @@ -1,8 +1,5 @@ package part2.exercise; -import data.Employee; -import data.JobHistoryEntry; -import data.Person; import org.junit.Test; import java.util.*; @@ -16,8 +13,13 @@ 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; +import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.Assert.assertThat; +@SuppressWarnings("WeakerAccess") public class CollectorsExercise2 { private static String generateString() { @@ -79,6 +81,28 @@ public Value(String keyId) { public String getKeyId() { return keyId; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Value value = (Value) o; + + return keyId != null ? keyId.equals(value.keyId) : value.keyId == null; + } + + @Override + public int hashCode() { + return keyId != null ? keyId.hashCode() : 0; + } + + @Override + public String toString() { + return "Value{" + + "keyId='" + keyId + '\'' + + '}'; + } } public static class Pair { @@ -131,7 +155,7 @@ public Map> getKnownKeys() { } } - private static class MapPair { + public static class MapPair { private final Map keyById; private final Map> valueById; @@ -168,32 +192,74 @@ public void collectKeyValueMap() { final List pairs = generatePairs(10, 100); // В два прохода - // final Map keyMap1 = pairs.stream()... + final Map keyMap1 = pairs.stream() + .map(Pair::getKey) + .collect(toMap(Key::getId, Function.identity(), (k1, k2) -> k2)); - // final Map> valuesMap1 = pairs.stream()... + final Map> valueMap1 = pairs.stream() + .map(Pair::getValue) + .collect(groupingBy(Value::getKeyId)); // В каждом Map.Entry id ключа должно совпадать с keyId для каждого значения в списке - // final Map> keyValuesMap1 = valueMap1.entrySet().stream()... + final Map> keyValuesMap1 = valueMap1.entrySet().stream() + .collect(toMap(e -> keyMap1.get(e.getKey()), + Map.Entry::getValue)); // В 1 проход в 2 Map с использованием MapPair и mapMerger - final MapPair res2 = pairs.stream() + final MapPair res2 = getMapPair(pairs); + + final Map keyMap2 = res2.getKeyById(); + final Map> valuesMap2 = res2.getValueById(); + + final Map> keyValuesMap2 = valuesMap2 + .entrySet().stream() + .collect(toMap(e->keyMap2.get(e.getKey()), + Map.Entry::getValue)); + + assertThat(keyMap1, equalTo(keyMap2)); + assertThat(keyValuesMap1.keySet(), equalTo(keyValuesMap2.keySet())); + + Key randomKey = keyMap1.entrySet().stream() + .map(Map.Entry::getValue) + .findAny() + .orElse(null); + assertThat(keyValuesMap1.get(randomKey), equalTo(keyValuesMap2.get(randomKey))); + } + + public static MapPair getMapPair(List pairs) { + return 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 (map, pair) -> { + map.getKeyById().merge(pair.getKey().getId(), pair.getKey(), (key, key2) -> key); + map.getValueById() + .computeIfAbsent(pair.getValue().getKeyId(), (t) -> new ArrayList<>()) + .add(pair.getValue()); + }; } @Override public BinaryOperator combiner() { - // TODO use mapMerger - throw new UnsupportedOperationException(); + return (map1, map2) -> { + BinaryOperator> mapBinaryOperator = mapMerger((o, o2) -> o); + BinaryOperator>> mapBinaryOperatorToo = mapMerger((list, list2) -> { + list.addAll(list2); + return list; + }); + + Map keyMap = + mapBinaryOperator.apply(map1.getKeyById(), map2.getKeyById()); + Map> valueMap = + mapBinaryOperatorToo.apply(map1.getValueById(), map2.getValueById()); + + return new MapPair(keyMap, valueMap); + }; } @Override @@ -208,50 +274,5 @@ public Set characteristics() { 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..b34d379 100755 --- a/src/test/java/part3/exercise/CollectorCombination.java +++ b/src/test/java/part3/exercise/CollectorCombination.java @@ -5,12 +5,19 @@ 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.*; +import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.Assert.assertThat; public class CollectorCombination { @@ -34,19 +41,46 @@ 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 (m1M2Pair, m1M2Pair2) -> { + M1 m1 = c1.combiner().apply(m1M2Pair.getA(), m1M2Pair2.getA()); + M2 m2 = c2.combiner().apply(m1M2Pair.getB(), m1M2Pair2.getB()); + return new Pair<>(m1, m2); + }; + } + + @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 List pairs = CollectorsExercise2.generatePairs(8, 100); final Pair, Map>> res2 = pairs.stream() .collect( @@ -56,9 +90,14 @@ public void collectKeyValueMap() { ) ); + CollectorsExercise2.MapPair mapPair = CollectorsExercise2.getMapPair(pairs); + assertThat(res2.getA(), equalTo(mapPair.getKeyById())); - // TODO tests - throw new UnsupportedOperationException(); + String randomKey = mapPair.getKeyById().entrySet().stream() + .map(Map.Entry::getKey) + .findAny() + .orElse(null); + assertThat(mapPair.getValueById().get(randomKey), equalTo(res2.getB().get(randomKey))); } -} +} \ No newline at end of file diff --git a/src/test/java/part3/exercise/lambda/LambdaExercise.java b/src/test/java/part3/exercise/lambda/LambdaExercise.java index 752e1f2..190dc5b 100755 --- a/src/test/java/part3/exercise/lambda/LambdaExercise.java +++ b/src/test/java/part3/exercise/lambda/LambdaExercise.java @@ -15,19 +15,23 @@ 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; // TODO return person from Supplier 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(); // TODO get the name of person using expression lambda - final Function getPersonName2 = null; // TODO get the name of person using method reference + final Function getPersonName2 = Person::getFirstName; // TODO get the name of person using method reference // TODO get the name of person and log it to System.out using statement lambda: {} - final Function getPersonNameAndLogIt = null; + final Function getPersonNameAndLogIt = person -> { + String name = person.getFirstName(); + System.out.println(name); + return name; + }; final Person person = new Person("John", "Galt", 30); @@ -38,19 +42,19 @@ public void function() { @Test public void combineFunctions() { - final Function getPersonName = null; // TODO get the name of person + final Function getPersonName = Person::getFirstName; // TODO get the name of person assertEquals("John", getPersonName.apply(new Person("John", "Galt", 30))); - final Function getStringLength = null; // TODO get string length + final Function getStringLength = String::length; // TODO get 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); @@ -68,22 +72,21 @@ 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); // TODO assertEquals(new Person("John", "Galt", 66), person); - final Function getPersonName = null; // TODO + final Function getPersonName = Person::getFirstName; // TODO assertEquals("John", getPersonName.apply(person)); - final Predicate isJohnString = null; // TODO using method reference check that "John" equals string parameter + final Predicate isJohnString = "John"::equals; // TODO using method reference check that "John" equals string parameter 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..37911e8 100755 --- a/src/test/java/part3/exercise/stream/StreamsExercise.java +++ b/src/test/java/part3/exercise/stream/StreamsExercise.java @@ -10,16 +10,25 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.function.BinaryOperator; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import static java.util.Comparator.comparingInt; +import static java.util.stream.Collectors.*; import static org.junit.Assert.assertEquals; +@SuppressWarnings("WeakerAccess") public class StreamsExercise { @Test 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()); } @@ -29,12 +38,15 @@ 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 +76,24 @@ public String toString() { public void indexPersonsByEmployer1() { final List employees = getEmployees(); - final Map> index = null; // TODO - + final Map> index = getPersonEmployerStream(employees) + .collect(groupingBy(PersonEmployer::getEmployer)); assertEquals(11, index.get("epam").size()); } + private static Stream getPersonEmployerStream(List employees) { + return employees.stream() + .flatMap(e -> e.getJobHistory().stream() + .map(t -> new PersonEmployer(e.getPerson(), t.getEmployer()))); + } + @Test public void indexPersonsByEmployer2() { final List employees = getEmployees(); - final Map> index = null; // TODO + final Map> index = getPersonEmployerStream(employees) + .collect(groupingBy(PersonEmployer::getEmployer, + mapping(PersonEmployer::getPerson, toList()))); assertEquals(11, index.get("epam").size()); } @@ -105,8 +125,11 @@ 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 @@ -114,7 +137,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(toMap(PersonDuration::getPerson, + PersonDuration::getDuration)); assertEquals(Integer.valueOf(8), personDuration.get(new Person("John", "Doe", 24))); } @@ -138,15 +164,19 @@ public Map getDurationByPositionIndex() { } private static PersonPositionIndex getPersonPositionIndex(Employee e) { - // TODO - throw new UnsupportedOperationException(); + Map collect = e.getJobHistory().stream() + .collect(groupingBy(JobHistoryEntry::getPosition, + summingInt(JobHistoryEntry::getDuration))); + return new PersonPositionIndex(e.getPerson(), collect); } @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 +209,31 @@ public int getDuration() { public void getDurationsForEachPersonByPosition() { final List employees = getEmployees(); - final List personPositionDurations = null; // TODO + final List personPositionDurations = getPersonPositionDurationStream(employees) + .collect(toList()); assertEquals(17, personPositionDurations.size()); } + private Stream getPersonPositionDurationStream(List employees) { + return employees.stream() + .map(StreamsExercise::getPersonPositionIndex) + .flatMap(e -> e.getDurationByPositionIndex().entrySet().stream() + .map(p -> new PersonPositionDuration(e.getPerson(), p.getKey(), p.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 = + getPersonPositionDurationStream(employees) + .collect(toMap( + PersonPositionDuration::getPosition, + Function.identity(), + BinaryOperator.maxBy(comparingInt(PersonPositionDuration::getDuration)))); assertEquals(new Person("John", "White", 22), coolestPersonByPosition.get("QA").getPerson()); @@ -201,7 +244,11 @@ public void getCoolestPersonByPosition2() { // Get person with max duration on given position final List employees = getEmployees(); - final Map coolestPersonByPosition = null; // TODO + final Map coolestPersonByPosition = + getPersonPositionDurationStream(employees) + .collect(groupingBy(PersonPositionDuration::getPosition, + collectingAndThen(Collectors.maxBy(comparingInt(PersonPositionDuration::getDuration)), + o -> o.get().getPerson()))); assertEquals(new Person("John", "White", 22), coolestPersonByPosition.get("QA"));