返回第一个非空值 [英] Return first non-null value

查看:653
本文介绍了返回第一个非空值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有许多功能:

String first(){}
String second(){}
...
String default(){}

每个都可以返回一个null值,默认值除外。 每个功能可以采用不同的参数。例如,第一个可以不参数,第二个可以接受一个字符串,第三个可以接受三个参数等。我想做的是:

Each can return a null value, except the default. each function can take different parameters. For example, first could take no arguments, second could take in a String, third could take three arguments, etc. What I'd like to do is something like:

ObjectUtils.firstNonNull(first(), second(), ..., default());

问题在于,由于函数调用,这是急切的评估。我想在哪里提前退出,在第二个函数之后说(因为函数调用可能很昂贵,想想API调用等)。在其他语言中,你可以做类似的事情:

The problem is that because of the function call, this does eager evaluation. Where'd I'd like to exit early, say after the second function (because the function calls can be expensive, think API calls, etc). In other languages, you can do something similar to this:

return first() || second() || ... || default()

在Java中,我知道我可以做类似的事情:

In Java, I know I can do something like:

String value;
if (value = first()) == null || (value = second()) == null ...
return value;

由于所有== null检查,这不是非常易读的IMO。 ObjectUtils.firstNonNull()首先创建一个集合,然后迭代,只要该函数被懒惰地评估,这是可以的。

That's not very readable IMO because of all the == null checks.ObjectUtils.firstNonNull() creates a collection first, and then iterates, which is okay as long as the function gets evaluated lazily.

建议? (除了做一堆ifs)

Suggestions? (besides doing a bunch of ifs)

推荐答案

String s = Stream.<Supplier<String>>of(this::first, this::second /*, ... */)
                 .map(Supplier::get)
                 .filter(Objects::nonNull)
                 .findFirst()
                 .orElseGet(this::defaultOne);

它在第一个非空值上停止或者设置从<$ c返回的值$ C> defaultOne 。只要你保持顺序,你就是安全的。当然这需要Java 8或更高版本。

It stops on the first non-null value or else sets the value which is returned from defaultOne. As long as you stay sequential, you are safe. Of course this requires Java 8 or later.

它在第一次出现非空值时停止的原因是由于 Stream 处理每一步。 map 中间操作 filter 另一边的findFirst 短路终端操作。所以它继续下一个元素,直到一个匹配过滤器。如果没有元素匹配,则返回空的可选项,因此 orElseGet - 调用供应商。

The reason why it stops on the first occurrence of a non-null value is due how the Stream handles each step. The map is an intermediate operation, so is filter. The findFirst on the other side is a short-circuiting terminal operation. So it continues with the next element until one matches the filter. If no element matches an empty optional is returned and so the orElseGet-supplier is called.

this :: first 等只是方法引用。如果它们是静态的,请用 YourClassName :: first 等替换它。

this::first, etc. are just method references. If they are static replace it with YourClassName::first, etc.

这是一个例子,如果签名是你的方法会有所不同:

Here is an example if the signature of your methods would differ:

String s = Stream.<Supplier<String>>of(() -> first("takesOneArgument"),
                                       () -> second("takes", 3, "arguments")
                                   /*, ... */)
                 .map(Supplier::get)
                 .filter(Objects::nonNull)
                 .findFirst()
                 .orElseGet(this::defaultOne);

请注意 供应商 仅在您拨打获取就可以了。这样你就会得到懒惰的评估行为。 supplier-lambda-expression中的方法参数必须是最终的或有效的最终。

Note that the Supplier is only evaluated when you call get on it. That way you get your lazy evaluation behaviour. The method-parameters within your supplier-lambda-expression must be final or effectively final.

这篇关于返回第一个非空值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆