diff --git a/optionals/.project b/optionals/.project
index 1917593..d24053b 100644
--- a/optionals/.project
+++ b/optionals/.project
@@ -14,4 +14,15 @@
org.eclipse.jdt.core.javanature
+
+
+ 1741281320906
+
+ 30
+
+ org.eclipse.core.resources.regexFilterMatcher
+ node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__
+
+
+
diff --git a/optionals/src/optionals/Main.java b/optionals/src/optionals/Main.java
index e882597..bfd3247 100644
--- a/optionals/src/optionals/Main.java
+++ b/optionals/src/optionals/Main.java
@@ -1,42 +1,120 @@
package optionals;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Predicate;
+import tester.Tester;
class OptionalUtils {
// Return the list of `f()` applied to every element in `xs`, but do not
// include the empty results.
static List
convertPassing(List xs, Function> f) {
- return null;
+ return dropEmpty(xs.stream().map(f).toList());
}
// Return the list of `f()` applied to every element in `xs`, but do not
// include the resuslts that don't pass `pred()`.
static List
convertPassing(List xs, Function f, Predicate pred) {
- return null;
+ return xs.stream().map(f).filter(pred).toList();
}
// Drop all empty values.
static List dropEmpty(List> xs) {
- return xs.stream().filter(Optional::isEmpty);
+ return xs
+ .stream() // Convert to stream.
+ .filter(Optional::isPresent) // Filter out empty.
+ .map(Optional::get) // Extract value from optional.
+ .toList(); // Convert back to list.
}
// Return a new function that applies `f()` to non-null values and returns
// empty optionals on null values.
static Function> nullFriendly(Function f) {
- return null;
+ // f() could still return NULL, doesn't check that case.
+ return x -> x == null ? Optional.empty() : Optional.of(f.apply(x));
}
// Apply and to the boolean values if both are present, otherwise return
// empty optional.
static Optional
optionalAnd(Optional b1, Optional b2) {
- return null;
+ return b1.isPresent() && b2.isPresent()
+ ? Optional.of(b1.get() && b2.get())
+ : Optional.empty();
}
}
-class Examples {}
+class Examples {
+ List> things = List.of(
+ Optional.of("Hello,"), Optional.empty(), Optional.of(" "),
+ Optional.of("world."), Optional.empty()
+ );
+
+ List thingsMissing =
+ new ArrayList<>(Arrays.asList("Hello,", null, " ", "world.", null));
+
+ List thingsFrobnicated =
+ List.of(",olleH,olleH", " ", ".dlrow.dlrow");
+
+ Optional decide(String s) {
+ return s.length() == 3 ? Optional.of(s.substring(0, 1))
+ : Optional.empty();
+ }
+
+ Boolean judge(String s) { return s.contains("h"); }
+ String augment(String s) { return s.repeat(2); }
+ String frobnicate(String s) {
+ return new StringBuilder(s).reverse().toString().repeat(2);
+ }
+
+ void testDropEmpty(Tester t) {
+ t.checkExpect(
+ OptionalUtils.dropEmpty(things), List.of("Hello,", " ", "world.")
+ );
+ }
+
+ void testConvertPassing(Tester t) {
+ t.checkExpect(
+ OptionalUtils.convertPassing(
+ List.of("ndsf", "asd", "hjkl"), this::decide
+ ),
+ List.of("a")
+ );
+
+ t.checkExpect(
+ OptionalUtils.convertPassing(
+ List.of("uff", "fhf", "hek", "uyr"), this::augment, this::judge
+ ),
+ List.of("fhffhf", "hekhek")
+ );
+ }
+
+ void testNullFriendly(Tester t) {
+ t.checkExpect(
+ OptionalUtils.convertPassing(
+ thingsMissing, OptionalUtils.nullFriendly(this::frobnicate)
+ ),
+ thingsFrobnicated
+ );
+ }
+
+ void testOptionalAnd(Tester t) {
+ t.checkExpect(
+ OptionalUtils.optionalAnd(Optional.of(true), Optional.of(true)),
+ Optional.of(true)
+ );
+ t.checkExpect(
+ OptionalUtils.optionalAnd(Optional.of(true), Optional.of(false)),
+ Optional.of(false)
+ );
+ t.checkExpect(
+ OptionalUtils.optionalAnd(Optional.of(true), Optional.empty()),
+ Optional.empty()
+ );
+ }
+}