Java 多个可选实例的逻辑或逻辑?
是否有一种更优雅的方式来使用Java核心API表示以下算法Java 多个可选实例的逻辑或逻辑?,java,java-stream,optional,Java,Java Stream,Optional,是否有一种更优雅的方式来使用Java核心API表示以下算法 Optional<Float> input = Optional.of(A); Optional<Float> output = input.map(function1).map(function2); if (!output.isPresent()) { output = input.map(function1).map(function2); if (!output.isPresent()) {
Optional<Float> input = Optional.of(A);
Optional<Float> output = input.map(function1).map(function2);
if (!output.isPresent())
{
output = input.map(function1).map(function2);
if (!output.isPresent())
{
output = input.map(function3).map(function4);
if (!output.isPresent())
output = input.map(function5).map(function6);
}
}
这就是我目前所得到的,但我们能做得更好吗
public class Optionals
{
/**
* @param <T> the type of value returned by the Optionals
* @param suppliers one or more suppliers that return a supplier
* @return the first Optional that {@link Optional#isPresent() isPresent()}
*/
public static <T> Optional<T> or(Supplier<Optional<T>>... suppliers)
{
for (Supplier<Optional<T>> supplier: suppliers)
{
Optional<T> candidate = supplier.get();
if (candidate.isPresent())
return candidate;
}
return Optional.empty();
}
/**
* Prevent construction.
*/
private Optionals()
{
}
}
公共类选项
{
/**
*@param选项返回的值的类型
*@param suppliers返回供应商的一个或多个供应商
*@返回第一个可选的{@link Optional#isPresent()isPresent()}
*/
公共静态或可选(供应商…供应商)
{
对于(供应商:供应商)
{
可选候选者=supplier.get();
if(candidate.isPresent())
返回候选人;
}
返回可选的.empty();
}
/**
*防止施工。
*/
私人期权()
{
}
}
可选的
有一个orElse
方法;如果调用此函数,它将返回可选
中的值(如果该值不为空),或者返回传递给或的值(如果该值为空)
因此,您可以使用嵌套的orElse
调用,如下所示:
Float output = input.map(function1).map(function2)
.orElse(input.map(function3).map(function4)
.orElse(input.map(function5).map(function6)
.orElse(0.0f)));
请注意,在这种情况下,最终结果不是可选
,而是浮点
。如果您不希望在没有任何映射返回值时使用默认返回值,例如0.0f
,您可以使其引发异常:
Float output = input.map(function1).map(function2)
.orElse(input.map(function3).map(function4)
.orElse(input.map(function5).map(function6)
.orElseThrow(() -> new IllegalStateException("No result"))));
在这种情况下,我不太喜欢供应商
方案,可能更喜欢这种方法:
public static void main(String[] args) {
Float x = 1.0f;
final Optional<Float> input = Optional.of(x);
Optional<Float> output = firstPresent(input, (a) -> a.map(FUNCTION1).map(FUNCTION2),
(a) -> a.map(FUNCTION3).map(FUNCTION4),
(a) -> a.map(FUNCTION5).map(FUNCTION6));
}
@SafeVarargs
public static <I,O> Optional<O> firstPresent(Optional<I> input, Function<Optional<I>, Optional<O>>... functions) {
for (Function<Optional<I>, Optional<O>> function : functions) {
final Optional<O> output = function.apply(input);
if(output.isPresent()) {
return output;
}
}
return Optional.empty();
}
publicstaticvoidmain(字符串[]args){
浮动x=1.0f;
最终可选输入=可选的(x);
可选输出=firstPresent(输入,(a)->a.map(函数1).map(函数2),
(a) ->a.map(功能3).map(功能4),
(a) ->a.map(函数5).map(函数6));
}
@安全变量
公共静态可选firstPresent(可选输入、函数…函数){
for(函数:函数){
最终可选输出=函数。应用(输入);
if(output.isPresent()){
返回输出;
}
}
返回可选的.empty();
}
通过Java8谓词(Yosi Lev)实现“多条件”逻辑AND的方法:
publicstaticvoidmain(字符串[]args){
Optional stringOptional=Optional.of(“这是一个字符串”);
谓词isNotNull=s->s!=null;
谓词isSizeGT0=s->s.length()>0;
谓词isSizeGT20=s->s.length()>20;
//使用所有需要批准的谓词调用isOk():
System.out.println(isOk(stringOptional,isNotNull,isSizeGT0,isSizeGT20));
}//main()
@安全变量
私有静态布尔isOk(可选inp、谓词…谓词){
//对输入强制执行所有谓词。。
布尔b=Arrays.stream(谓词).allMatch(pr->pr.test(inp.get());
返回b;
}
未对此进行测试。Java8Lambdas使用数组流。这将评估所有供应商,这不是我想要的。我希望返回以按顺序评估供应商,并在其中一个供应商返回非空值时立即停止。Arrays.stream(suppliers).map(Supplier::get).filter(可选::isPresent).findFirst().orElse(可选::empty)
这不会导致总是对函数3到函数6进行求值吗?@您可以使用构造函数传递lambda,以避免急于求值。这对我不起作用,因为它返回t
而不是可选的。我有3种方法来查找值,但这3种方法都可能返回空值。我会将您的或
函数重命名为firstOf
,然后使用它。在我看来,这是一个很好的解决方案。在我的例子中,供应商
从外部代码块捕获输入
,但是是的,这更明确。@Gili这样,您也可以更容易地重用lambdas/函数。供应商需要为每个输入构建。我并不真正重用lambda/函数,但这是一个很好的观点。谁知道我将来可能需要什么。。。
Float output = input.map(function1).map(function2)
.orElse(input.map(function3).map(function4)
.orElse(input.map(function5).map(function6)
.orElseThrow(() -> new IllegalStateException("No result"))));
public static void main(String[] args) {
Float x = 1.0f;
final Optional<Float> input = Optional.of(x);
Optional<Float> output = firstPresent(input, (a) -> a.map(FUNCTION1).map(FUNCTION2),
(a) -> a.map(FUNCTION3).map(FUNCTION4),
(a) -> a.map(FUNCTION5).map(FUNCTION6));
}
@SafeVarargs
public static <I,O> Optional<O> firstPresent(Optional<I> input, Function<Optional<I>, Optional<O>>... functions) {
for (Function<Optional<I>, Optional<O>> function : functions) {
final Optional<O> output = function.apply(input);
if(output.isPresent()) {
return output;
}
}
return Optional.empty();
}
public static void main(String[] args) {
Optional<String> stringOptional = Optional.of( "this is a string" );
Predicate<String> isNotNull = s-> s != null;
Predicate<String> isSizeGT0 = s-> s.length() > 0 ;
Predicate<String> isSizeGT20 = s-> s.length() > 20 ;
// calling isOk() with all required Predicates to be approved:
System.out.println(isOk(stringOptional, isNotNull, isSizeGT0, isSizeGT20));
}//main()
@SafeVarargs
private static <I> boolean isOk(Optional<I> inp, Predicate<I>... predicates){
// Enforce all predicates on input..
boolean b = Arrays.stream( predicates ).allMatch( pr->pr.test( inp.get()));
return b;
}