From a676876c40b904e89ea9e41bb30be447db38cc8c Mon Sep 17 00:00:00 2001 From: Andrey Kravtsun Date: Fri, 7 Apr 2017 01:49:55 +0300 Subject: [PATCH 1/6] Homework solved. --- src/main/java/ru/spbau/mit/Collections.java | 64 +++++++ src/main/java/ru/spbau/mit/Function1.java | 14 ++ src/main/java/ru/spbau/mit/Function2.java | 42 ++++ src/main/java/ru/spbau/mit/Predicate.java | 57 ++++++ .../java/ru/spbau/mit/CollectionsTest.java | 181 ++++++++++++++++++ src/test/java/ru/spbau/mit/Function1Test.java | 102 ++++++++++ src/test/java/ru/spbau/mit/Function2Test.java | 72 +++++++ src/test/java/ru/spbau/mit/PredicateTest.java | 99 ++++++++++ 8 files changed, 631 insertions(+) create mode 100644 src/main/java/ru/spbau/mit/Collections.java create mode 100644 src/main/java/ru/spbau/mit/Function1.java create mode 100644 src/main/java/ru/spbau/mit/Function2.java create mode 100644 src/main/java/ru/spbau/mit/Predicate.java create mode 100644 src/test/java/ru/spbau/mit/CollectionsTest.java create mode 100644 src/test/java/ru/spbau/mit/Function1Test.java create mode 100644 src/test/java/ru/spbau/mit/Function2Test.java create mode 100644 src/test/java/ru/spbau/mit/PredicateTest.java diff --git a/src/main/java/ru/spbau/mit/Collections.java b/src/main/java/ru/spbau/mit/Collections.java new file mode 100644 index 0000000..105a807 --- /dev/null +++ b/src/main/java/ru/spbau/mit/Collections.java @@ -0,0 +1,64 @@ +package ru.spbau.mit; + +import java.util.ArrayList; +import java.util.Collection; + +public final class Collections { + private Collections() {} + + public static Collection map(Function1 f, Collection c) { + Collection newcol = new ArrayList(); + for (T el : c) { + newcol.add(f.apply(el)); + } + return newcol; + } + + public static Collection filter(Predicate pred, Collection c) { + Collection newcol = new ArrayList(); + for (T el : c) { + if (pred.apply(el)) { + newcol.add(el); + } + } + return newcol; + } + + public static Collection takeWhile(Predicate pred, Collection c) { + Collection newcol = new ArrayList(); + for (T el : c) { + if (!pred.apply(el)) { + break; + } + newcol.add(el); + } + return newcol; + } + + public static Collection takeUnless(Predicate pred, Collection c) { + return takeWhile(pred.not(), c); + } + + + public static I foldl(Function2 f, Collection c, I init) { + I res = init; + for (T el : c) { + res = f.apply2(res, el); + } + return res; + } + + public static I foldr(Function2 f, Collection c, I init) { + Function1 resfunc = new Function1() { + @Override + public I apply(I arg) { + return arg; + } + }; + + for (T el : c) { + resfunc = f.bind1(el).compose(resfunc); + } + return resfunc.apply(init); + } +} diff --git a/src/main/java/ru/spbau/mit/Function1.java b/src/main/java/ru/spbau/mit/Function1.java new file mode 100644 index 0000000..16783fe --- /dev/null +++ b/src/main/java/ru/spbau/mit/Function1.java @@ -0,0 +1,14 @@ +package ru.spbau.mit; + +public abstract class Function1 { + public Function1 compose(final Function1 g) { + return new Function1() { + @Override + public G apply(T arg) { + return g.apply(Function1.this.apply(arg)); + } + }; + } + + public abstract S apply(T arg); +} diff --git a/src/main/java/ru/spbau/mit/Function2.java b/src/main/java/ru/spbau/mit/Function2.java new file mode 100644 index 0000000..d99fc3a --- /dev/null +++ b/src/main/java/ru/spbau/mit/Function2.java @@ -0,0 +1,42 @@ +package ru.spbau.mit; + +// extends Function1> +public abstract class Function2 { + public Function1> curry() { + return new Function1>() { + @Override + public Function1 apply(T1 arg1) { + return Function2.this.bind1(arg1); + } + }; + } + + // because of compose can't extend from Function1 + public Function2 compose(final Function1 g) { + return new Function2() { + public S2 apply2(T1 arg1, T2 arg2) { + return g.apply(Function2.this.apply2(arg1, arg2)); + } + }; + } + + public Function1 bind1(final T1 arg1) { + return new Function1() { + @Override + public S apply(T2 arg2) { + return apply2(arg1, arg2); + } + }; + } + + public Function1 bind2(final T2 arg2) { + return new Function1() { + @Override + public S apply(T1 arg1) { + return apply2(arg1, arg2); + } + }; + } + + public abstract S apply2(T1 arg1, T2 arg2); +} diff --git a/src/main/java/ru/spbau/mit/Predicate.java b/src/main/java/ru/spbau/mit/Predicate.java new file mode 100644 index 0000000..1fd45f7 --- /dev/null +++ b/src/main/java/ru/spbau/mit/Predicate.java @@ -0,0 +1,57 @@ +package ru.spbau.mit; + +public abstract class Predicate extends Function1 { + @SuppressWarnings("unchecked") + public static final Predicate ALWAYS_TRUE = new Predicate() { + @Override + public Boolean apply(Object arg) { + return true; + } + }; + + public static final Predicate ALWAYS_FALSE = new Predicate() { + @Override + public Boolean apply(Object arg) { + return false; + } + }; + @SuppressWarnings("checked") + + public Predicate and(final Predicate rhs) { + return new Predicate() { + @Override + public Boolean apply(T arg) { + if (Predicate.this.apply(arg)) { + return rhs.apply(arg); + } else { + return false; + } + } + }; + } + + public Predicate or(final Predicate rhs) { + return new Predicate() { + @Override + public Boolean apply(T arg) { + if (Predicate.this.apply(arg)) { + return true; + } else { + return rhs.apply(arg); + } + } + }; + } + + public Predicate not() { + return new Predicate() { + @Override + public Boolean apply(T arg) { + return !Predicate.this.apply(arg); + } + }; + } + + @Override + public abstract Boolean apply(T arg); +} diff --git a/src/test/java/ru/spbau/mit/CollectionsTest.java b/src/test/java/ru/spbau/mit/CollectionsTest.java new file mode 100644 index 0000000..5a58eee --- /dev/null +++ b/src/test/java/ru/spbau/mit/CollectionsTest.java @@ -0,0 +1,181 @@ +package ru.spbau.mit; + +import org.junit.Test; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.*; + +public class CollectionsTest { + private static final Integer MAGIC_1 = 1; + private static final Integer MAGIC_2 = -4; + private static final Integer MAGIC_3 = 3; + private static final Integer MAGIC_4 = 10; + private static final Integer MAGIC_5 = -20; + + private static final ArrayList INT_ARR = new ArrayList() { { + add(MAGIC_1); + add(MAGIC_2); + add(MAGIC_3); + add(MAGIC_4); + add(MAGIC_5); + } }; + + private static final ArrayList INT_ARR_NEGATED = new ArrayList() { { + add(-MAGIC_1); + add(-MAGIC_2); + add(-MAGIC_3); + add(-MAGIC_4); + add(-MAGIC_5); + } }; + + private static final ArrayList INT_ARR_STRINGED = new ArrayList() { { + add(MAGIC_1.toString()); + add(MAGIC_2.toString()); + add(MAGIC_3.toString()); + add(MAGIC_4.toString()); + add(MAGIC_5.toString()); + } }; + + private static final Predicate IS_POSITIVE_INTEGER = new Predicate() { + @Override + public Boolean apply(Integer arg) { + return arg > 0; + } + }; + + private static final List EMPTY_ARR = new ArrayList<>(); + + private static final Function2 MINUS = new Function2() { + @Override + public Integer apply2(Integer arg1, Integer arg2) { + return arg1 - arg2; + } + }; + + private static final Function1 ID = new Function1() { + @Override + public Object apply(Object arg) { + return arg; + } + }; + + private static final Function1 TO_STRING = new Function1() { + @Override + public String apply(Object arg) { + return arg.toString(); + } + }; + + private static final Function2 FAIL_FUNCTION = + new Function2() { + @Override + public Object apply2(Object arg1, Object arg2) { + assert false; + return null; + } + }; + +@Test + public void testConstructorIsPrivate() throws NoSuchMethodException, + IllegalAccessException, + InvocationTargetException, + InstantiationException { + Constructor constructor = Collections.class.getDeclaredConstructor(); + assertTrue(Modifier.isPrivate(constructor.getModifiers())); + constructor.setAccessible(true); + constructor.newInstance(); + } + + @Test + public void map() throws Exception { + assertEquals(INT_ARR_NEGATED, Collections.map(MINUS.bind1(0), INT_ARR)); + assertEquals(EMPTY_ARR, Collections.map(ID, EMPTY_ARR)); + assertEquals(INT_ARR_STRINGED, Collections.map(TO_STRING, INT_ARR)); + assertEquals(INT_ARR, Collections.map(ID, INT_ARR)); + } + + @Test + public void filter() throws Exception { + final ArrayList positiveOnly = new ArrayList() { { + add(-MAGIC_2); + add(-MAGIC_5); + } }; + assertEquals(positiveOnly, Collections.filter(IS_POSITIVE_INTEGER, INT_ARR_NEGATED)); + assertEquals(INT_ARR, Collections.filter(Predicate.ALWAYS_TRUE, INT_ARR)); + assertEquals(EMPTY_ARR, Collections.filter(Predicate.ALWAYS_FALSE, INT_ARR)); + } + + @Test + public void takeWhile() throws Exception { + Predicate u2 = new Predicate() { + @Override + public Boolean apply(CharSequence charSequence) { + return charSequence.length() < 2; + } + }; + + ArrayList firstSmall = new ArrayList() { { + add("1"); + } }; + + assertEquals(firstSmall, Collections.takeWhile(u2, INT_ARR_STRINGED)); + assertEquals(EMPTY_ARR, Collections.takeWhile(IS_POSITIVE_INTEGER, INT_ARR_NEGATED)); + assertEquals(INT_ARR_STRINGED, Collections.takeWhile(Predicate.ALWAYS_TRUE, INT_ARR_STRINGED)); + } + + @Test + public void takeUnless() throws Exception { + ArrayList firstNegative = new ArrayList() { { + add(-1); + } }; + + assertEquals(EMPTY_ARR, Collections.takeUnless(IS_POSITIVE_INTEGER.not(), INT_ARR_NEGATED)); + assertEquals(firstNegative, Collections.takeUnless(IS_POSITIVE_INTEGER, INT_ARR_NEGATED)); + assertEquals(INT_ARR, Collections.takeUnless(Predicate.ALWAYS_FALSE, INT_ARR)); + } + + + @Test + public void foldl() throws Exception { + final Integer result = 10; + assertEquals(result, Collections.foldl(MINUS, INT_ARR, (Integer) 0)); + + final Function2 accumulateString = new Function2() { + @Override + public String apply2(String arg1, Integer arg2) { + return arg1 + arg2.toString(); + } + }; + + final String initString = "Hello, "; + final String resultString = "Hello, 1-4310-20"; + assertEquals(resultString, Collections.foldl(accumulateString, INT_ARR, initString)); + assertEquals(0, Collections.foldl(FAIL_FUNCTION, EMPTY_ARR, 0)); + } + + @Test + public void foldr() throws Exception { + final Function2 accumulateString = new Function2() { + @Override + public String apply2(Integer arg1, String arg2) { + return arg1.toString() + arg2; + } + }; + final String initString = "123"; + final String resultString = "-14-3-1020123"; + assertEquals(resultString, Collections.foldr(accumulateString, INT_ARR_NEGATED, initString)); + + final Integer init = -33; + final Integer result = 11; + assertEquals(result, Collections.foldr(MINUS, INT_ARR, init)); + + assertEquals(0, Collections.foldr(FAIL_FUNCTION, EMPTY_ARR, 0)); + + } + +} diff --git a/src/test/java/ru/spbau/mit/Function1Test.java b/src/test/java/ru/spbau/mit/Function1Test.java new file mode 100644 index 0000000..4af0133 --- /dev/null +++ b/src/test/java/ru/spbau/mit/Function1Test.java @@ -0,0 +1,102 @@ +package ru.spbau.mit; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Collection; + +import static org.junit.Assert.*; + +public class Function1Test { + private static Function1> fromArrayToCollection = + new Function1>() { + @Override + public Collection apply(Integer[] arg) { + Collection c = new ArrayList(); + for (Object o : arg) { + c.add((Integer) o); + } + return c; + } + }; + + private final Function1 sqr = new Function1() { + @Override + public Integer apply(Integer arg) { + return arg * arg; + } + }; + + private final Function2 minus = new Function2() { + @Override + public Integer apply2(Integer arg1, Integer arg2) { + return arg1 - arg2; + } + }; + + private final Function1 id = new Function1() { + @Override + public Object apply(Object arg) { + return arg; + } + }; + + @Test + public void compose() throws Exception { + Function1 g = new Function1() { + @Override + public Double apply(Integer integer) { + return integer.doubleValue(); + } + }; + final Double fiveDouble = 5.0; + final Integer fiveInteger = 5; + assertEquals(fiveDouble, g.apply(fiveInteger)); + + Function1 f = new Function1() { + @Override + public String apply(Number number) { + return number.toString(); + } + }; + + Function1 fg = g.compose(f); + String fiveDoubleString = "5.0"; + assertEquals(fiveDoubleString, fg.apply(fiveInteger)); + + Function1 hash = new Function1() { + @Override + public Integer apply(Object arg) { + return arg.hashCode(); + } + }; + + Integer i = 1; + // must compile. + final Integer someInteger = 123; + assertEquals(0, hash.apply(someInteger) % 1); + + + final int arraySize = 10; + Integer[] integers = new Integer[arraySize]; + fromArrayToCollection.apply(integers); // compilation OK. + +// Double []doubles = new Double[arraySize]; +// fromArrayToCollection.apply(doubles); // compilation Failed. + +// Function1 +// Function1 u1 = new Function1() { +// @Override +// Boolean apply(Object o) { +// return o.hashCode() % 2 == 0; +// } +// }; +// + final Integer twentyFiveInteger = 25; + assertEquals(twentyFiveInteger, sqr.compose(id).apply(fiveInteger)); + assertEquals(fiveInteger, id.compose(id).apply(fiveInteger)); + String someString = "5"; + assertEquals(someString, id.compose(id).apply(someString)); + } + +} diff --git a/src/test/java/ru/spbau/mit/Function2Test.java b/src/test/java/ru/spbau/mit/Function2Test.java new file mode 100644 index 0000000..2064b7e --- /dev/null +++ b/src/test/java/ru/spbau/mit/Function2Test.java @@ -0,0 +1,72 @@ +package ru.spbau.mit; + +import org.junit.Test; + +import static org.junit.Assert.*; + +public class Function2Test { + + private static final Integer FIVE_INTEGER = 5; + private static final Integer FOUR_INTEGER = 4; + private static final Integer THREE_INTEGER = 3; + private static final Integer ONE_INTEGER = 1; + private static final Integer ZERO_INTEGER = 0; + + private final Function1 sqr = new Function1() { + @Override + public Integer apply(Integer arg) { + return arg * arg; + } + }; + + private final Function2 minus = new Function2() { + @Override + public Integer apply2(Integer arg1, Integer arg2) { + return arg1 - arg2; + } + }; + + private final Function1 id = new Function1() { + @Override + public Object apply(Object arg) { + return arg; + } + }; + + @Test + public void curry() throws Exception { + Function1 fiveMinus = new Function1() { + @Override + public Integer apply(Integer arg) { + return FIVE_INTEGER - arg; + } + }; + + assertEquals(ONE_INTEGER, minus.curry().apply(FIVE_INTEGER).apply(FOUR_INTEGER)); + assertEquals(ONE_INTEGER, fiveMinus.apply(FOUR_INTEGER)); +// assertEquals(ONE_INTEGER, minus.curry(fiveDouble).apply(FOUR_INTEGER)); // Compilation error. +// assertEquals(ONE_INTEGER, minus.curry(ONE_INTEGER).apply(fiveDouble)); // Compilation error. + } + + @Test + public void apply2() throws Exception { + assertEquals(FOUR_INTEGER, minus.apply2(FIVE_INTEGER, ONE_INTEGER)); +// assertEquals(ONE_INTEGER, minus.apply2(FIVE_INTEGER, (Double) FOUR_INTEGER)); // Compilation error. + } + + @Test + public void compose() throws Exception { + assertEquals(ONE_INTEGER, minus.compose(id).apply2(FIVE_INTEGER, FOUR_INTEGER)); + assertEquals(ONE_INTEGER, minus.compose(sqr).apply2(FOUR_INTEGER, THREE_INTEGER)); + } + + @Test + public void bind1() throws Exception { + assertEquals(FOUR_INTEGER, minus.bind1(FIVE_INTEGER).apply(ONE_INTEGER)); + } + + @Test + public void bind2() throws Exception { + assertEquals(ZERO_INTEGER, minus.bind2(ONE_INTEGER).apply(ONE_INTEGER)); + } +} diff --git a/src/test/java/ru/spbau/mit/PredicateTest.java b/src/test/java/ru/spbau/mit/PredicateTest.java new file mode 100644 index 0000000..84b4e8c --- /dev/null +++ b/src/test/java/ru/spbau/mit/PredicateTest.java @@ -0,0 +1,99 @@ +package ru.spbau.mit; + +import org.junit.Test; + +import static org.junit.Assert.*; + +public class PredicateTest { + private static final Integer FIVE_INTEGER = 5; + private static final Double ZERO_DOUBLE = 0.0; + private static final Double ONE_DOUBLE = 1.0; + private static final Integer ONE_INTEGER = 1; + private static final Integer BIG_INTEGER = 123123124; + private static final int FOUR_INTEGER = 4; + + // Does not work. +// private static final Function2 less = new Function2() { +// @Override +// public Boolean apply2(Integer arg1, Integer arg2) { +// return arg1 < arg2; +// } +// }; + + private static final Predicate LESS_THAN_FIVE = new Predicate() { + @Override + public Boolean apply(Integer arg) { + return arg < FIVE_INTEGER; + } + }; + + private static final Predicate IS_POSITIVE_INTEGER = new Predicate() { + @Override + public Boolean apply(Integer arg) { + return arg > 0; + } + }; + + private static final Predicate IS_POSITIVE_DOUBLE = new Predicate() { + @Override + public Boolean apply(Double arg) { + return arg > 0; + } + }; + + private static final Predicate FAIL_INTEGER = new Predicate() { + @Override + public Boolean apply(Integer arg) { + assert false; + return null; + } + }; + + private static final Predicate FAIL_DOUBLE = new Predicate() { + @Override + public Boolean apply(Double arg) { + assert false; + return null; + } + }; + + private static final Predicate EQUAL_TO_ONE = new Predicate() { + @Override + public Boolean apply(Double arg) { + return ONE_DOUBLE == arg; + } + }; + + @Test + public void and() throws Exception { + assertFalse(EQUAL_TO_ONE.and(FAIL_DOUBLE).apply(ZERO_DOUBLE)); + assertFalse(IS_POSITIVE_INTEGER.and(LESS_THAN_FIVE).apply(BIG_INTEGER)); + assertTrue(LESS_THAN_FIVE.and(IS_POSITIVE_INTEGER).apply(FOUR_INTEGER)); + assertTrue(IS_POSITIVE_DOUBLE.and(EQUAL_TO_ONE).apply(ONE_DOUBLE)); + assertFalse(Predicate.ALWAYS_FALSE.and(FAIL_DOUBLE).apply(null)); + } + + @Test + public void or() throws Exception { +// assertTrue(EQUAL_TO_ONE.apply(ONE_INTEGER)); // Compilation error. + assertFalse(EQUAL_TO_ONE.or(IS_POSITIVE_DOUBLE).apply(ZERO_DOUBLE)); + assertTrue(LESS_THAN_FIVE.or(IS_POSITIVE_INTEGER).apply(FIVE_INTEGER)); + assertTrue(LESS_THAN_FIVE.or(FAIL_INTEGER).apply(ONE_INTEGER)); + assertTrue(IS_POSITIVE_DOUBLE.or(EQUAL_TO_ONE).apply(ONE_DOUBLE)); + assertTrue(Predicate.ALWAYS_TRUE.or(FAIL_INTEGER).apply(null)); + } + + @Test + public void not() throws Exception { + assertFalse(LESS_THAN_FIVE.not().apply(FOUR_INTEGER)); + assertTrue(LESS_THAN_FIVE.not().apply(FIVE_INTEGER)); + } + + @Test + public void apply() throws Exception { + assertTrue(LESS_THAN_FIVE.apply(FOUR_INTEGER)); + assertFalse(LESS_THAN_FIVE.apply(FIVE_INTEGER)); + assertFalse(EQUAL_TO_ONE.apply(ZERO_DOUBLE)); + } + +} From 07081f4158e071bb66ff72e13bfb6842e31803af Mon Sep 17 00:00:00 2001 From: Andrey Kravtsun Date: Fri, 7 Apr 2017 02:00:03 +0300 Subject: [PATCH 2/6] Unsuppress warnings on checked conversion (static ALWAYS_TRUE and ALWAYS_FALSE). --- src/main/java/ru/spbau/mit/Predicate.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/ru/spbau/mit/Predicate.java b/src/main/java/ru/spbau/mit/Predicate.java index 1fd45f7..426d784 100644 --- a/src/main/java/ru/spbau/mit/Predicate.java +++ b/src/main/java/ru/spbau/mit/Predicate.java @@ -1,7 +1,6 @@ package ru.spbau.mit; public abstract class Predicate extends Function1 { - @SuppressWarnings("unchecked") public static final Predicate ALWAYS_TRUE = new Predicate() { @Override public Boolean apply(Object arg) { @@ -15,7 +14,6 @@ public Boolean apply(Object arg) { return false; } }; - @SuppressWarnings("checked") public Predicate and(final Predicate rhs) { return new Predicate() { From 1e86bdafb4a2532e632a0de0a2a929c13fff053a Mon Sep 17 00:00:00 2001 From: Andrey Kravtsun Date: Fri, 7 Apr 2017 02:04:24 +0300 Subject: [PATCH 3/6] Removing test on private constructor for Collections. --- src/test/java/ru/spbau/mit/CollectionsTest.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/test/java/ru/spbau/mit/CollectionsTest.java b/src/test/java/ru/spbau/mit/CollectionsTest.java index 5a58eee..9fe3978 100644 --- a/src/test/java/ru/spbau/mit/CollectionsTest.java +++ b/src/test/java/ru/spbau/mit/CollectionsTest.java @@ -80,17 +80,6 @@ public Object apply2(Object arg1, Object arg2) { } }; -@Test - public void testConstructorIsPrivate() throws NoSuchMethodException, - IllegalAccessException, - InvocationTargetException, - InstantiationException { - Constructor constructor = Collections.class.getDeclaredConstructor(); - assertTrue(Modifier.isPrivate(constructor.getModifiers())); - constructor.setAccessible(true); - constructor.newInstance(); - } - @Test public void map() throws Exception { assertEquals(INT_ARR_NEGATED, Collections.map(MINUS.bind1(0), INT_ARR)); From a153e56993a09c07f681e764cd427f772394db10 Mon Sep 17 00:00:00 2001 From: Andrey Kravtsun Date: Fri, 7 Apr 2017 02:06:33 +0300 Subject: [PATCH 4/6] Fixed warnings on previous commit's unused imports left. --- src/test/java/ru/spbau/mit/CollectionsTest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/test/java/ru/spbau/mit/CollectionsTest.java b/src/test/java/ru/spbau/mit/CollectionsTest.java index 9fe3978..0dfaa9c 100644 --- a/src/test/java/ru/spbau/mit/CollectionsTest.java +++ b/src/test/java/ru/spbau/mit/CollectionsTest.java @@ -2,9 +2,6 @@ import org.junit.Test; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; From e29c71748580392d64f4722950075e7e6145c156 Mon Sep 17 00:00:00 2001 From: Andrey Kravtsun Date: Mon, 24 Apr 2017 16:21:37 +0300 Subject: [PATCH 5/6] Some fixes from pull request notes. --- src/main/java/ru/spbau/mit/Collections.java | 20 ++-- src/main/java/ru/spbau/mit/Function2.java | 1 - src/main/java/ru/spbau/mit/Predicate.java | 18 +-- .../java/ru/spbau/mit/CollectionsTest.java | 104 ++++++++++-------- src/test/java/ru/spbau/mit/PredicateTest.java | 10 +- 5 files changed, 80 insertions(+), 73 deletions(-) diff --git a/src/main/java/ru/spbau/mit/Collections.java b/src/main/java/ru/spbau/mit/Collections.java index 105a807..911f510 100644 --- a/src/main/java/ru/spbau/mit/Collections.java +++ b/src/main/java/ru/spbau/mit/Collections.java @@ -1,21 +1,21 @@ package ru.spbau.mit; import java.util.ArrayList; -import java.util.Collection; +import java.util.List; public final class Collections { private Collections() {} - public static Collection map(Function1 f, Collection c) { - Collection newcol = new ArrayList(); + public static List map(Function1 f, Iterable c) { + List newcol = new ArrayList(); for (T el : c) { newcol.add(f.apply(el)); } return newcol; } - public static Collection filter(Predicate pred, Collection c) { - Collection newcol = new ArrayList(); + public static List filter(Predicate pred, Iterable c) { + List newcol = new ArrayList(); for (T el : c) { if (pred.apply(el)) { newcol.add(el); @@ -24,8 +24,8 @@ public static Collection filter(Predicate pred, Collection return newcol; } - public static Collection takeWhile(Predicate pred, Collection c) { - Collection newcol = new ArrayList(); + public static List takeWhile(Predicate pred, Iterable c) { + List newcol = new ArrayList(); for (T el : c) { if (!pred.apply(el)) { break; @@ -35,12 +35,12 @@ public static Collection takeWhile(Predicate pred, Collection< return newcol; } - public static Collection takeUnless(Predicate pred, Collection c) { + public static List takeUnless(Predicate pred, Iterable c) { return takeWhile(pred.not(), c); } - public static I foldl(Function2 f, Collection c, I init) { + public static I foldl(Function2 f, Iterable c, I init) { I res = init; for (T el : c) { res = f.apply2(res, el); @@ -48,7 +48,7 @@ public static I foldl(Function2 f, Collection c, I in return res; } - public static I foldr(Function2 f, Collection c, I init) { + public static I foldr(Function2 f, Iterable c, I init) { Function1 resfunc = new Function1() { @Override public I apply(I arg) { diff --git a/src/main/java/ru/spbau/mit/Function2.java b/src/main/java/ru/spbau/mit/Function2.java index d99fc3a..92179bb 100644 --- a/src/main/java/ru/spbau/mit/Function2.java +++ b/src/main/java/ru/spbau/mit/Function2.java @@ -1,6 +1,5 @@ package ru.spbau.mit; -// extends Function1> public abstract class Function2 { public Function1> curry() { return new Function1>() { diff --git a/src/main/java/ru/spbau/mit/Predicate.java b/src/main/java/ru/spbau/mit/Predicate.java index 426d784..57ee6f4 100644 --- a/src/main/java/ru/spbau/mit/Predicate.java +++ b/src/main/java/ru/spbau/mit/Predicate.java @@ -1,14 +1,14 @@ package ru.spbau.mit; public abstract class Predicate extends Function1 { - public static final Predicate ALWAYS_TRUE = new Predicate() { + public static final Predicate ALWAYS_TRUE = new Predicate() { @Override public Boolean apply(Object arg) { return true; } }; - public static final Predicate ALWAYS_FALSE = new Predicate() { + public static final Predicate ALWAYS_FALSE = new Predicate() { @Override public Boolean apply(Object arg) { return false; @@ -19,11 +19,7 @@ public Predicate and(final Predicate rhs) { return new Predicate() { @Override public Boolean apply(T arg) { - if (Predicate.this.apply(arg)) { - return rhs.apply(arg); - } else { - return false; - } + return Predicate.this.apply(arg) && rhs.apply(arg); } }; } @@ -32,16 +28,12 @@ public Predicate or(final Predicate rhs) { return new Predicate() { @Override public Boolean apply(T arg) { - if (Predicate.this.apply(arg)) { - return true; - } else { - return rhs.apply(arg); - } + return Predicate.this.apply(arg) || rhs.apply(arg); } }; } - public Predicate not() { + public Predicate not() { return new Predicate() { @Override public Boolean apply(T arg) { diff --git a/src/test/java/ru/spbau/mit/CollectionsTest.java b/src/test/java/ru/spbau/mit/CollectionsTest.java index 0dfaa9c..824bb85 100644 --- a/src/test/java/ru/spbau/mit/CollectionsTest.java +++ b/src/test/java/ru/spbau/mit/CollectionsTest.java @@ -3,8 +3,11 @@ import org.junit.Test; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Objects; +import static java.util.Collections.emptyList; import static org.junit.Assert.*; public class CollectionsTest { @@ -14,29 +17,22 @@ public class CollectionsTest { private static final Integer MAGIC_4 = 10; private static final Integer MAGIC_5 = -20; - private static final ArrayList INT_ARR = new ArrayList() { { - add(MAGIC_1); - add(MAGIC_2); - add(MAGIC_3); - add(MAGIC_4); - add(MAGIC_5); - } }; - - private static final ArrayList INT_ARR_NEGATED = new ArrayList() { { - add(-MAGIC_1); - add(-MAGIC_2); - add(-MAGIC_3); - add(-MAGIC_4); - add(-MAGIC_5); - } }; - - private static final ArrayList INT_ARR_STRINGED = new ArrayList() { { - add(MAGIC_1.toString()); - add(MAGIC_2.toString()); - add(MAGIC_3.toString()); - add(MAGIC_4.toString()); - add(MAGIC_5.toString()); - } }; + private static final List INT_ARR = Arrays.asList( + MAGIC_1, MAGIC_2, MAGIC_3, MAGIC_4, MAGIC_5); + + private static final List INT_ARR_NEGATED = Arrays.asList( + -MAGIC_1, -MAGIC_2, -MAGIC_3, -MAGIC_4, -MAGIC_5); + + private static final List ARR_WITH_NULL = Arrays.asList( + null, 1, null, 4, null); + + private static final List INT_ARR_STRINGED = Arrays.asList( + MAGIC_1.toString(), + MAGIC_2.toString(), + MAGIC_3.toString(), + MAGIC_4.toString(), + MAGIC_5.toString() + ); private static final Predicate IS_POSITIVE_INTEGER = new Predicate() { @Override @@ -45,7 +41,16 @@ public Boolean apply(Integer arg) { } }; - private static final List EMPTY_ARR = new ArrayList<>(); + private static final Predicate IS_NULL = new Predicate() { + @Override + public Boolean apply(Object arg) { + return arg == null; + } + }; + + private static final Predicate NOT_NULL = IS_NULL.not(); + + private static final List EMPTY_ARR = (List) emptyList(); private static final Function2 MINUS = new Function2() { @Override @@ -94,6 +99,16 @@ public void filter() throws Exception { assertEquals(positiveOnly, Collections.filter(IS_POSITIVE_INTEGER, INT_ARR_NEGATED)); assertEquals(INT_ARR, Collections.filter(Predicate.ALWAYS_TRUE, INT_ARR)); assertEquals(EMPTY_ARR, Collections.filter(Predicate.ALWAYS_FALSE, INT_ARR)); + assertEquals(EMPTY_ARR, Collections.filter(IS_NULL, INT_ARR)); + assertEquals(Arrays.asList(null, null, null), Collections.filter(IS_NULL, ARR_WITH_NULL)); + Predicate isTen = new Predicate() { + @Override + public Boolean apply(Object arg) { + return (arg).toString().equals("10"); + } + }; + final int ten = 10; + assertEquals(Arrays.asList(ten), Collections.filter(isTen, INT_ARR)); } @Test @@ -104,37 +119,35 @@ public Boolean apply(CharSequence charSequence) { return charSequence.length() < 2; } }; - - ArrayList firstSmall = new ArrayList() { { - add("1"); - } }; - - assertEquals(firstSmall, Collections.takeWhile(u2, INT_ARR_STRINGED)); + assertEquals(Arrays.asList("1"), Collections.takeWhile(u2, INT_ARR_STRINGED)); assertEquals(EMPTY_ARR, Collections.takeWhile(IS_POSITIVE_INTEGER, INT_ARR_NEGATED)); assertEquals(INT_ARR_STRINGED, Collections.takeWhile(Predicate.ALWAYS_TRUE, INT_ARR_STRINGED)); + ArrayList nullArray = new ArrayList<>(); + nullArray.add(null); + assertEquals(nullArray, Collections.takeWhile(IS_NULL, ARR_WITH_NULL)); + assertEquals(EMPTY_ARR, Collections.takeWhile(IS_NULL, INT_ARR)); } @Test public void takeUnless() throws Exception { - ArrayList firstNegative = new ArrayList() { { - add(-1); - } }; - assertEquals(EMPTY_ARR, Collections.takeUnless(IS_POSITIVE_INTEGER.not(), INT_ARR_NEGATED)); - assertEquals(firstNegative, Collections.takeUnless(IS_POSITIVE_INTEGER, INT_ARR_NEGATED)); + assertEquals(Arrays.asList(-1), Collections.takeUnless(IS_POSITIVE_INTEGER, INT_ARR_NEGATED)); assertEquals(INT_ARR, Collections.takeUnless(Predicate.ALWAYS_FALSE, INT_ARR)); + ArrayList nullArr = new ArrayList<>(); + nullArr.add(null); + assertEquals(nullArr, Collections.takeUnless(NOT_NULL, ARR_WITH_NULL)); + assertEquals(EMPTY_ARR, Collections.takeUnless(IS_NULL, ARR_WITH_NULL)); } - @Test public void foldl() throws Exception { final Integer result = 10; assertEquals(result, Collections.foldl(MINUS, INT_ARR, (Integer) 0)); - final Function2 accumulateString = new Function2() { + final Function2 accumulateString = new Function2() { @Override - public String apply2(String arg1, Integer arg2) { - return arg1 + arg2.toString(); + public String apply2(String arg1, Object arg2) { + return arg1 + Objects.toString(arg2); } }; @@ -142,16 +155,20 @@ public String apply2(String arg1, Integer arg2) { final String resultString = "Hello, 1-4310-20"; assertEquals(resultString, Collections.foldl(accumulateString, INT_ARR, initString)); assertEquals(0, Collections.foldl(FAIL_FUNCTION, EMPTY_ARR, 0)); + String expected = "null1null4null"; + assertEquals(expected, Collections.foldl(accumulateString, ARR_WITH_NULL, "")); } @Test public void foldr() throws Exception { - final Function2 accumulateString = new Function2() { + + final Function2 accumulateString = new Function2() { @Override - public String apply2(Integer arg1, String arg2) { - return arg1.toString() + arg2; + public String apply2(Object arg1, String arg2) { + return Objects.toString(arg1) + arg2; } }; + final String initString = "123"; final String resultString = "-14-3-1020123"; assertEquals(resultString, Collections.foldr(accumulateString, INT_ARR_NEGATED, initString)); @@ -159,9 +176,6 @@ public String apply2(Integer arg1, String arg2) { final Integer init = -33; final Integer result = 11; assertEquals(result, Collections.foldr(MINUS, INT_ARR, init)); - assertEquals(0, Collections.foldr(FAIL_FUNCTION, EMPTY_ARR, 0)); - } - } diff --git a/src/test/java/ru/spbau/mit/PredicateTest.java b/src/test/java/ru/spbau/mit/PredicateTest.java index 84b4e8c..eac7e92 100644 --- a/src/test/java/ru/spbau/mit/PredicateTest.java +++ b/src/test/java/ru/spbau/mit/PredicateTest.java @@ -2,6 +2,8 @@ import org.junit.Test; +import java.util.Objects; + import static org.junit.Assert.*; public class PredicateTest { @@ -10,7 +12,7 @@ public class PredicateTest { private static final Double ONE_DOUBLE = 1.0; private static final Integer ONE_INTEGER = 1; private static final Integer BIG_INTEGER = 123123124; - private static final int FOUR_INTEGER = 4; + private static final Integer FOUR_INTEGER = 4; // Does not work. // private static final Function2 less = new Function2() { @@ -60,7 +62,7 @@ public Boolean apply(Double arg) { private static final Predicate EQUAL_TO_ONE = new Predicate() { @Override public Boolean apply(Double arg) { - return ONE_DOUBLE == arg; + return Objects.equals(ONE_DOUBLE, arg); } }; @@ -70,7 +72,7 @@ public void and() throws Exception { assertFalse(IS_POSITIVE_INTEGER.and(LESS_THAN_FIVE).apply(BIG_INTEGER)); assertTrue(LESS_THAN_FIVE.and(IS_POSITIVE_INTEGER).apply(FOUR_INTEGER)); assertTrue(IS_POSITIVE_DOUBLE.and(EQUAL_TO_ONE).apply(ONE_DOUBLE)); - assertFalse(Predicate.ALWAYS_FALSE.and(FAIL_DOUBLE).apply(null)); +// assertFalse(Predicate.ALWAYS_FALSE.and(FAIL_DOUBLE).apply(null)); } @Test @@ -80,7 +82,7 @@ public void or() throws Exception { assertTrue(LESS_THAN_FIVE.or(IS_POSITIVE_INTEGER).apply(FIVE_INTEGER)); assertTrue(LESS_THAN_FIVE.or(FAIL_INTEGER).apply(ONE_INTEGER)); assertTrue(IS_POSITIVE_DOUBLE.or(EQUAL_TO_ONE).apply(ONE_DOUBLE)); - assertTrue(Predicate.ALWAYS_TRUE.or(FAIL_INTEGER).apply(null)); +// assertTrue(Predicate.ALWAYS_TRUE.or(FAIL_INTEGER).apply(null)); } @Test From 19e347102182bbb21aae6505b4d41ca0bd60d106 Mon Sep 17 00:00:00 2001 From: Andrey Kravtsun Date: Sun, 7 May 2017 01:55:57 +0300 Subject: [PATCH 6/6] Final changes. --- src/main/java/ru/spbau/mit/Collections.java | 6 ++--- src/main/java/ru/spbau/mit/Predicate.java | 3 --- .../java/ru/spbau/mit/CollectionsTest.java | 18 +++++++-------- src/test/java/ru/spbau/mit/Function1Test.java | 22 +++++-------------- 4 files changed, 16 insertions(+), 33 deletions(-) diff --git a/src/main/java/ru/spbau/mit/Collections.java b/src/main/java/ru/spbau/mit/Collections.java index 911f510..c2e5e0c 100644 --- a/src/main/java/ru/spbau/mit/Collections.java +++ b/src/main/java/ru/spbau/mit/Collections.java @@ -7,7 +7,7 @@ public final class Collections { private Collections() {} public static List map(Function1 f, Iterable c) { - List newcol = new ArrayList(); + List newcol = new ArrayList<>(); for (T el : c) { newcol.add(f.apply(el)); } @@ -15,7 +15,7 @@ public static List map(Function1 f, Iterable c) { } public static List filter(Predicate pred, Iterable c) { - List newcol = new ArrayList(); + List newcol = new ArrayList<>(); for (T el : c) { if (pred.apply(el)) { newcol.add(el); @@ -25,7 +25,7 @@ public static List filter(Predicate pred, Iterable c) { } public static List takeWhile(Predicate pred, Iterable c) { - List newcol = new ArrayList(); + List newcol = new ArrayList<>(); for (T el : c) { if (!pred.apply(el)) { break; diff --git a/src/main/java/ru/spbau/mit/Predicate.java b/src/main/java/ru/spbau/mit/Predicate.java index 57ee6f4..c2b9fd2 100644 --- a/src/main/java/ru/spbau/mit/Predicate.java +++ b/src/main/java/ru/spbau/mit/Predicate.java @@ -41,7 +41,4 @@ public Boolean apply(T arg) { } }; } - - @Override - public abstract Boolean apply(T arg); } diff --git a/src/test/java/ru/spbau/mit/CollectionsTest.java b/src/test/java/ru/spbau/mit/CollectionsTest.java index 824bb85..fb31488 100644 --- a/src/test/java/ru/spbau/mit/CollectionsTest.java +++ b/src/test/java/ru/spbau/mit/CollectionsTest.java @@ -8,6 +8,7 @@ import java.util.Objects; import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; import static org.junit.Assert.*; public class CollectionsTest { @@ -50,7 +51,7 @@ public Boolean apply(Object arg) { private static final Predicate NOT_NULL = IS_NULL.not(); - private static final List EMPTY_ARR = (List) emptyList(); + private static final List EMPTY_ARR = emptyList(); private static final Function2 MINUS = new Function2() { @Override @@ -92,10 +93,7 @@ public void map() throws Exception { @Test public void filter() throws Exception { - final ArrayList positiveOnly = new ArrayList() { { - add(-MAGIC_2); - add(-MAGIC_5); - } }; + final List positiveOnly = Arrays.asList(-MAGIC_2, -MAGIC_5); assertEquals(positiveOnly, Collections.filter(IS_POSITIVE_INTEGER, INT_ARR_NEGATED)); assertEquals(INT_ARR, Collections.filter(Predicate.ALWAYS_TRUE, INT_ARR)); assertEquals(EMPTY_ARR, Collections.filter(Predicate.ALWAYS_FALSE, INT_ARR)); @@ -108,7 +106,7 @@ public Boolean apply(Object arg) { } }; final int ten = 10; - assertEquals(Arrays.asList(ten), Collections.filter(isTen, INT_ARR)); + assertEquals(singletonList(ten), Collections.filter(isTen, INT_ARR)); } @Test @@ -119,7 +117,7 @@ public Boolean apply(CharSequence charSequence) { return charSequence.length() < 2; } }; - assertEquals(Arrays.asList("1"), Collections.takeWhile(u2, INT_ARR_STRINGED)); + assertEquals(singletonList("1"), Collections.takeWhile(u2, INT_ARR_STRINGED)); assertEquals(EMPTY_ARR, Collections.takeWhile(IS_POSITIVE_INTEGER, INT_ARR_NEGATED)); assertEquals(INT_ARR_STRINGED, Collections.takeWhile(Predicate.ALWAYS_TRUE, INT_ARR_STRINGED)); ArrayList nullArray = new ArrayList<>(); @@ -131,9 +129,9 @@ public Boolean apply(CharSequence charSequence) { @Test public void takeUnless() throws Exception { assertEquals(EMPTY_ARR, Collections.takeUnless(IS_POSITIVE_INTEGER.not(), INT_ARR_NEGATED)); - assertEquals(Arrays.asList(-1), Collections.takeUnless(IS_POSITIVE_INTEGER, INT_ARR_NEGATED)); + assertEquals(singletonList(-1), Collections.takeUnless(IS_POSITIVE_INTEGER, INT_ARR_NEGATED)); assertEquals(INT_ARR, Collections.takeUnless(Predicate.ALWAYS_FALSE, INT_ARR)); - ArrayList nullArr = new ArrayList<>(); + ArrayList nullArr = new ArrayList<>(); nullArr.add(null); assertEquals(nullArr, Collections.takeUnless(NOT_NULL, ARR_WITH_NULL)); assertEquals(EMPTY_ARR, Collections.takeUnless(IS_NULL, ARR_WITH_NULL)); @@ -142,7 +140,7 @@ public void takeUnless() throws Exception { @Test public void foldl() throws Exception { final Integer result = 10; - assertEquals(result, Collections.foldl(MINUS, INT_ARR, (Integer) 0)); + assertEquals(result, Collections.foldl(MINUS, INT_ARR, 0)); final Function2 accumulateString = new Function2() { @Override diff --git a/src/test/java/ru/spbau/mit/Function1Test.java b/src/test/java/ru/spbau/mit/Function1Test.java index 4af0133..ba3aa33 100644 --- a/src/test/java/ru/spbau/mit/Function1Test.java +++ b/src/test/java/ru/spbau/mit/Function1Test.java @@ -1,22 +1,17 @@ package ru.spbau.mit; import org.junit.Test; - -import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import static org.junit.Assert.*; public class Function1Test { - private static Function1> fromArrayToCollection = + private static final Function1> FROM_ARRAY_TO_COLLECTION = new Function1>() { @Override public Collection apply(Integer[] arg) { - Collection c = new ArrayList(); - for (Object o : arg) { - c.add((Integer) o); - } - return c; + return Arrays.asList(arg); } }; @@ -27,13 +22,6 @@ public Integer apply(Integer arg) { } }; - private final Function2 minus = new Function2() { - @Override - public Integer apply2(Integer arg1, Integer arg2) { - return arg1 - arg2; - } - }; - private final Function1 id = new Function1() { @Override public Object apply(Object arg) { @@ -79,10 +67,10 @@ public Integer apply(Object arg) { final int arraySize = 10; Integer[] integers = new Integer[arraySize]; - fromArrayToCollection.apply(integers); // compilation OK. + FROM_ARRAY_TO_COLLECTION.apply(integers); // compilation OK. // Double []doubles = new Double[arraySize]; -// fromArrayToCollection.apply(doubles); // compilation Failed. +// FROM_ARRAY_TO_COLLECTION.apply(doubles); // compilation Failed. // Function1 // Function1 u1 = new Function1() {