The problem is that Java SE 8 Optional is incompatible with the guard clause, I wondered if it could coexist with the guard clause.
package com.ikemo3;
import java.util.Optional;
public class Main {
public static void main(String[] args) {
System.out.println(Main.sqrt("16"));
System.out.println(Main.sqrt("-16"));
System.out.println(Main.sqrt("str"));
}
public static String sqrt(String str) {
return Optionals.of(str, String.class)
.guard((s) -> toInteger(s), () -> "Not an integer")
.guard((i) -> sqrt(i), () -> "Not a positive number")
.get((d) -> String.valueOf(d));
}
/**
*If the value is positive, make it an integer
*/
public static Optional<Integer> toInteger(String str) {
try {
return Optional.of(Integer.valueOf(str));
} catch (NumberFormatException e) {
return Optional.empty();
}
}
/**
*If the value is positive, take the square root
*/
public static Optional<Double> sqrt(int i) {
if (i >= 0) {
return Optional.of(Math.sqrt(i));
} else {
return Optional.empty();
}
}
}
The output result is as follows.
4.0
Not a positive number
Not an integer
How to call is like this. I wonder if it looks like a guard clause.
public static String sqrt(String str) {
return Optionals.of(str, String.class)
.guard((s) -> toInteger(s), () -> "Not an integer")
.guard((i) -> sqrt(i), () -> "Not a positive number")
.get((d) -> String.valueOf(d));
}
The implementation of the class is as follows.
package com.ikemo3;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;
public class Optionals<IN, RET> {
private final IN value;
private final RET elseValue;
private final Class<RET> clazz;
public static <IN, OUT> Optionals<IN, OUT> of(IN value, Class<OUT> clazz) {
return new Optionals(value, clazz);
}
private Optionals(IN value, Class<RET> clazz) {
this.value = value;
this.clazz = clazz;
this.elseValue = null;
}
private Optionals(RET elseValue) {
this.value = null;
this.clazz = null;
this.elseValue = elseValue;
}
public <OUT> Optionals<OUT, RET> guard(Function<IN, Optional<OUT>> func, Supplier<RET> elseValue) {
if (this.elseValue != null) {
return new Optionals(this.elseValue);
}
Optional<OUT> result = func.apply(this.value);
if (result.isPresent()) {
return Optionals.of(result.get(), this.clazz);
} else {
return new Optionals(elseValue.get());
}
}
public RET get(Function<IN, RET> func) {
if (this.elseValue != null) {
return this.elseValue;
} else {
return func.apply(this.value);
}
}
}
Recommended Posts