RFE: add missing methods to Optional, OptionalInt, OptionalLong and OptionalDouble
Rob Spoor
openjdk at icemanx.nl
Sat Feb 16 12:52:02 UTC 2019
I noticed that, while Stream and its primitive equivalents have multiple
map and flapMap methods, Optional and its primitive equivalents were
missing those. Since these can still be very useful, I wrote a patch to
add the following methods:
* Optional: mapToInt, mapToLong, mapToDouble, flatMapToInt,
flatMapToLong, flatMapToDouble
* OptionalInt: map, mapToObj, mapToLong, mapToDouble, flatMap
* OptionalLong: map, mapToObj, mapToInt, mapToDouble, flatMap
* OptionalDouble: map, mapToObj, mapToInt, mapToLong, flatMap
I did not add any more flatMap methods to OptionalInt, OptionalLong and
OptionalDouble because these also don't exist on IntStream, LongStream
and DoubleStream.
In addition, I also added the missing or method to OptionalInt,
OptionalLong and OptionalDouble based on that of Optional.
My OCA has been processed on 2019-01-22.
Rob
-------------- next part --------------
diff --git a/src/java.base/share/classes/java/util/Optional.java b/src/java.base/share/classes/java/util/Optional.java
--- a/src/java.base/share/classes/java/util/Optional.java
+++ b/src/java.base/share/classes/java/util/Optional.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,9 @@
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
+import java.util.function.ToDoubleFunction;
+import java.util.function.ToIntFunction;
+import java.util.function.ToLongFunction;
import java.util.stream.Stream;
/**
@@ -267,6 +270,69 @@
}
/**
+ * If a value is present, returns an {@code OptionalInt} describing the
+ * result of applying the given mapping function to the value, otherwise
+ * returns an empty {@code OptionalInt}.
+ *
+ * @param mapper the mapping function to apply to a value, if present
+ * @return an {@code OptionalInt} describing the result of applying a
+ * mapping function to the value of this {@code Optional}, if a
+ * value is present, otherwise an empty {@code Optional}
+ * @throws NullPointerException if the mapping function is {@code null}
+ * @since 13
+ */
+ public OptionalInt mapToInt(ToIntFunction<? super T> mapper) {
+ Objects.requireNonNull(mapper);
+ if (!isPresent()) {
+ return OptionalInt.empty();
+ } else {
+ return OptionalInt.of(mapper.applyAsInt(value));
+ }
+ }
+
+ /**
+ * If a value is present, returns an {@code OptionalLong} describing the
+ * result of applying the given mapping function to the value, otherwise
+ * returns an empty {@code OptionalLong}.
+ *
+ * @param mapper the mapping function to apply to a value, if present
+ * @return an {@code OptionalLong} describing the result of applying a
+ * mapping function to the value of this {@code Optional}, if a
+ * value is present, otherwise an empty {@code Optional}
+ * @throws NullPointerException if the mapping function is {@code null}
+ * @since 13
+ */
+ public OptionalLong mapToLong(ToLongFunction<? super T> mapper) {
+ Objects.requireNonNull(mapper);
+ if (!isPresent()) {
+ return OptionalLong.empty();
+ } else {
+ return OptionalLong.of(mapper.applyAsLong(value));
+ }
+ }
+
+ /**
+ * If a value is present, returns an {@code OptionalDouble} describing the
+ * result of applying the given mapping function to the value, otherwise
+ * returns an empty {@code OptionalDouble}.
+ *
+ * @param mapper the mapping function to apply to a value, if present
+ * @return an {@code OptionalDouble} describing the result of applying a
+ * mapping function to the value of this {@code Optional}, if a
+ * value is present, otherwise an empty {@code Optional}
+ * @throws NullPointerException if the mapping function is {@code null}
+ * @since 13
+ */
+ public OptionalDouble mapToDouble(ToDoubleFunction<? super T> mapper) {
+ Objects.requireNonNull(mapper);
+ if (!isPresent()) {
+ return OptionalDouble.empty();
+ } else {
+ return OptionalDouble.of(mapper.applyAsDouble(value));
+ }
+ }
+
+ /**
* If a value is present, returns the result of applying the given
* {@code Optional}-bearing mapping function to the value, otherwise returns
* an empty {@code Optional}.
@@ -297,6 +363,90 @@
}
/**
+ * If a value is present, returns the result of applying the given
+ * {@code OptionalInt}-bearing mapping function to the value, otherwise
+ * returns an empty {@code OptionalInt}.
+ *
+ * <p>This method is similar to {@link #mapToInt(ToIntFunction)}, but the
+ * mapping function is one whose result is already an {@code OptionalInt},
+ * and if invoked, {@code flatMapToInt} does not wrap it within an
+ * additional {@code OptionalInt}.
+ *
+ * @param mapper the mapping function to apply to a value, if present
+ * @return the result of applying an {@code OptionalInt}-bearing mapping
+ * function to the value of this {@code Optional}, if a value is
+ * present, otherwise an empty {@code OptionalInt}
+ * @throws NullPointerException if the mapping function is {@code null} or
+ * returns a {@code null} result
+ * @since 13
+ */
+ public OptionalInt flatMapToInt(Function<? super T, ? extends OptionalInt> mapper) {
+ Objects.requireNonNull(mapper);
+ if (!isPresent()) {
+ return OptionalInt.empty();
+ } else {
+ OptionalInt r = mapper.apply(value);
+ return Objects.requireNonNull(r);
+ }
+ }
+
+ /**
+ * If a value is present, returns the result of applying the given
+ * {@code OptionalLong}-bearing mapping function to the value, otherwise
+ * returns an empty {@code OptionalLong}.
+ *
+ * <p>This method is similar to {@link #mapToLong(ToLongFunction)}, but the
+ * mapping function is one whose result is already an {@code OptionalLong},
+ * and if invoked, {@code flatMapToLong} does not wrap it within an
+ * additional {@code OptionalLong}.
+ *
+ * @param mapper the mapping function to apply to a value, if present
+ * @return the result of applying an {@code OptionalLong}-bearing mapping
+ * function to the value of this {@code Optional}, if a value is
+ * present, otherwise an empty {@code OptionalLong}
+ * @throws NullPointerException if the mapping function is {@code null} or
+ * returns a {@code null} result
+ * @since 13
+ */
+ public OptionalLong flatMapToLong(Function<? super T, ? extends OptionalLong> mapper) {
+ Objects.requireNonNull(mapper);
+ if (!isPresent()) {
+ return OptionalLong.empty();
+ } else {
+ OptionalLong r = mapper.apply(value);
+ return Objects.requireNonNull(r);
+ }
+ }
+
+ /**
+ * If a value is present, returns the result of applying the given
+ * {@code OptionalDouble}-bearing mapping function to the value, otherwise
+ * returns an empty {@code OptionalDouble}.
+ *
+ * <p>This method is similar to {@link #mapToDouble(ToDoubleFunction)}, but
+ * the mapping function is one whose result is already an
+ * {@code OptionalDouble}, and if invoked, {@code flatMapToDouble} does not
+ * wrap it within an additional {@code OptionalDouble}.
+ *
+ * @param mapper the mapping function to apply to a value, if present
+ * @return the result of applying an {@code OptionalDouble}-bearing mapping
+ * function to the value of this {@code Optional}, if a value is
+ * present, otherwise an empty {@code OptionalDouble}
+ * @throws NullPointerException if the mapping function is {@code null} or
+ * returns a {@code null} result
+ * @since 13
+ */
+ public OptionalDouble flatMapToDouble(Function<? super T, ? extends OptionalDouble> mapper) {
+ Objects.requireNonNull(mapper);
+ if (!isPresent()) {
+ return OptionalDouble.empty();
+ } else {
+ OptionalDouble r = mapper.apply(value);
+ return Objects.requireNonNull(r);
+ }
+ }
+
+ /**
* If a value is present, returns an {@code Optional} describing the value,
* otherwise returns an {@code Optional} produced by the supplying function.
*
diff --git a/src/java.base/share/classes/java/util/OptionalDouble.java b/src/java.base/share/classes/java/util/OptionalDouble.java
--- a/src/java.base/share/classes/java/util/OptionalDouble.java
+++ b/src/java.base/share/classes/java/util/OptionalDouble.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,11 @@
package java.util;
import java.util.function.DoubleConsumer;
+import java.util.function.DoubleFunction;
import java.util.function.DoubleSupplier;
+import java.util.function.DoubleToIntFunction;
+import java.util.function.DoubleToLongFunction;
+import java.util.function.DoubleUnaryOperator;
import java.util.function.Supplier;
import java.util.stream.DoubleStream;
@@ -185,6 +189,146 @@
}
/**
+ * If a value is present, returns an {@code OptionalDouble} describing the
+ * result of applying the given mapping function to the value, otherwise
+ * returns an empty {@code OptionalDouble}.
+ *
+ * @param mapper the mapping function to apply to a value, if present
+ * @return an {@code OptionalDouble} describing the result of applying a
+ * mapping function to the value of this {@code OptionalDouble}, if
+ * a value is present, otherwise an empty {@code OptionalDouble}
+ * @throws NullPointerException if the mapping function is {@code null}
+ * @since 13
+ */
+ public OptionalDouble map(DoubleUnaryOperator mapper) {
+ Objects.requireNonNull(mapper);
+ if (!isPresent()) {
+ return OptionalDouble.empty();
+ } else {
+ return OptionalDouble.of(mapper.applyAsDouble(value));
+ }
+ }
+
+ /**
+ * If a value is present, returns an {@code Optional} describing (as if by
+ * {@link Optional#ofNullable}) the result of applying the given mapping
+ * function to the value, otherwise returns an empty {@code Optional}.
+ *
+ * <p>If the mapping function returns a {@code null} result then this method
+ * returns an empty {@code Optional}.
+ *
+ * @param mapper the mapping function to apply to a value, if present
+ * @param <U> The type of the value returned from the mapping function
+ * @return an {@code Optional} describing the result of applying a mapping
+ * function to the value of this {@code OptionalDouble}, if a value
+ * is present, otherwise an empty {@code Optional}
+ * @throws NullPointerException if the mapping function is {@code null}
+ * @since 13
+ */
+ public <U> Optional<U> mapToObj(DoubleFunction<? extends U> mapper) {
+ Objects.requireNonNull(mapper);
+ if (!isPresent()) {
+ return Optional.empty();
+ } else {
+ return Optional.ofNullable(mapper.apply(value));
+ }
+ }
+
+ /**
+ * If a value is present, returns an {@code OptionalInt} describing the
+ * result of applying the given mapping function to the value, otherwise
+ * returns an empty {@code OptionalInt}.
+ *
+ * @param mapper the mapping function to apply to a value, if present
+ * @return an {@code OptionalInt} describing the result of applying a
+ * mapping function to the value of this {@code OptionalDouble}, if
+ * a value is present, otherwise an empty {@code OptionalInt}
+ * @throws NullPointerException if the mapping function is {@code null}
+ * @since 13
+ */
+ public OptionalInt mapToInt(DoubleToIntFunction mapper) {
+ Objects.requireNonNull(mapper);
+ if (!isPresent()) {
+ return OptionalInt.empty();
+ } else {
+ return OptionalInt.of(mapper.applyAsInt(value));
+ }
+ }
+
+ /**
+ * If a value is present, returns an {@code OptionalLong} describing the
+ * result of applying the given mapping function to the value, otherwise
+ * returns an empty {@code OptionalLong}.
+ *
+ * @param mapper the mapping function to apply to a value, if present
+ * @return an {@code OptionalLong} describing the result of applying a
+ * mapping function to the value of this {@code OptionalDouble}, if
+ * a value is present, otherwise an empty {@code OptionalLong}
+ * @throws NullPointerException if the mapping function is {@code null}
+ * @since 13
+ */
+ public OptionalLong mapToLong(DoubleToLongFunction mapper) {
+ Objects.requireNonNull(mapper);
+ if (!isPresent()) {
+ return OptionalLong.empty();
+ } else {
+ return OptionalLong.of(mapper.applyAsLong(value));
+ }
+ }
+
+ /**
+ * If a value is present, returns the result of applying the given
+ * {@code OptionalDouble}-bearing mapping function to the value, otherwise
+ * returns an empty {@code OptionalDouble}.
+ *
+ * <p>This method is similar to {@link #map(DoubleUnaryOperator)}, but the
+ * mapping function is one whose result is already an
+ * {@code OptionalDouble}, and if invoked, {@code flatMap} does not wrap it
+ * within an additional {@code OptionalDouble}.
+ *
+ * @param mapper the mapping function to apply to a value, if present
+ * @return the result of applying an {@code OptionalDouble}-bearing mapping
+ * function to the value of this {@code OptionalDouble}, if a value
+ * is present, otherwise an empty {@code OptionalDouble}
+ * @throws NullPointerException if the mapping function is {@code null} or
+ * returns a {@code null} result
+ * @since 13
+ */
+ public OptionalDouble flatMap(DoubleFunction<? extends OptionalDouble> mapper) {
+ Objects.requireNonNull(mapper);
+ if (!isPresent()) {
+ return OptionalDouble.empty();
+ } else {
+ OptionalDouble r = mapper.apply(value);
+ return Objects.requireNonNull(r);
+ }
+ }
+
+ /**
+ * If a value is present, returns an {@code OptionalDouble} describing the
+ * value, otherwise returns an {@code OptionalDouble} produced by the supplying
+ * function.
+ *
+ * @param supplier the supplying function that produces an
+ * {@code OptionalDouble} to be returned
+ * @return returns an {@code OptionalDouble} describing the value of this
+ * {@code OptionalDouble}, if a value is present, otherwise an
+ * {@code OptionalDouble} produced by the supplying function.
+ * @throws NullPointerException if the supplying function is {@code null} or
+ * produces a {@code null} result
+ * @since 13
+ */
+ public OptionalDouble or(Supplier<? extends OptionalDouble> supplier) {
+ Objects.requireNonNull(supplier);
+ if (isPresent()) {
+ return this;
+ } else {
+ OptionalDouble r = supplier.get();
+ return Objects.requireNonNull(r);
+ }
+ }
+
+ /**
* If a value is present, returns a sequential {@link DoubleStream}
* containing only that value, otherwise returns an empty
* {@code DoubleStream}.
diff --git a/src/java.base/share/classes/java/util/OptionalInt.java b/src/java.base/share/classes/java/util/OptionalInt.java
--- a/src/java.base/share/classes/java/util/OptionalInt.java
+++ b/src/java.base/share/classes/java/util/OptionalInt.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,11 @@
package java.util;
import java.util.function.IntConsumer;
+import java.util.function.IntFunction;
import java.util.function.IntSupplier;
+import java.util.function.IntToDoubleFunction;
+import java.util.function.IntToLongFunction;
+import java.util.function.IntUnaryOperator;
import java.util.function.Supplier;
import java.util.stream.IntStream;
@@ -185,6 +189,146 @@
}
/**
+ * If a value is present, returns an {@code OptionalInt} describing the
+ * result of applying the given mapping function to the value, otherwise
+ * returns an empty {@code OptionalInt}.
+ *
+ * @param mapper the mapping function to apply to a value, if present
+ * @return an {@code OptionalInt} describing the result of applying a
+ * mapping function to the value of this {@code OptionalInt}, if a
+ * value is present, otherwise an empty {@code OptionalInt}
+ * @throws NullPointerException if the mapping function is {@code null}
+ * @since 13
+ */
+ public OptionalInt map(IntUnaryOperator mapper) {
+ Objects.requireNonNull(mapper);
+ if (!isPresent()) {
+ return OptionalInt.empty();
+ } else {
+ return OptionalInt.of(mapper.applyAsInt(value));
+ }
+ }
+
+ /**
+ * If a value is present, returns an {@code Optional} describing (as if by
+ * {@link Optional#ofNullable}) the result of applying the given mapping
+ * function to the value, otherwise returns an empty {@code Optional}.
+ *
+ * <p>If the mapping function returns a {@code null} result then this method
+ * returns an empty {@code Optional}.
+ *
+ * @param mapper the mapping function to apply to a value, if present
+ * @param <U> The type of the value returned from the mapping function
+ * @return an {@code Optional} describing the result of applying a mapping
+ * function to the value of this {@code OptionalInt}, if a value is
+ * present, otherwise an empty {@code Optional}
+ * @throws NullPointerException if the mapping function is {@code null}
+ * @since 13
+ */
+ public <U> Optional<U> mapToObj(IntFunction<? extends U> mapper) {
+ Objects.requireNonNull(mapper);
+ if (!isPresent()) {
+ return Optional.empty();
+ } else {
+ return Optional.ofNullable(mapper.apply(value));
+ }
+ }
+
+ /**
+ * If a value is present, returns an {@code OptionalLong} describing the
+ * result of applying the given mapping function to the value, otherwise
+ * returns an empty {@code OptionalLong}.
+ *
+ * @param mapper the mapping function to apply to a value, if present
+ * @return an {@code OptionalLong} describing the result of applying a
+ * mapping function to the value of this {@code OptionalInt}, if a
+ * value is present, otherwise an empty {@code OptionalLong}
+ * @throws NullPointerException if the mapping function is {@code null}
+ * @since 13
+ */
+ public OptionalLong mapToLong(IntToLongFunction mapper) {
+ Objects.requireNonNull(mapper);
+ if (!isPresent()) {
+ return OptionalLong.empty();
+ } else {
+ return OptionalLong.of(mapper.applyAsLong(value));
+ }
+ }
+
+ /**
+ * If a value is present, returns an {@code OptionalDouble} describing the
+ * result of applying the given mapping function to the value, otherwise
+ * returns an empty {@code OptionalDouble}.
+ *
+ * @param mapper the mapping function to apply to a value, if present
+ * @return an {@code OptionalDouble} describing the result of applying a
+ * mapping function to the value of this {@code OptionalInt}, if a
+ * value is present, otherwise an empty {@code OptionalDouble}
+ * @throws NullPointerException if the mapping function is {@code null}
+ * @since 13
+ */
+ public OptionalDouble mapToDouble(IntToDoubleFunction mapper) {
+ Objects.requireNonNull(mapper);
+ if (!isPresent()) {
+ return OptionalDouble.empty();
+ } else {
+ return OptionalDouble.of(mapper.applyAsDouble(value));
+ }
+ }
+
+ /**
+ * If a value is present, returns the result of applying the given
+ * {@code OptionalInt}-bearing mapping function to the value, otherwise
+ * returns an empty {@code OptionalInt}.
+ *
+ * <p>This method is similar to {@link #map(IntUnaryOperator)}, but the
+ * mapping function is one whose result is already an {@code OptionalInt},
+ * and if invoked, {@code flatMap} does not wrap it within an additional
+ * {@code OptionalInt}.
+ *
+ * @param mapper the mapping function to apply to a value, if present
+ * @return the result of applying an {@code OptionalInt}-bearing mapping
+ * function to the value of this {@code OptionalInt}, if a value is
+ * present, otherwise an empty {@code OptionalInt}
+ * @throws NullPointerException if the mapping function is {@code null} or
+ * returns a {@code null} result
+ * @since 13
+ */
+ public OptionalInt flatMap(IntFunction<? extends OptionalInt> mapper) {
+ Objects.requireNonNull(mapper);
+ if (!isPresent()) {
+ return OptionalInt.empty();
+ } else {
+ OptionalInt r = mapper.apply(value);
+ return Objects.requireNonNull(r);
+ }
+ }
+
+ /**
+ * If a value is present, returns an {@code OptionalInt} describing the
+ * value, otherwise returns an {@code OptionalInt} produced by the supplying
+ * function.
+ *
+ * @param supplier the supplying function that produces an
+ * {@code OptionalInt} to be returned
+ * @return returns an {@code OptionalInt} describing the value of this
+ * {@code OptionalInt}, if a value is present, otherwise an
+ * {@code OptionalInt} produced by the supplying function.
+ * @throws NullPointerException if the supplying function is {@code null} or
+ * produces a {@code null} result
+ * @since 13
+ */
+ public OptionalInt or(Supplier<? extends OptionalInt> supplier) {
+ Objects.requireNonNull(supplier);
+ if (isPresent()) {
+ return this;
+ } else {
+ OptionalInt r = supplier.get();
+ return Objects.requireNonNull(r);
+ }
+ }
+
+ /**
* If a value is present, returns a sequential {@link IntStream} containing
* only that value, otherwise returns an empty {@code IntStream}.
*
diff --git a/src/java.base/share/classes/java/util/OptionalLong.java b/src/java.base/share/classes/java/util/OptionalLong.java
--- a/src/java.base/share/classes/java/util/OptionalLong.java
+++ b/src/java.base/share/classes/java/util/OptionalLong.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,11 @@
package java.util;
import java.util.function.LongConsumer;
+import java.util.function.LongFunction;
import java.util.function.LongSupplier;
+import java.util.function.LongToDoubleFunction;
+import java.util.function.LongToIntFunction;
+import java.util.function.LongUnaryOperator;
import java.util.function.Supplier;
import java.util.stream.LongStream;
@@ -185,6 +189,146 @@
}
/**
+ * If a value is present, returns an {@code OptionalLong} describing the
+ * result of applying the given mapping function to the value, otherwise
+ * returns an empty {@code OptionalLong}.
+ *
+ * @param mapper the mapping function to apply to a value, if present
+ * @return an {@code OptionalLong} describing the result of applying a
+ * mapping function to the value of this {@code OptionalLong}, if a
+ * value is present, otherwise an empty {@code OptionalLong}
+ * @throws NullPointerException if the mapping function is {@code null}
+ * @since 13
+ */
+ public OptionalLong map(LongUnaryOperator mapper) {
+ Objects.requireNonNull(mapper);
+ if (!isPresent()) {
+ return OptionalLong.empty();
+ } else {
+ return OptionalLong.of(mapper.applyAsLong(value));
+ }
+ }
+
+ /**
+ * If a value is present, returns an {@code Optional} describing (as if by
+ * {@link Optional#ofNullable}) the result of applying the given mapping
+ * function to the value, otherwise returns an empty {@code Optional}.
+ *
+ * <p>If the mapping function returns a {@code null} result then this method
+ * returns an empty {@code Optional}.
+ *
+ * @param mapper the mapping function to apply to a value, if present
+ * @param <U> The type of the value returned from the mapping function
+ * @return an {@code Optional} describing the result of applying a mapping
+ * function to the value of this {@code OptionalLong}, if a value
+ * is present, otherwise an empty {@code Optional}
+ * @throws NullPointerException if the mapping function is {@code null}
+ * @since 13
+ */
+ public <U> Optional<U> mapToObj(LongFunction<? extends U> mapper) {
+ Objects.requireNonNull(mapper);
+ if (!isPresent()) {
+ return Optional.empty();
+ } else {
+ return Optional.ofNullable(mapper.apply(value));
+ }
+ }
+
+ /**
+ * If a value is present, returns an {@code OptionalInt} describing the
+ * result of applying the given mapping function to the value, otherwise
+ * returns an empty {@code OptionalInt}.
+ *
+ * @param mapper the mapping function to apply to a value, if present
+ * @return an {@code OptionalInt} describing the result of applying a
+ * mapping function to the value of this {@code OptionalLong}, if a
+ * value is present, otherwise an empty {@code OptionalInt}
+ * @throws NullPointerException if the mapping function is {@code null}
+ * @since 13
+ */
+ public OptionalInt mapToInt(LongToIntFunction mapper) {
+ Objects.requireNonNull(mapper);
+ if (!isPresent()) {
+ return OptionalInt.empty();
+ } else {
+ return OptionalInt.of(mapper.applyAsInt(value));
+ }
+ }
+
+ /**
+ * If a value is present, returns an {@code OptionalDouble} describing the
+ * result of applying the given mapping function to the value, otherwise
+ * returns an empty {@code OptionalDouble}.
+ *
+ * @param mapper the mapping function to apply to a value, if present
+ * @return an {@code OptionalDouble} describing the result of applying a
+ * mapping function to the value of this {@code OptionalLong}, if a
+ * value is present, otherwise an empty {@code OptionalDouble}
+ * @throws NullPointerException if the mapping function is {@code null}
+ * @since 13
+ */
+ public OptionalDouble mapToDouble(LongToDoubleFunction mapper) {
+ Objects.requireNonNull(mapper);
+ if (!isPresent()) {
+ return OptionalDouble.empty();
+ } else {
+ return OptionalDouble.of(mapper.applyAsDouble(value));
+ }
+ }
+
+ /**
+ * If a value is present, returns the result of applying the given
+ * {@code OptionalLong}-bearing mapping function to the value, otherwise
+ * returns an empty {@code OptionalLong}.
+ *
+ * <p>This method is similar to {@link #map(LongUnaryOperator)}, but the
+ * mapping function is one whose result is already an {@code OptionalLong},
+ * and if invoked, {@code flatMap} does not wrap it within an additional
+ * {@code OptionalLong}.
+ *
+ * @param mapper the mapping function to apply to a value, if present
+ * @return the result of applying an {@code OptionalLong}-bearing mapping
+ * function to the value of this {@code OptionalLong}, if a value is
+ * present, otherwise an empty {@code OptionalLong}
+ * @throws NullPointerException if the mapping function is {@code null} or
+ * returns a {@code null} result
+ * @since 13
+ */
+ public OptionalLong flatMap(LongFunction<? extends OptionalLong> mapper) {
+ Objects.requireNonNull(mapper);
+ if (!isPresent()) {
+ return OptionalLong.empty();
+ } else {
+ OptionalLong r = mapper.apply(value);
+ return Objects.requireNonNull(r);
+ }
+ }
+
+ /**
+ * If a value is present, returns an {@code OptionalLong} describing the
+ * value, otherwise returns an {@code OptionalLong} produced by the
+ * supplying function.
+ *
+ * @param supplier the supplying function that produces an
+ * {@code OptionalLong} to be returned
+ * @return returns an {@code OptionalLong} describing the value of this
+ * {@code OptionalLong}, if a value is present, otherwise an
+ * {@code OptionalLong} produced by the supplying function.
+ * @throws NullPointerException if the supplying function is {@code null} or
+ * produces a {@code null} result
+ * @since 13
+ */
+ public OptionalLong or(Supplier<? extends OptionalLong> supplier) {
+ Objects.requireNonNull(supplier);
+ if (isPresent()) {
+ return this;
+ } else {
+ OptionalLong r = supplier.get();
+ return Objects.requireNonNull(r);
+ }
+ }
+
+ /**
* If a value is present, returns a sequential {@link LongStream} containing
* only that value, otherwise returns an empty {@code LongStream}.
*
diff --git a/test/jdk/java/util/Optional/Basic.java b/test/jdk/java/util/Optional/Basic.java
--- a/test/jdk/java/util/Optional/Basic.java
+++ b/test/jdk/java/util/Optional/Basic.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,9 @@
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;
+import java.util.OptionalDouble;
+import java.util.OptionalInt;
+import java.util.OptionalLong;
import java.util.concurrent.atomic.AtomicBoolean;
import static java.util.stream.Collectors.toList;
@@ -44,7 +47,7 @@
/**
* Checks a block of assertions over an empty Optional.
*/
- void checkEmpty(Optional<String> empty) {
+ static void checkEmpty(Optional<String> empty) {
assertTrue(empty.equals(Optional.empty()));
assertTrue(Optional.empty().equals(empty));
assertFalse(empty.equals(Optional.of("unexpected")));
@@ -78,7 +81,7 @@
* Checks a block of assertions over an Optional that is expected to
* have a particular value present.
*/
- void checkPresent(Optional<String> opt, String expected) {
+ static void checkPresent(Optional<String> opt, String expected) {
assertFalse(opt.equals(Optional.empty()));
assertFalse(Optional.empty().equals(opt));
assertTrue(opt.equals(Optional.of(expected)));
@@ -161,6 +164,36 @@
}
@Test(groups = "unit")
+ public void testMapToIntEmpty() {
+ BasicInt.checkEmpty(Optional.empty().mapToInt(s -> { fail(); return 0; }));
+ }
+
+ @Test(groups = "unit")
+ public void testMapToIntPresent() {
+ BasicInt.checkPresent(Optional.of("xyzzy").mapToInt(s -> BasicInt.INTVAL), BasicInt.INTVAL);
+ }
+
+ @Test(groups = "unit")
+ public void testMapToLongEmpty() {
+ BasicLong.checkEmpty(Optional.empty().mapToLong(s -> { fail(); return 0L; }));
+ }
+
+ @Test(groups = "unit")
+ public void testMapToLongPresent() {
+ BasicLong.checkPresent(Optional.of("xyzzy").mapToLong(s -> BasicLong.LONGVAL), BasicLong.LONGVAL);
+ }
+
+ @Test(groups = "unit")
+ public void testMapToDoubleEmpty() {
+ BasicDouble.checkEmpty(Optional.empty().mapToDouble(s -> { fail(); return 0D; }));
+ }
+
+ @Test(groups = "unit")
+ public void testMapToDoublePresent() {
+ BasicDouble.checkPresent(Optional.of("xyzzy").mapToDouble(s -> BasicDouble.DOUBLEVAL), BasicDouble.DOUBLEVAL);
+ }
+
+ @Test(groups = "unit")
public void testFlatMapEmpty() {
checkEmpty(Optional.empty().flatMap(s -> { fail(); return Optional.of(""); }));
}
@@ -179,6 +212,60 @@
}
@Test(groups = "unit")
+ public void testFlatMapToIntEmpty() {
+ BasicInt.checkEmpty(Optional.empty().flatMapToInt(s -> { fail(); return OptionalInt.of(0); }));
+ }
+
+ @Test(groups = "unit")
+ public void testFlatMapToIntPresentReturnEmpty() {
+ BasicInt.checkEmpty(Optional.of("xyzzy")
+ .flatMapToInt(s -> { assertEquals(s, "xyzzy"); return OptionalInt.empty(); }));
+ }
+
+ @Test(groups = "unit")
+ public void testFlatMapToIntPresentReturnPresent() {
+ BasicInt.checkPresent(Optional.of("xyzzy")
+ .flatMapToInt(s -> { assertEquals(s, "xyzzy"); return OptionalInt.of(BasicInt.INTVAL); }),
+ BasicInt.INTVAL);
+ }
+
+ @Test(groups = "unit")
+ public void testFlatMapToLongEmpty() {
+ BasicLong.checkEmpty(Optional.empty().flatMapToLong(s -> { fail(); return OptionalLong.of(0L); }));
+ }
+
+ @Test(groups = "unit")
+ public void testFlatMapToLongPresentReturnEmpty() {
+ BasicLong.checkEmpty(Optional.of("xyzzy")
+ .flatMapToLong(s -> { assertEquals(s, "xyzzy"); return OptionalLong.empty(); }));
+ }
+
+ @Test(groups = "unit")
+ public void testFlatMapToLongPresentReturnPresent() {
+ BasicLong.checkPresent(Optional.of("xyzzy")
+ .flatMapToLong(s -> { assertEquals(s, "xyzzy"); return OptionalLong.of(BasicLong.LONGVAL); }),
+ BasicLong.LONGVAL);
+ }
+
+ @Test(groups = "unit")
+ public void testFlatMapToDoubleEmpty() {
+ BasicDouble.checkEmpty(Optional.empty().flatMapToDouble(s -> { fail(); return OptionalDouble.of(0D); }));
+ }
+
+ @Test(groups = "unit")
+ public void testFlatMapToDoublePresentReturnEmpty() {
+ BasicDouble.checkEmpty(Optional.of("xyzzy")
+ .flatMapToDouble(s -> { assertEquals(s, "xyzzy"); return OptionalDouble.empty(); }));
+ }
+
+ @Test(groups = "unit")
+ public void testFlatMapToDoublePresentReturnPresent() {
+ BasicDouble.checkPresent(Optional.of("xyzzy")
+ .flatMapToDouble(s -> { assertEquals(s, "xyzzy"); return OptionalDouble.of(BasicDouble.DOUBLEVAL); }),
+ BasicDouble.DOUBLEVAL);
+ }
+
+ @Test(groups = "unit")
public void testOrEmptyEmpty() {
checkEmpty(Optional.<String>empty().or(() -> Optional.empty()));
}
diff --git a/test/jdk/java/util/Optional/BasicDouble.java b/test/jdk/java/util/Optional/BasicDouble.java
--- a/test/jdk/java/util/Optional/BasicDouble.java
+++ b/test/jdk/java/util/Optional/BasicDouble.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,7 +43,7 @@
/**
* Checks a block of assertions over an empty OptionalDouble.
*/
- void checkEmpty(OptionalDouble empty) {
+ static void checkEmpty(OptionalDouble empty) {
assertTrue(empty.equals(OptionalDouble.empty()));
assertTrue(OptionalDouble.empty().equals(empty));
assertFalse(empty.equals(OptionalDouble.of(UNEXPECTED)));
@@ -77,7 +77,7 @@
* Checks a block of assertions over an OptionalDouble that is expected to
* have a particular value present.
*/
- void checkPresent(OptionalDouble opt, double expected) {
+ static void checkPresent(OptionalDouble opt, double expected) {
assertFalse(opt.equals(OptionalDouble.empty()));
assertFalse(OptionalDouble.empty().equals(opt));
assertTrue(opt.equals(OptionalDouble.of(expected)));
@@ -128,4 +128,77 @@
public void testStreamPresent() {
assertEquals(OptionalDouble.of(DOUBLEVAL).stream().toArray(), new double[] { DOUBLEVAL });
}
+
+ @Test(groups = "unit")
+ public void testMapEmpty() {
+ checkEmpty(OptionalDouble.empty().map(s -> { fail(); return 0D; }));
+ }
+
+ @Test(groups = "unit")
+ public void testMapPresent() {
+ checkPresent(OptionalDouble.of(DOUBLEVAL).map(d -> d * 2), 2 * DOUBLEVAL);
+ }
+
+ @Test(groups = "unit")
+ public void testMapToObjEmpty() {
+ Basic.checkEmpty(OptionalDouble.empty().mapToObj(s -> { fail(); return ""; }));
+ }
+
+ @Test(groups = "unit")
+ public void testMapToObjPresent() {
+ Basic.checkPresent(OptionalDouble.of(DOUBLEVAL).mapToObj(d -> "plugh"), "plugh");
+ }
+
+ @Test(groups = "unit")
+ public void testMapToIntEmpty() {
+ BasicInt.checkEmpty(OptionalDouble.empty().mapToInt(s -> { fail(); return 0; }));
+ }
+
+ @Test(groups = "unit")
+ public void testMapToIntPresent() {
+ BasicInt.checkPresent(OptionalDouble.of(DOUBLEVAL).mapToInt(d -> BasicInt.INTVAL), BasicInt.INTVAL);
+ }
+
+ @Test(groups = "unit")
+ public void testMapToLongEmpty() {
+ BasicLong.checkEmpty(OptionalDouble.empty().mapToLong(s -> { fail(); return 0L; }));
+ }
+
+ @Test(groups = "unit")
+ public void testMapToLongPresent() {
+ BasicLong.checkPresent(OptionalDouble.of(DOUBLEVAL).mapToLong(d -> BasicLong.LONGVAL), BasicLong.LONGVAL);
+ }
+
+ @Test(groups = "unit")
+ public void testFlatMapEmpty() {
+ checkEmpty(OptionalDouble.empty().flatMap(s -> { fail(); return OptionalDouble.of(0D); }));
+ }
+
+ @Test(groups = "unit")
+ public void testFlatMapPresentReturnEmpty() {
+ checkEmpty(OptionalDouble.of(DOUBLEVAL)
+ .flatMap(d -> { assertEquals(d, DOUBLEVAL); return OptionalDouble.empty(); }));
+ }
+
+ @Test(groups = "unit")
+ public void testFlatMapPresentReturnPresent() {
+ checkPresent(OptionalDouble.of(DOUBLEVAL)
+ .flatMap(d -> { assertEquals(d, DOUBLEVAL); return OptionalDouble.of(Math.E); }),
+ Math.E);
+ }
+
+ @Test(groups = "unit")
+ public void testOrEmptyEmpty() {
+ checkEmpty(OptionalDouble.empty().or(() -> OptionalDouble.empty()));
+ }
+
+ @Test(groups = "unit")
+ public void testOrEmptyPresent() {
+ checkPresent(OptionalDouble.empty().or(() -> OptionalDouble.of(DOUBLEVAL)), DOUBLEVAL);
+ }
+
+ @Test(groups = "unit")
+ public void testOrPresentDontCare() {
+ checkPresent(OptionalDouble.of(DOUBLEVAL).or(() -> { fail(); return OptionalDouble.of(0D); }), DOUBLEVAL);
+ }
}
diff --git a/test/jdk/java/util/Optional/BasicInt.java b/test/jdk/java/util/Optional/BasicInt.java
--- a/test/jdk/java/util/Optional/BasicInt.java
+++ b/test/jdk/java/util/Optional/BasicInt.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -44,7 +44,7 @@
/**
* Checks a block of assertions over an empty OptionalInt.
*/
- void checkEmpty(OptionalInt empty) {
+ static void checkEmpty(OptionalInt empty) {
assertTrue(empty.equals(OptionalInt.empty()));
assertTrue(OptionalInt.empty().equals(empty));
assertFalse(empty.equals(OptionalInt.of(UNEXPECTED)));
@@ -78,7 +78,7 @@
* Checks a block of assertions over an OptionalInt that is expected to
* have a particular value present.
*/
- void checkPresent(OptionalInt opt, int expected) {
+ static void checkPresent(OptionalInt opt, int expected) {
assertFalse(opt.equals(OptionalInt.empty()));
assertFalse(OptionalInt.empty().equals(opt));
assertTrue(opt.equals(OptionalInt.of(expected)));
@@ -129,4 +129,77 @@
public void testStreamPresent() {
assertEquals(OptionalInt.of(INTVAL).stream().toArray(), new int[] { INTVAL });
}
+
+ @Test(groups = "unit")
+ public void testMapEmpty() {
+ checkEmpty(OptionalInt.empty().map(s -> { fail(); return 0; }));
+ }
+
+ @Test(groups = "unit")
+ public void testMapPresent() {
+ checkPresent(OptionalInt.of(INTVAL).map(i -> i * 2), 2 * INTVAL);
+ }
+
+ @Test(groups = "unit")
+ public void testMapToObjEmpty() {
+ Basic.checkEmpty(OptionalInt.empty().mapToObj(s -> { fail(); return ""; }));
+ }
+
+ @Test(groups = "unit")
+ public void testMapToObjPresent() {
+ Basic.checkPresent(OptionalInt.of(INTVAL).mapToObj(i -> "plugh"), "plugh");
+ }
+
+ @Test(groups = "unit")
+ public void testMapToLongEmpty() {
+ BasicLong.checkEmpty(OptionalInt.empty().mapToLong(s -> { fail(); return 0L; }));
+ }
+
+ @Test(groups = "unit")
+ public void testMapToLongPresent() {
+ BasicLong.checkPresent(OptionalInt.of(INTVAL).mapToLong(i -> BasicLong.LONGVAL), BasicLong.LONGVAL);
+ }
+
+ @Test(groups = "unit")
+ public void testMapToDoubleEmpty() {
+ BasicDouble.checkEmpty(OptionalInt.empty().mapToDouble(s -> { fail(); return 0D; }));
+ }
+
+ @Test(groups = "unit")
+ public void testMapToDoublePresent() {
+ BasicDouble.checkPresent(OptionalInt.of(INTVAL).mapToDouble(i -> BasicDouble.DOUBLEVAL), BasicDouble.DOUBLEVAL);
+ }
+
+ @Test(groups = "unit")
+ public void testFlatMapEmpty() {
+ checkEmpty(OptionalInt.empty().flatMap(s -> { fail(); return OptionalInt.of(0); }));
+ }
+
+ @Test(groups = "unit")
+ public void testFlatMapPresentReturnEmpty() {
+ checkEmpty(OptionalInt.of(INTVAL)
+ .flatMap(i -> { assertEquals(i, INTVAL); return OptionalInt.empty(); }));
+ }
+
+ @Test(groups = "unit")
+ public void testFlatMapPresentReturnPresent() {
+ checkPresent(OptionalInt.of(INTVAL)
+ .flatMap(i -> { assertEquals(i, INTVAL); return OptionalInt.of(2 * INTVAL); }),
+ 2 * INTVAL);
+ }
+
+ @Test(groups = "unit")
+ public void testOrEmptyEmpty() {
+ checkEmpty(OptionalInt.empty().or(() -> OptionalInt.empty()));
+ }
+
+ @Test(groups = "unit")
+ public void testOrEmptyPresent() {
+ checkPresent(OptionalInt.empty().or(() -> OptionalInt.of(INTVAL)), INTVAL);
+ }
+
+ @Test(groups = "unit")
+ public void testOrPresentDontCare() {
+ checkPresent(OptionalInt.of(INTVAL).or(() -> { fail(); return OptionalInt.of(0); }), INTVAL);
+ }
}
diff --git a/test/jdk/java/util/Optional/BasicLong.java b/test/jdk/java/util/Optional/BasicLong.java
--- a/test/jdk/java/util/Optional/BasicLong.java
+++ b/test/jdk/java/util/Optional/BasicLong.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,7 +43,7 @@
/**
* Checks a block of assertions over an empty OptionalLong.
*/
- void checkEmpty(OptionalLong empty) {
+ static void checkEmpty(OptionalLong empty) {
assertTrue(empty.equals(OptionalLong.empty()));
assertTrue(OptionalLong.empty().equals(empty));
assertFalse(empty.equals(OptionalLong.of(UNEXPECTED)));
@@ -77,7 +77,7 @@
* Checks a block of assertions over an OptionalLong that is expected to
* have a particular value present.
*/
- void checkPresent(OptionalLong opt, long expected) {
+ static void checkPresent(OptionalLong opt, long expected) {
assertFalse(opt.equals(OptionalLong.empty()));
assertFalse(OptionalLong.empty().equals(opt));
assertTrue(opt.equals(OptionalLong.of(expected)));
@@ -128,4 +128,77 @@
public void testStreamPresent() {
assertEquals(OptionalLong.of(LONGVAL).stream().toArray(), new long[] { LONGVAL });
}
+
+ @Test(groups = "unit")
+ public void testMapEmpty() {
+ checkEmpty(OptionalLong.empty().map(s -> { fail(); return 0L; }));
+ }
+
+ @Test(groups = "unit")
+ public void testMapPresent() {
+ checkPresent(OptionalLong.of(LONGVAL).map(l -> l * 2), 2 * LONGVAL);
+ }
+
+ @Test(groups = "unit")
+ public void testMapToObjEmpty() {
+ Basic.checkEmpty(OptionalLong.empty().mapToObj(s -> { fail(); return ""; }));
+ }
+
+ @Test(groups = "unit")
+ public void testMapToObjPresent() {
+ Basic.checkPresent(OptionalLong.of(LONGVAL).mapToObj(l -> "plugh"), "plugh");
+ }
+
+ @Test(groups = "unit")
+ public void testMapToIntEmpty() {
+ BasicInt.checkEmpty(OptionalLong.empty().mapToInt(s -> { fail(); return 0; }));
+ }
+
+ @Test(groups = "unit")
+ public void testMapToIntPresent() {
+ BasicInt.checkPresent(OptionalLong.of(LONGVAL).mapToInt(l -> BasicInt.INTVAL), BasicInt.INTVAL);
+ }
+
+ @Test(groups = "unit")
+ public void testMapToDoubleEmpty() {
+ BasicDouble.checkEmpty(OptionalLong.empty().mapToDouble(s -> { fail(); return 0D; }));
+ }
+
+ @Test(groups = "unit")
+ public void testMapToDoublePresent() {
+ BasicDouble.checkPresent(OptionalLong.of(LONGVAL).mapToDouble(l -> BasicDouble.DOUBLEVAL), BasicDouble.DOUBLEVAL);
+ }
+
+ @Test(groups = "unit")
+ public void testFlatMapEmpty() {
+ checkEmpty(OptionalLong.empty().flatMap(s -> { fail(); return OptionalLong.of(0L); }));
+ }
+
+ @Test(groups = "unit")
+ public void testFlatMapPresentReturnEmpty() {
+ checkEmpty(OptionalLong.of(LONGVAL)
+ .flatMap(d -> { assertEquals(d, LONGVAL); return OptionalLong.empty(); }));
+ }
+
+ @Test(groups = "unit")
+ public void testFlatMapPresentReturnPresent() {
+ checkPresent(OptionalLong.of(LONGVAL)
+ .flatMap(d -> { assertEquals(d, LONGVAL); return OptionalLong.of(2 * LONGVAL); }),
+ 2 * LONGVAL);
+ }
+
+ @Test(groups = "unit")
+ public void testOrEmptyEmpty() {
+ checkEmpty(OptionalLong.empty().or(() -> OptionalLong.empty()));
+ }
+
+ @Test(groups = "unit")
+ public void testOrEmptyPresent() {
+ checkPresent(OptionalLong.empty().or(() -> OptionalLong.of(LONGVAL)), LONGVAL);
+ }
+
+ @Test(groups = "unit")
+ public void testOrPresentDontCare() {
+ checkPresent(OptionalLong.of(LONGVAL).or(() -> { fail(); return OptionalLong.of(0L); }), LONGVAL);
+ }
}
More information about the core-libs-dev
mailing list