diff --git a/src/test/java/lambda/part3/exercise/Mapping.java b/src/test/java/lambda/part3/exercise/Mapping.java index c0a814a..aa6634d 100644 --- a/src/test/java/lambda/part3/exercise/Mapping.java +++ b/src/test/java/lambda/part3/exercise/Mapping.java @@ -9,7 +9,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; @@ -32,8 +31,9 @@ public List getList() { // [T] -> (T -> R) -> [R] // [T1, T2, T3] -> (T -> R) -> [R1, R2, R3] public MapHelper map(Function f) { - // TODO - throw new UnsupportedOperationException(); + List rs = new ArrayList<>(); + list.forEach(t -> rs.add(f.apply(t))); + return new MapHelper<>(rs); } // [T] -> (T -> [R]) -> [R] @@ -43,13 +43,25 @@ public MapHelper map(Function f) { public MapHelper flatMap(Function> f) { final List result = new ArrayList(); list.forEach((T t) -> - f.apply(t).forEach(result::add) + result.addAll(f.apply(t)) ); return new MapHelper(result); } } + private List addOneYear(List entries){ + MapHelper res = new MapHelper<>(entries); + return res.map(e -> e.withDuration(e.getDuration() + 1)).getList(); + } + + private List renamePosition(List entries, String from, String to){ + return new MapHelper<>(entries) + .map(jobHistoryEntry -> jobHistoryEntry.getPosition().equals(from) ? + jobHistoryEntry.withPosition(to) : + jobHistoryEntry).getList(); + } + @Test public void mapping() { final List employees = @@ -76,12 +88,15 @@ public void mapping() { final List mappedEmployees = new MapHelper<>(employees) + .map(employee -> employee.withPerson(employee.getPerson().withFirstName("John"))) + .map(employee -> employee.withJobHistory(addOneYear(employee.getJobHistory()))) + .map(employee -> employee.withJobHistory(renamePosition(employee.getJobHistory(), "qa", "QA"))) + .getList(); /* .map(TODO) // change name to John .map(e -> e.withPerson(e.getPerson().withFirstName("John"))) .map(TODO) // add 1 year to experience duration .map(e -> e.withJobHistory(addOneYear(e.getJobHistory()))) .map(TODO) // replace qa with QA * */ - .getList(); final List expectedResult = Arrays.asList( @@ -224,4 +239,198 @@ public void lazy_mapping() { assertEquals(mappedEmployees, expectedResult); } + + + interface Traversable { + void forEach(Consumer c); + + default Traversable map(Function f) { + Traversable self = this; + + return new Traversable() { + @Override + public void forEach(Consumer c) { + self.forEach(t -> c.accept(f.apply(t))); + } + }; + } + + default Traversable filter(Predicate p) { + Traversable self = this; + + return new Traversable() { + @Override + public void forEach(Consumer c) { + self.forEach(t -> { + if (p.test(t)) { + c.accept(t); + } + }); + } + }; + } + + default Traversable flatMap(Function> f) { + Traversable self = this; + + return new Traversable() { + @Override + public void forEach(Consumer c) { + self.forEach(t -> f.apply(t).forEach(c)); + } + }; + } + + static Traversable from(List l) { + return new Traversable() { + @Override + public void forEach(Consumer action) { + l.forEach(action); + } + }; + } + + default List force() { + final List res = new ArrayList<>(); + this.forEach(res::add); + return res; + } + } + + @Test + public void traversalMapTests() { + + final List employees = + Arrays.asList( + new Employee( + new Person("a", "Galt", 30), + Arrays.asList( + new JobHistoryEntry(2, "dev", "epam"), + new JobHistoryEntry(1, "dev", "google") + )), + new Employee( + new Person("b", "Doe", 40), + Arrays.asList( + new JobHistoryEntry(3, "qa", "yandex"), + new JobHistoryEntry(1, "qa", "epam"), + new JobHistoryEntry(1, "dev", "abc") + )), + new Employee( + new Person("c", "White", 50), + Collections.singletonList( + new JobHistoryEntry(5, "qa", "epam") + )) + ); + + final List mappedEmployees = + Traversable.from(employees) + .map(e -> e.withPerson(e.getPerson().withFirstName("John"))) + .force(); + + final List expectedResult = + Arrays.asList( + new Employee( + new Person("John", "Galt", 30), + Arrays.asList( + new JobHistoryEntry(2, "dev", "epam"), + new JobHistoryEntry(1, "dev", "google") + )), + new Employee( + new Person("John", "Doe", 40), + Arrays.asList( + new JobHistoryEntry(3, "qa", "yandex"), + new JobHistoryEntry(1, "qa", "epam"), + new JobHistoryEntry(1, "dev", "abc") + )), + new Employee( + new Person("John", "White", 50), + Collections.singletonList( + new JobHistoryEntry(5, "qa", "epam") + )) + ); + + assertEquals(mappedEmployees, expectedResult); + } + + @Test + public void traversalFilterTests() { + List employees = + Arrays.asList( + new Employee( + new Person("a", "Galt", 30), + Arrays.asList( + new JobHistoryEntry(2, "dev", "epam"), + new JobHistoryEntry(1, "dev", "google") + )), + new Employee( + new Person("b", "Doe", 40), + Arrays.asList( + new JobHistoryEntry(3, "qa", "yandex"), + new JobHistoryEntry(1, "qa", "epam"), + new JobHistoryEntry(1, "dev", "abc") + )), + new Employee( + new Person("c", "White", 50), + Collections.singletonList( + new JobHistoryEntry(5, "qa", "epam") + )) + ); + + final List filteredEmployees = + Traversable.from(employees) + .filter(e -> e.getPerson().getAge() == 40).force(); + + final List expectedResult = + Arrays.asList( + new Employee( + new Person("b", "Doe", 40), + Arrays.asList( + new JobHistoryEntry(3, "qa", "yandex"), + new JobHistoryEntry(1, "qa", "epam"), + new JobHistoryEntry(1, "dev", "abc") + )) + ); + + assertEquals(filteredEmployees, expectedResult); + } + + @Test + public void traversalFlatMapTests() { + List employees = + Arrays.asList( + new Employee( + new Person("a", "Galt", 30), + Arrays.asList( + new JobHistoryEntry(2, "dev", "epam"), + new JobHistoryEntry(1, "dev", "google") + )), + new Employee( + new Person("b", "Doe", 40), + Arrays.asList( + new JobHistoryEntry(3, "qa", "yandex"), + new JobHistoryEntry(1, "qa", "epam"), + new JobHistoryEntry(1, "dev", "abc") + )), + new Employee( + new Person("c", "White", 50), + Collections.singletonList( + new JobHistoryEntry(5, "qa", "epam") + )) + ); + + final List flatMappedEmployees = + Traversable.from(employees) + .filter(e -> e.getPerson().getAge() == 40) + .flatMap(e -> Traversable.from(e.getJobHistory())).force(); + + final List expectedResult = + Arrays.asList( + new JobHistoryEntry(3, "qa", "yandex"), + new JobHistoryEntry(1, "qa", "epam"), + new JobHistoryEntry(1, "dev", "abc") + + ); + + assertEquals(flatMappedEmployees, expectedResult); + } }