There are things that have been done.

This commit is contained in:
Jacob Signorovitch
2025-03-26 09:30:27 -04:00
parent 677b8941e3
commit 59efc034a8
2 changed files with 95 additions and 6 deletions

View File

@@ -14,4 +14,15 @@
<natures> <natures>
<nature>org.eclipse.jdt.core.javanature</nature> <nature>org.eclipse.jdt.core.javanature</nature>
</natures> </natures>
<filteredResources>
<filter>
<id>1741281320906</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription> </projectDescription>

View File

@@ -1,42 +1,120 @@
package optionals; package optionals;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
import tester.Tester;
class OptionalUtils { class OptionalUtils {
// Return the list of `f()` applied to every element in `xs`, but do not // Return the list of `f()` applied to every element in `xs`, but do not
// include the empty results. // include the empty results.
static <X, Y> List<Y> static <X, Y> List<Y>
convertPassing(List<X> xs, Function<X, Optional<Y>> f) { convertPassing(List<X> xs, Function<X, Optional<Y>> f) {
return null; return dropEmpty(xs.stream().map(f).toList());
} }
// Return the list of `f()` applied to every element in `xs`, but do not // Return the list of `f()` applied to every element in `xs`, but do not
// include the resuslts that don't pass `pred()`. // include the resuslts that don't pass `pred()`.
static <X, Y> List<Y> static <X, Y> List<Y>
convertPassing(List<X> xs, Function<X, Y> f, Predicate<Y> pred) { convertPassing(List<X> xs, Function<X, Y> f, Predicate<Y> pred) {
return null; return xs.stream().map(f).filter(pred).toList();
} }
// Drop all empty values. // Drop all empty values.
static <X> List<X> dropEmpty(List<Optional<X>> xs) { static <X> List<X> dropEmpty(List<Optional<X>> 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 // Return a new function that applies `f()` to non-null values and returns
// empty optionals on null values. // empty optionals on null values.
static <X, Y> Function<X, Optional<Y>> nullFriendly(Function<X, Y> f) { static <X, Y> Function<X, Optional<Y>> nullFriendly(Function<X, Y> 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 // Apply and to the boolean values if both are present, otherwise return
// empty optional. // empty optional.
static Optional<Boolean> static Optional<Boolean>
optionalAnd(Optional<Boolean> b1, Optional<Boolean> b2) { optionalAnd(Optional<Boolean> b1, Optional<Boolean> b2) {
return null; return b1.isPresent() && b2.isPresent()
? Optional.of(b1.get() && b2.get())
: Optional.empty();
} }
} }
class Examples {} class Examples {
List<Optional<String>> things = List.of(
Optional.of("Hello,"), Optional.empty(), Optional.of(" "),
Optional.of("world."), Optional.empty()
);
List<String> thingsMissing =
new ArrayList<>(Arrays.asList("Hello,", null, " ", "world.", null));
List<String> thingsFrobnicated =
List.of(",olleH,olleH", " ", ".dlrow.dlrow");
Optional<String> 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()
);
}
}