Java - 单个语句中的变量声明、赋值和空值检查

Java - variable Declaration, Assignment and null-check in a single statement

我想知道是否有办法让下面代码的前两行在Java中成为一行行:

Object object;
if ((object = queue.poll()) != null) {
    // do something with object
}

可能不太好看:

Optional.ofNullable(queue.poll())
    .ifPresent(object -> ... do something with object ...);

或者

Optional.ofNullable(queue.poll()).ifPresent(object -> {
    ... do something with object ...;
});

所以你可能对顺子有更好的看法:

Object object = queue.poll();
if (object != null) {
    // do something with object
}

如果您不介意将对象变量的范围限制在大括号中的代码中,那么您可以这样做:

for (Object object; (object = queue.poll()) != null;) {
    // do whatever with object
    break;
}

这与我们在读取文件时所做的典型操作相差无几,如下所示:

for (String line; (line = reader.readLine()) != null;) {
    // do something with line
}

或者按照 rzwitserloot 的建议:

for (Object object = queue.poll; object != null; object = null)   {
 // do something with object
}  

这样它只轮询一次,省略循环体中的中断没有坏处。清空增量中的对象可确保循环在第一次通过后终止。

有一个你无意循环的 for 循环是一种虐待。我会继续使用您开始使用的 multi-line 版本。

但是如果你正在轮询,通常你无论如何都需要一个循环。

条件有点做作。因此,如果不滥用某些东西就很难满足要求,比如用 可选 隐藏 null-check,这不是为了那个目的。

实际上,下面的代码将是最简单和最有表现力的:

Object object = queue.poll()
if (object != null) {
    // do something with object
}

消除单行是有代价的——代码的可读性。

我想到的方法是使用 Stream.ofNullable(),如果提供的参数是 null,它将产生一个 空流 。然后将 stream 转换为 iterator 并在其上调用 forEachRemaining()。此方法需要一个 Supplier,您可以通过放置来自 if 语句的逻辑或单独定义它。

Stream.ofNullable(queue.poll()).iterator().forEachRemaining(System.out::println);

注意Stream接口定义的forEach()方法这里没有为了顺序故意使用与 Stream API documentation in regard to side-effects 的准则保持一致。而是使用了 Iterator,因为它的方法 forEachRemaining().

没有这样的要求

将您的 poll() 变成供应商并假装您正在使用一种鼓励猴子修补的语言

Supplier<Optional<Object>> spout = () -> Optional.ofNullable(queue.poll());
spout.get().ifPresent(o -> System.out.println(o));