是否有Java等效的SQL COALESCE
函数?也就是说,有没有办法返回几个变量的第一个非空值?
例如
Double a = null;
Double b = 4.4;
Double c = null;
Run Code Online (Sandbox Code Playgroud)
我想无论如何都将返回的第一个非NULL值的语句a
,b
以及c
-在这种情况下,它会返回b
,或4.4.(类似于sql方法 - 返回COALESCE(a,b,c)
).我知道我可以用以下方式明确地做到:
return a != null ? a : (b != null ? b : c)
Run Code Online (Sandbox Code Playgroud)
但我想知道是否有任何内置的,可接受的功能来实现这一目标.
And*_*lis 171
Apache Commons Lang 3
ObjectUtils.firstNonNull(T...)
Java 8 Stream
Stream.of(T...).filter(Objects::nonNull).findFirst().orElse(null)
les*_*es2 102
不,没有.
你最接近的是:
public static <T> T coalesce(T ...items) {
for(T i : items) if(i != null) return i;
return null;
}
Run Code Online (Sandbox Code Playgroud)
出于有效的原因,您可以按如下方式处理常见情况:
public static <T> T coalesce(T a, T b) {
return a == null ? b : a;
}
public static <T> T coalesce(T a, T b, T c) {
return a != null ? a : (b != null ? b : c);
}
public static <T> T coalesce(T a, T b, T c, T d) {
return ...
}
Run Code Online (Sandbox Code Playgroud)
Dav*_*ave 57
如果只检查两个变量并且您正在使用Guava,则可以使用MoreObjects.firstNonNull(T first,T second).
Chr*_*oom 46
如果只有两个参考测试,并且您使用的是Java 8,则可以使用
Object o = null;
Object p = "p";
Object r = Optional.ofNullable( o ).orElse( p );
System.out.println( r ); // p
Run Code Online (Sandbox Code Playgroud)
如果导入静态可选,表达式也不错.
不幸的是,使用Optional-method无法使用"几个变量".相反,你可以使用:
Object o = null;
Object p = null;
Object q = "p";
Optional<Object> r = Stream.of( o, p, q ).filter( Objects::nonNull ).findFirst();
System.out.println( r.orElse(null) ); // p
Run Code Online (Sandbox Code Playgroud)
Eri*_*ric 24
继LES2的答案之后,您可以通过调用重载函数来消除高效版本中的一些重复:
public static <T> T coalesce(T a, T b) {
return a != null ? a : b;
}
public static <T> T coalesce(T a, T b, T c) {
return a != null ? a : coalesce(b,c);
}
public static <T> T coalesce(T a, T b, T c, T d) {
return a != null ? a : coalesce(b,c,d);
}
public static <T> T coalesce(T a, T b, T c, T d, T e) {
return a != null ? a : coalesce(b,c,d,e);
}
Run Code Online (Sandbox Code Playgroud)
这种情况需要一些预处理器.因为如果你编写一个函数(静态方法)来选择第一个非空值,它会评估所有项目.如果某些项是方法调用(可能是时间昂贵的方法调用),则会出现问题.即使它们之前的任何项不为null,也会调用此方法.
有些功能就是这样
public static <T> T coalesce(T ...items) …
Run Code Online (Sandbox Code Playgroud)
应该使用,但在编译成字节代码之前,应该有一个预处理器,它找到这个"合并函数"的用法,并用类似的结构替换它
a != null ? a : (b != null ? b : c)
Run Code Online (Sandbox Code Playgroud)
更新2014-09-02:
感谢Java 8和Lambdas,有可能在Java中实现真正的合并!包括关键特性:特殊表达式仅在需要时进行评估 - 如果前一个不为空,则不评估后续的(不调用方法,不进行计算或磁盘/网络操作).
我写了一篇关于它的文章Java 8:coalesce - hledámeneNULLovéhodnoty - (用捷克语编写,但我希望代码示例对每个人都是可以理解的).
使用番石榴,您可以:
Optional.fromNullable(a).or(b);
Run Code Online (Sandbox Code Playgroud)
它不会抛出NPE如果两个a
和b
是null
.
编辑:我错了,它确实抛出了NPE.MichalČizmazia评论的正确方法是:
Optional.fromNullable(a).or(Optional.fromNullable(b)).orNull();
Run Code Online (Sandbox Code Playgroud)
你可以试试这个:
public static <T> T coalesce(T... t) {
return Stream.of(t).filter(Objects::nonNull).findFirst().orElse(null);
}
Run Code Online (Sandbox Code Playgroud)
基于此回复
小智 5
当您想避免评估某些昂贵的方法时,使用供应商怎么样?
像这样:
public static <T> T coalesce(Supplier<T>... items) {
for (Supplier<T> item : items) {
T value = item.get();
if (value != null) {
return value;
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
然后像这样使用它:
Double amount = coalesce(order::firstAmount, order::secondAmount, order::thirdAmount)
Run Code Online (Sandbox Code Playgroud)
您还可以使用重载方法来进行带有两个、三个或四个参数的调用。
此外,您还可以使用流,如下所示:
public static <T> T coalesce2(Supplier<T>... s) {
return Arrays.stream(s).map(Supplier::get).filter(Objects::nonNull).findFirst().orElse(null);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
77609 次 |
最近记录: |