Java充斥着如下语句:
if(cage.getChicken() != null) {
dinner = cage.getChicken();
} else {
dinner = getFreeRangeChicken();
}
在将返回的对象分配给getChicken()
之前,需要对dinner
进行两次调用。
这也可以写成一行,如下所示:
dinner = cage.getChicken() != null? cage.getChicken() : getFreeRangeChicken();
但是仍有两次拨打getChicken()
。
当然我们可以分配一个局部变量然后再次使用三元运算符来分配它,如果它不是null,但这是两行而不是那么漂亮:
FutureMeal chicken = cage.getChicken();
dinner = chicken != null? chicken : getFreeRangeChicken();
有什么方法可以说:
变量var =某些值,如果某个值不为空或其他值 值;
我想我只是在这里谈论语法,在编译代码之后,它可能不会在性能意义上如何编写代码。
由于这是一个非常常见的代码,因此有一个单行代码可以写它。
其他任何语言都有此功能吗?
答案 0 :(得分:52)
与Loki的答案相同,但更短。请记住,较短并不会自动意味着更好。
Optional
注意:JDK的架构师和Optional功能的设计者明确不鼓励使用{{1}}。您正在分配一个新鲜的物体,并且每次都会立即丢弃它。但另一方面它可以很容易阅读。
答案 1 :(得分:44)
Java缺少coalesce运算符,因此具有显式临时值的代码是单个调用的赋值的最佳选择。
您可以将结果变量用作临时变量,如下所示:
dinner = ((dinner = cage.getChicken()) != null) ? dinner : getFreeRangeChicken();
然而,这很难理解。
答案 2 :(得分:11)
使用Java 1.8,您可以使用Optional
public class Main {
public static void main(String[] args) {
//example call, the methods are just dumb templates, note they are static
FutureMeal meal = getChicken().orElse(getFreeRangeChicken());
//another possible way to call this having static methods is
FutureMeal meal = getChicken().orElseGet(Main::getFreeRangeChicken); //method reference
//or if you would use a Instance of Main and call getChicken and getFreeRangeChicken
// as nonstatic methods (assume static would be replaced with public for this)
Main m = new Main();
FutureMeal meal = m.getChicken().orElseGet(m::getFreeRangeChicken); //method reference
//or
FutureMeal meal = m.getChicken().orElse(m.getFreeRangeChicken()); //method call
}
static Optional<FutureMeal> getChicken(){
//instead of returning null, you would return Optional.empty()
//here I just return it to demonstrate
return Optional.empty();
//if you would return a valid object the following comment would be the code
//FutureMeal ret = new FutureMeal(); //your return object
//return Optional.of(ret);
}
static FutureMeal getFreeRangeChicken(){
return new FutureMeal();
}
}
您要为getChicken
实现逻辑,以返回Optional.empty()
而不是null,或Optional.of(myReturnObject)
,其中myReturnObject
是您的chicken
。
然后你可以致电getChicken()
,如果它会返回Optional.empty()
,那么orElse(fallback)
将为你提供任何后备,在你的情况下是第二种方法。
答案 3 :(得分:11)
如果你还没有使用java 1.8并且你不介意使用commons-lang你可以使用org.apache.commons.lang3.ObjectUtils#defaultIfNull
您的代码将是:
onLayout
答案 4 :(得分:1)
public static <T> T defaultWhenNull(@Nullable T object, @NonNull T def) {
return (object == null) ? def : object;
}
示例:
defaultWhenNull(getNullableString(), "");
始终评估default value
(选择为cond ? nonNull() : notEvaluated()
)
这可以通过传递Callable而不是默认值来规避,但会使其更复杂,更不动态(例如,如果性能有问题)。
顺便说一句,使用Optional.orElse()
时会遇到同样的缺点; - )
答案 5 :(得分:0)
dinner = cage.getChicken();
if(dinner == null) dinner = getFreeRangeChicken();
或
if( (dinner = cage.getChicken() ) == null) dinner = getFreeRangeChicken();
答案 6 :(得分:0)
或者在Java8中,您可以根据需要使用 Nullable 或 NotNull 注释。
public class TestingNullable {
@Nullable
public Color nullableMethod(){
//some code here
return color;
}
public void usingNullableMethod(){
// some code
Color color = nullableMethod();
// Introducing assurance of not-null resolves the problem
if (color != null) {
color.toString();
}
}
}
public class TestingNullable {
public void foo(@NotNull Object param){
//some code here
}
...
public void callingNotNullMethod() {
//some code here
// the parameter value according to the explicit contract
// cannot be null
foo(null);
}
}
答案 7 :(得分:0)
自Java 9以来,您拥有Objects#requireNonNullElse,它可以做到:
public static <T> T requireNonNullElse(T obj, T defaultObj) {
return (obj != null) ? obj : requireNonNull(defaultObj, "defaultObj");
}
您的代码应该是
dinner = Objects.requireNonNullElse(cage.getChicken(), getFreeRangeChicken());
这是1行,只调用一次getChicken()
,因此两个要求都得到满足。
请注意,第二个参数也不能为null
;此方法强制返回值不为空。
还要考虑替代方法Objects#requireNonNullElseGet:
public static <T> T requireNonNullElseGet(T obj, Supplier<? extends T> supplier)
如果第一个参数不是null
,它甚至不求值第二个参数,但是确实有创建Supplier
的开销。
答案 8 :(得分:0)
怎么样?
dinner = cage.getChicken();
if(dinner == null) {
dinner = getFreeRangeChicken();
}
此方法删除了else部分。