如何将 java.util.Optional<Something> 映射到 Something?在科特林

How to map java.util.Optional<Something> to Something? in Kotlin

我有一个方法returns java.util.Optional<Something>。 我想使用 Kotlin 的那个方法,我希望我的结果是 Something?,而不是 Optional<Something>

如何在 Kotlin 中以惯用的方式做到这一点?

Optional 上调用 .orElse(null) 确实给了我 Something?,但看起来不太好。如果我写 val msg: Something = optional.orElse(null).,Kotlin 不会抱怨(msg 被声明为 Something,而不是 Something?- 我松开了编译类型检查)。

我使用 Kotlin 1.0.3

用一种方法扩展 java API Optional:

fun <T> Optional<T>.unwrap(): T? = orElse(null)

然后随心所欲地使用它:

val msg: Something? = optional.unwrap()  // the type is enforced

详情见https://kotlinlang.org/docs/reference/extensions.html

如果您使用 com.google.common.base.Optional(Guava 库),那么 orNull() 更好。

例如,

// Java
public class JavaClass
  public Optional<String> getOptionalString() {
    return Optional.absent();
  }
}

// Kotlin
val optionalString = JavaClass().getOptionalString().orNull()

定义orNull()

/**
 * Returns the contained instance if it is present; {@code null} otherwise. If the instance is
 * known to be present, use {@link #get()} instead.
 *
 * <p><b>Comparison to {@code java.util.Optional}:</b> this method is equivalent to Java 8's
 * {@code Optional.orElse(null)}.
 */
@Nullable
public abstract T orNull();

Kotlin 中的可空类型可以具有值或空值,因此您可以将 Optional 转换为可空类型,如下所示:

val str: SomeType? = Optional.of(SomeType_Value).map { it }.orElse(null)

例如,对于某些类型的字符串,我们有

val str: String? = Optional.of("someValue").map { it }.orElse(null)

看起来 java.util.Optional 支持将添加到 Kotlin 1.7 (KT-50484)。然后optional.getOrNull()就可以了

另一种简洁的替代方法是使用 extension properties:

val <T> Optional<T>.value: T?
    get() = orElse(null)

用法:

val message: Something = optional.value ?: defaultMessage