From ee08d4a060bd9bcb203ba6170f26d336f8343daf Mon Sep 17 00:00:00 2001 From: h908714124 Date: Thu, 22 Jul 2021 11:32:47 +0200 Subject: [PATCH] move static methods to Eithers, add toOptionalList --- src/main/java/io/jbock/util/Either.java | 52 ---------- src/main/java/io/jbock/util/Eithers.java | 96 +++++++++++++++++++ .../io/jbock/util/ValidatingCollector.java | 2 +- .../io/jbock/util/ValidatingCollectorAll.java | 2 +- src/test/java/io/jbock/util/EitherTest.java | 8 -- src/test/java/io/jbock/util/EithersTest.java | 37 +++++++ .../util/ValidatingCollectorAllTest.java | 6 -- .../jbock/util/ValidatingCollectorTest.java | 6 -- 8 files changed, 135 insertions(+), 74 deletions(-) create mode 100644 src/main/java/io/jbock/util/Eithers.java create mode 100644 src/test/java/io/jbock/util/EithersTest.java diff --git a/src/main/java/io/jbock/util/Either.java b/src/main/java/io/jbock/util/Either.java index f793be7..dbe8719 100644 --- a/src/main/java/io/jbock/util/Either.java +++ b/src/main/java/io/jbock/util/Either.java @@ -1,10 +1,8 @@ package io.jbock.util; -import java.util.List; import java.util.Optional; import java.util.function.Consumer; import java.util.function.Function; -import java.util.stream.Collector; /** * A class that acts as a container for a value of one of two types. An Either @@ -49,56 +47,6 @@ public static Either right(R value) { return new Right<>(value); } - /** - * Returns a collector that accumulates a Right containing all values in the original order, - * if there are no Left instances in the stream. - * If the stream contains a Left, it accumulates a Left containing the first LHS value in the stream. - * - * @param the LHS type - * @param the RHS type - * @return a Right containing all RHS values in the stream, - * or, if an LHS value exists, a Left containing the first such value - */ - public static Collector, ?, Either>> toValidList() { - return new ValidatingCollector<>(); - } - - /** - * Returns a collector that accumulates a Right containing all values in the original order, - * if there are no Left instances in the stream. - * If the stream contains a Left, it accumulates a Left containing all LHS values in the stream, - * in the original order. - * - * @param the LHS type - * @param the RHS type - * @return a list of the RHS values in the stream, - * or, if an LHS value exists, a nonempty list of all LHS values - */ - public static Collector, ?, Either, List>> toValidListAll() { - return new ValidatingCollectorAll<>(); - } - - /** - * If the provided list is empty, returns an empty {@link Optional}. - * Otherwise, returns an {@code Optional} containing the list. - * - *

This utility method can sometimes be used to express a - * {@link #filter(Function)} operation more efficiently. - * - * @param values a list of objects - * @param the type of the members of {@code values} - * @return an {@code Optional} which is empty if and only if {@code values} - * is empty - */ - public static Optional> optionalList(List values) { - if (values.isEmpty()) { - return Optional.empty(); - } - @SuppressWarnings("unchecked") - List result = (List) values; - return Optional.of(result); - } - /** * If this is a Right, returns a Right containing the result of applying * the mapper function to the RHS value. diff --git a/src/main/java/io/jbock/util/Eithers.java b/src/main/java/io/jbock/util/Eithers.java new file mode 100644 index 0000000..cc25ef0 --- /dev/null +++ b/src/main/java/io/jbock/util/Eithers.java @@ -0,0 +1,96 @@ +package io.jbock.util; + +import java.util.List; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Collector; +import java.util.stream.Collectors; + +/** + * This class contains static utility methods related to + * the {@link Either} type. + */ +public final class Eithers { + + private Eithers() { + } + + /** + * Returns a {@code Collector} that accumulates the input elements into + * a Right containing all values in the original order, + * but only if there are no Left instances in the stream. + * If the stream does contain a Left instance, it discards the Right instances and + * accumulates a Left instance, which contains the first LHS value in the stream, + * in encounter order. + * + * @param the type of the LHS values in the stream + * @param the type of the RHS values in the stream + * @return a {@code Collector} which collects all the input elements into + * a Right containing all RHS values in the stream, or, + * if an LHS value exists, a Left containing the first LHS value + */ + public static Collector, ?, Either>> toValidList() { + return new ValidatingCollector<>(); + } + + /** + * Returns a {@code Collector} that accumulates the input elements into + * a Right containing all values in the original order, + * but only if there are no Left instances in the stream. + * If the stream does contain a Left instance, it discards the Right instances and + * accumulates a Left containing only the LHS values, + * in encounter order. + * + * @param the type of the LHS values in the stream + * @param the type of the RHS values in the stream + * @return a {@code Collector} which collects all the input elements into + * a Right containing all RHS values in the stream, + * or, if an LHS value exists, a Left containing a nonempty list + * of all LHS values in the stream + */ + public static Collector, ?, Either, List>> toValidListAll() { + return new ValidatingCollectorAll<>(); + } + + /** + * Returns a {@code Collector} that accumulates the input elements into + * a new {@code List}. There are no guarantees on the type, mutability, + * serializability, or thread-safety of the {@code List} returned. + * The resulting list is wrapped in an {@code Optional}, + * which is empty if and only if the list is empty. + * + * @see #optionalList(List) + * @param the type of the input elements + * @return a list of the RHS values in the stream, + * or, if an LHS value exists, a nonempty list of all LHS values + */ + public static Collector>> toOptionalList() { + return Collectors.collectingAndThen( + Collectors.toList(), + Eithers::optionalList); + } + + /** + * If the provided list is empty, returns an empty {@link Optional}. + * Otherwise, returns an {@code Optional} containing the nonempty + * input list. + * + *

Note: The resulting {@code Optional} might be used in a + * {@link Either#filter(Function) filter} or + * {@link Either#filterLeft(Function) filterLeft} operation. + * + * @see #toOptionalList() + * @param values a list of objects + * @param the type of the members of {@code values} + * @return an {@code Optional} which is either empty, or + * contains a nonempty list + */ + public static Optional> optionalList(List values) { + if (values.isEmpty()) { + return Optional.empty(); + } + @SuppressWarnings("unchecked") + List result = (List) values; + return Optional.of(result); + } +} diff --git a/src/main/java/io/jbock/util/ValidatingCollector.java b/src/main/java/io/jbock/util/ValidatingCollector.java index 4b073cc..07a64ff 100644 --- a/src/main/java/io/jbock/util/ValidatingCollector.java +++ b/src/main/java/io/jbock/util/ValidatingCollector.java @@ -10,7 +10,7 @@ import java.util.stream.Collector; /** - * Internal implementation of {@link Either#toValidList()}. + * Internal implementation of {@link Eithers#toValidList()}. * * @param the type of the LHS values in the stream * @param the type of the RHS values in the stream diff --git a/src/main/java/io/jbock/util/ValidatingCollectorAll.java b/src/main/java/io/jbock/util/ValidatingCollectorAll.java index bec11b0..9602086 100644 --- a/src/main/java/io/jbock/util/ValidatingCollectorAll.java +++ b/src/main/java/io/jbock/util/ValidatingCollectorAll.java @@ -10,7 +10,7 @@ import java.util.stream.Collector; /** - * Internal implementation of {@link Either#toValidListAll()}. + * Internal implementation of {@link Eithers#toValidListAll()}. * * @param the type of the LHS values in the stream * @param the type of the RHS values in the stream diff --git a/src/test/java/io/jbock/util/EitherTest.java b/src/test/java/io/jbock/util/EitherTest.java index ba417fa..7fde5ce 100644 --- a/src/test/java/io/jbock/util/EitherTest.java +++ b/src/test/java/io/jbock/util/EitherTest.java @@ -4,7 +4,6 @@ import org.junit.jupiter.api.Test; import java.io.IOException; -import java.util.List; import java.util.Objects; import java.util.Optional; @@ -135,11 +134,4 @@ void testOrElseThrow() { Either right = Either.right("2"); assertEquals("2", right.orElseThrow(IllegalArgumentException::new)); } - - @Test - void testOptionalList() { - assertEquals(Optional.empty(), Either.optionalList(List.of())); - assertEquals(Optional.of(List.of(1)), Either.optionalList(List.of(1))); - assertEquals(Optional.of(List.of("1", "2")), Either.optionalList(List.of("1", "2"))); - } } diff --git a/src/test/java/io/jbock/util/EithersTest.java b/src/test/java/io/jbock/util/EithersTest.java new file mode 100644 index 0000000..1eba2b1 --- /dev/null +++ b/src/test/java/io/jbock/util/EithersTest.java @@ -0,0 +1,37 @@ +package io.jbock.util; + +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; + +import static io.jbock.util.Eithers.optionalList; +import static io.jbock.util.Eithers.toOptionalList; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class EithersTest { + + @Test + void testOptionalList() { + assertEquals(Optional.empty(), optionalList(List.of())); + assertEquals(Optional.of(List.of(1)), optionalList(List.of(1))); + } + + @Test + void testToValidList() { + assertTrue(Eithers.toValidList() instanceof ValidatingCollector); + } + + @Test + void testToValidListAll() { + assertTrue(Eithers.toValidListAll() instanceof ValidatingCollectorAll); + } + + @Test + void testToOptionalList() { + assertEquals(Optional.empty(), Stream.of().collect(toOptionalList())); + assertEquals(Optional.of(List.of(1)), Stream.of(1).collect(toOptionalList())); + } +} \ No newline at end of file diff --git a/src/test/java/io/jbock/util/ValidatingCollectorAllTest.java b/src/test/java/io/jbock/util/ValidatingCollectorAllTest.java index 9071324..9ceffcc 100644 --- a/src/test/java/io/jbock/util/ValidatingCollectorAllTest.java +++ b/src/test/java/io/jbock/util/ValidatingCollectorAllTest.java @@ -7,7 +7,6 @@ import static io.jbock.util.Either.left; import static io.jbock.util.Either.right; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; class ValidatingCollectorAllTest { @@ -32,11 +31,6 @@ void testRight() { assertEquals(right(List.of(1, 2, 3)), apply(List.of(right(1), right(2), right(3)))); } - @Test - void testFactoryMethod() { - assertTrue(Either.toValidList() instanceof ValidatingCollector); - } - private Either, List> apply(List> data) { return data.stream().collect(new ValidatingCollectorAll<>()); } diff --git a/src/test/java/io/jbock/util/ValidatingCollectorTest.java b/src/test/java/io/jbock/util/ValidatingCollectorTest.java index 7557f03..40f6296 100644 --- a/src/test/java/io/jbock/util/ValidatingCollectorTest.java +++ b/src/test/java/io/jbock/util/ValidatingCollectorTest.java @@ -7,7 +7,6 @@ import static io.jbock.util.Either.left; import static io.jbock.util.Either.right; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; class ValidatingCollectorTest { @@ -32,11 +31,6 @@ void testRight() { assertEquals(right(List.of(1, 2, 3)), apply(List.of(right(1), right(2), right(3)))); } - @Test - void testFactoryMethod() { - assertTrue(Either.toValidListAll() instanceof ValidatingCollectorAll); - } - private Either> apply(List> data) { return data.stream().collect(new ValidatingCollector<>()); }