From b14c581bce0b70aa79f7d47236179692d9bf11ce Mon Sep 17 00:00:00 2001 From: Andrei Andronov Date: Thu, 6 Jul 2017 11:39:16 +0300 Subject: [PATCH 1/3] part 3 was done partially, without LazyFlatMapHelper realisation --- .../java/lambda/part3/exercise/Mapping.java | 54 ++++++++++++------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/src/test/java/lambda/part3/exercise/Mapping.java b/src/test/java/lambda/part3/exercise/Mapping.java index c0a814a..01f0a12 100644 --- a/src/test/java/lambda/part3/exercise/Mapping.java +++ b/src/test/java/lambda/part3/exercise/Mapping.java @@ -9,10 +9,7 @@ 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; import static org.junit.Assert.assertEquals; @@ -32,8 +29,10 @@ public List getList() { // [T] -> (T -> R) -> [R] // [T1, T2, T3] -> (T -> R) -> [R1, R2, R3] public MapHelper map(Function f) { - // TODO - throw new UnsupportedOperationException(); + final List result = new ArrayList<>(); + list.forEach(t -> + result.add(f.apply(t))); + return new MapHelper<>(result); } // [T] -> (T -> [R]) -> [R] @@ -76,11 +75,9 @@ public void mapping() { final List mappedEmployees = new MapHelper<>(employees) - /* - .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 - * */ + .map(e -> e.withPerson(e.getPerson().withFirstName("John"))) + .map(e -> e.withJobHistory(addOneYear(e.getJobHistory()))) + .map(e -> e.withJobHistory(qaToUpperCase(e.getJobHistory()))) .getList(); final List expectedResult = @@ -108,10 +105,30 @@ public void mapping() { assertEquals(mappedEmployees, expectedResult); } + // [JobHistoryEntry] -> (JobHistoryEntry -> JobHistoryEntry) -> [JobHistoryEntry] + private static List qaToUpperCase(List list) { + return new MapHelper<>(list) + .map(entry -> + entry.getPosition().equals("qa") ? entry.withPosition("QA") : entry) + .getList(); + } + + // [JobHistoryEntry] -> (JobHistoryEntry -> JobHistoryEntry) -> [JobHistoryEntry] + private static List addOneYear(List list) { + return new MapHelper<>(list) + .map(entry -> + entry.withDuration(entry.getDuration() + 1)) + .getList(); + } private static class LazyMapHelper { - public LazyMapHelper(List list, Function function) { + private final List list; + private final Function function; + + private LazyMapHelper(List list, Function function) { + this.list = list; + this.function = function; } public static LazyMapHelper from(List list) { @@ -119,13 +136,12 @@ public static LazyMapHelper from(List list) { } public List force() { - // TODO - throw new UnsupportedOperationException(); + return new MapHelper<>(list).map(function).getList(); } public LazyMapHelper map(Function f) { - // TODO - throw new UnsupportedOperationException(); + Function newFunction = function.andThen(f); + return new LazyMapHelper<>(list, newFunction); } } @@ -193,11 +209,9 @@ public void lazy_mapping() { final List mappedEmployees = LazyMapHelper.from(employees) - /* - .map(TODO) // change name to John - .map(TODO) // add 1 year to experience duration - .map(TODO) // replace qa with QA - * */ + .map(e -> e.withPerson(e.getPerson().withFirstName("John"))) // change name to John + .map(e -> e.withJobHistory(addOneYear(e.getJobHistory()))) // add 1 year to experience duration + .map(e -> e.withJobHistory(qaToUpperCase(e.getJobHistory()))) // replace qa with QA .force(); final List expectedResult = From 5b3c6e0b5a994407eeeae3169210805f204515f1 Mon Sep 17 00:00:00 2001 From: Andrei Andronov Date: Thu, 6 Jul 2017 17:30:11 +0300 Subject: [PATCH 2/3] part 3 Traversable flatMap and filter were done. ReachIterable is in process --- .../java/lambda/part3/exercise/Mapping.java | 131 +++++++++++++++--- 1 file changed, 109 insertions(+), 22 deletions(-) diff --git a/src/test/java/lambda/part3/exercise/Mapping.java b/src/test/java/lambda/part3/exercise/Mapping.java index 01f0a12..c438e47 100644 --- a/src/test/java/lambda/part3/exercise/Mapping.java +++ b/src/test/java/lambda/part3/exercise/Mapping.java @@ -9,7 +9,9 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.function.Consumer; import java.util.function.Function; +import java.util.function.Predicate; import static org.junit.Assert.assertEquals; @@ -143,45 +145,130 @@ public LazyMapHelper map(Function f) { Function newFunction = function.andThen(f); return new LazyMapHelper<>(list, newFunction); } - } - private static class LazyFlatMapHelper { + interface ReachIterable { + //hasNext and next + boolean tryGet(Consumer c); - public LazyFlatMapHelper(List list, Function> function) { - } - public static LazyFlatMapHelper from(List list) { - throw new UnsupportedOperationException(); + //TODO boolean anyMatch(Predicate p) + //TODO boolean allMatch(Predicate p) + //TODO boolean noneMatch(Predicate p) + + //TODO Optional firstMatch(Predicate p) + + static ReachIterable from(List list) { + return new ReachIterable() { + @Override + public boolean tryGet(Consumer c) { + return false; + } + }; } + } - public List force() { - // TODO - throw new UnsupportedOperationException(); + interface Traversable { + void forEach(Consumer c); + + default Traversable filter(Predicate p) { + final Traversable self = this; + return new Traversable() { + @Override + public void forEach(Consumer c) { + self.forEach(t -> { + if (p.test(t)) + c.accept(t); + }); + } + }; } - // TODO filter - // (T -> boolean) -> (T -> [T]) - // filter: [T1, T2] -> (T -> boolean) -> [T2] - // flatMap": [T1, T2] -> (T -> [T]) -> [T2] + default Traversable flatMap(Function> f) { + final Traversable self = this; + return new Traversable() { + @Override + public void forEach(Consumer c) { + self.forEach( + t -> f.apply(t) + .forEach(c)); + } + }; + } - public LazyFlatMapHelper map(Function f) { - final Function> listFunction = rR2TorListR2(f); - return flatMap(listFunction); + default Traversable map(Function f) { + final Traversable self = this; + return new Traversable() { + @Override + public void forEach(Consumer c) { + self.forEach(t -> c.accept(f.apply(t))); + } + }; } - // (R -> R2) -> (R -> [R2]) - private Function> rR2TorListR2(Function f) { - throw new UnsupportedOperationException(); + default List toList() { + final List list = new ArrayList<>(); + forEach(list::add); + return list; } - // TODO * - public LazyFlatMapHelper flatMap(Function> f) { - throw new UnsupportedOperationException(); + static Traversable from(List list) { + return new Traversable() { + @Override + public void forEach(Consumer c) { + list.forEach(c); + } + }; } } + @Test + public void testFlatMap() { + 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") + )) + ); + + System.err.println( + Arrays.toString( + Traversable.from(employees).flatMap(Employee::getJobHistory).toList().toArray())); + } + + @Test + public void testFilter() { + 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") + )) + ); + System.err.println( + Arrays.toString( + Traversable.from(employees).filter(e -> e.getPerson().getFirstName().equals("a")).toList().toArray())); + } @Test public void lazy_mapping() { From 48964fee6c974270f4211f6d9636ce31cbc1ab61 Mon Sep 17 00:00:00 2001 From: Andrei Andronov Date: Sun, 9 Jul 2017 22:44:53 +0300 Subject: [PATCH 3/3] part 3: allMatch, anyMatch, firstMatch, noneMatch methods of ReachIterable were done --- .../java/lambda/part3/exercise/Mapping.java | 42 +++++++++++++++++-- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/src/test/java/lambda/part3/exercise/Mapping.java b/src/test/java/lambda/part3/exercise/Mapping.java index c438e47..0a75680 100644 --- a/src/test/java/lambda/part3/exercise/Mapping.java +++ b/src/test/java/lambda/part3/exercise/Mapping.java @@ -5,10 +5,7 @@ import data.Person; import org.junit.Test; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; +import java.util.*; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; @@ -153,15 +150,52 @@ interface ReachIterable { //TODO boolean anyMatch(Predicate p) + default boolean anyMatch(Predicate p) { + return firstMatch(p).isPresent(); + } + //TODO boolean allMatch(Predicate p) + default boolean allMatch(Predicate p) { + final List allMatch = Collections.singletonList(true); + final List keep = Collections.singletonList(true); + Consumer consumer = t -> { + if (keep.get(0) && !p.test(t)) { + allMatch.set(0, false); + keep.set(0, false); + } + }; + while (tryGet(consumer)) {} + return allMatch.get(0); + } + //TODO boolean noneMatch(Predicate p) + default boolean noneMatch(Predicate p) { + return !allMatch(p); + } //TODO Optional firstMatch(Predicate p) + default Optional firstMatch(Predicate p) { + final List> optionals = Collections.singletonList(Optional.empty()); + final List keep = Collections.singletonList(true); + Consumer consumer = t -> { + if (keep.get(0) && p.test(t)) { + optionals.set(0, Optional.ofNullable(t)); + keep.set(0, false); + } + }; + while (tryGet(consumer)) {} + return optionals.get(0); + } static ReachIterable from(List list) { return new ReachIterable() { @Override public boolean tryGet(Consumer c) { + Iterator iterator = list.iterator(); + if (iterator.hasNext()) { + c.accept(iterator.next()); + return true; + } return false; } };