Bartosz Bilicki
Bartosz Bilicki

Reputation: 13235

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

I have a method that returns java.util.Optional<Something>. I want to use that method from Kotlin, and I want my result to be Something?, not Optional<Something>

How to do that in Kotlin, in idiomatic way?

calling .orElse(null) on Optional gives me Something? indeed, but it does not look good. Kotlin does not complain if I write val msg: Something = optional.orElse(null). (msg is declared as Something, not Something?- I loose compile-type check).

I use Kotlin 1.0.3

Upvotes: 31

Views: 24822

Answers (4)

bjmi
bjmi

Reputation: 603

It looks like java.util.Optional support will be added to Kotlin 1.7 (KT-50484). Then optional.getOrNull() will do it.

Another concise alternative would use extension properties:

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

Usages:

val msg: Something? = optional.value
val msg: Something  = optional.value ?: defaultMessage

Upvotes: 5

Mr.Q
Mr.Q

Reputation: 4524

A nullable type in Kotlin can have value or null so you can convert and Optional to nullable Type as follows:

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

For example for SomeType of String we have

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

Upvotes: 1

Jake Lin
Jake Lin

Reputation: 11494

If you use com.google.common.base.Optional (Guava library) then orNull() is better.

For example,

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

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

The definition of 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();

Upvotes: 7

voddan
voddan

Reputation: 33769

Extend the java API with a method to unwrap Optional:

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

Then use it like you wanted:

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

See https://kotlinlang.org/docs/reference/extensions.html for details.

Upvotes: 54

Related Questions