changeset 48328:7acf5700d542

8140281: add no-arg Optional.orElseThrow() as preferred alternative to get() Reviewed-by: alanb, bpb, forax, darcy
author smarks
date Wed, 13 Dec 2017 18:47:20 -0800
parents d2a837cf9ff1
children 984c4b99afc9
files src/java.base/share/classes/java/util/Optional.java src/java.base/share/classes/java/util/OptionalDouble.java src/java.base/share/classes/java/util/OptionalInt.java src/java.base/share/classes/java/util/OptionalLong.java test/jdk/java/util/Optional/Basic.java test/jdk/java/util/Optional/BasicDouble.java test/jdk/java/util/Optional/BasicInt.java test/jdk/java/util/Optional/BasicLong.java
diffstat 8 files changed, 118 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/util/Optional.java	Wed Dec 13 17:28:24 2017 -0800
+++ b/src/java.base/share/classes/java/util/Optional.java	Wed Dec 13 18:47:20 2017 -0800
@@ -32,8 +32,9 @@
 
 /**
  * A container object which may or may not contain a non-{@code null} value.
- * If a value is present, {@code isPresent()} returns {@code true} and
- * {@code get()} returns the value.
+ * If a value is present, {@code isPresent()} returns {@code true}. If no
+ * value is present, the object is considered <i>empty</i> and
+ * {@code isPresent()} returns {@code false}.
  *
  * <p>Additional methods that depend on the presence or absence of a contained
  * value are provided, such as {@link #orElse(Object) orElse()}
@@ -137,14 +138,10 @@
      * {@code NoSuchElementException}.
      *
      * @apiNote
-     * The methods {@link #orElse(Object) orElse} and
-     * {@link #orElseGet(Supplier) orElseGet}
-     * are generally preferable to this method, as they return a substitute
-     * value if the value is absent, instead of throwing an exception.
+     * The preferred alternative to this method is {@link #orElseThrow()}.
      *
      * @return the non-{@code null} value described by this {@code Optional}
      * @throws NoSuchElementException if no value is present
-     * @see Optional#isPresent()
      */
     public T get() {
         if (value == null) {
@@ -362,6 +359,21 @@
     }
 
     /**
+     * If a value is present, returns the value, otherwise throws
+     * {@code NoSuchElementException}.
+     *
+     * @return the non-{@code null} value described by this {@code Optional}
+     * @throws NoSuchElementException if no value is present
+     * @since 10
+     */
+    public T orElseThrow() {
+        if (value == null) {
+            throw new NoSuchElementException("No value present");
+        }
+        return value;
+    }
+
+    /**
      * If a value is present, returns the value, otherwise throws an exception
      * produced by the exception supplying function.
      *
--- a/src/java.base/share/classes/java/util/OptionalDouble.java	Wed Dec 13 17:28:24 2017 -0800
+++ b/src/java.base/share/classes/java/util/OptionalDouble.java	Wed Dec 13 18:47:20 2017 -0800
@@ -30,9 +30,10 @@
 import java.util.stream.DoubleStream;
 
 /**
- * A container object which may or may not contain a {@code double} value.  If a
- * value is present, {@code isPresent()} returns {@code true} and
- * {@code getAsDouble()} returns the value.
+ * A container object which may or may not contain a {@code double} value.
+ * If a value is present, {@code isPresent()} returns {@code true}. If no
+ * value is present, the object is considered <i>empty</i> and
+ * {@code isPresent()} returns {@code false}.
  *
  * <p>Additional methods that depend on the presence or absence of a contained
  * value are provided, such as {@link #orElse(double) orElse()}
@@ -117,14 +118,10 @@
      * {@code NoSuchElementException}.
      *
      * @apiNote
-     * The methods {@link #orElse(double) orElse} and
-     * {@link #orElseGet(DoubleSupplier) orElseGet}
-     * are generally preferable to this method, as they return a substitute
-     * value if the value is absent, instead of throwing an exception.
+     * The preferred alternative to this method is {@link #orElseThrow()}.
      *
      * @return the value described by this {@code OptionalDouble}
      * @throws NoSuchElementException if no value is present
-     * @see OptionalDouble#isPresent()
      */
     public double getAsDouble() {
         if (!isPresent) {
@@ -226,6 +223,21 @@
     }
 
     /**
+     * If a value is present, returns the value, otherwise throws
+     * {@code NoSuchElementException}.
+     *
+     * @return the value described by this {@code OptionalDouble}
+     * @throws NoSuchElementException if no value is present
+     * @since 10
+     */
+    public double orElseThrow() {
+        if (!isPresent) {
+            throw new NoSuchElementException("No value present");
+        }
+        return value;
+    }
+
+    /**
      * If a value is present, returns the value, otherwise throws an exception
      * produced by the exception supplying function.
      *
--- a/src/java.base/share/classes/java/util/OptionalInt.java	Wed Dec 13 17:28:24 2017 -0800
+++ b/src/java.base/share/classes/java/util/OptionalInt.java	Wed Dec 13 18:47:20 2017 -0800
@@ -30,9 +30,10 @@
 import java.util.stream.IntStream;
 
 /**
- * A container object which may or may not contain an {@code int} value.  If a
- * value is present, {@code isPresent()} returns {@code true} and
- * {@code getAsInt()} returns the value.
+ * A container object which may or may not contain an {@code int} value.
+ * If a value is present, {@code isPresent()} returns {@code true}. If no
+ * value is present, the object is considered <i>empty</i> and
+ * {@code isPresent()} returns {@code false}.
  *
  * <p>Additional methods that depend on the presence or absence of a contained
  * value are provided, such as {@link #orElse(int) orElse()}
@@ -117,14 +118,10 @@
      * {@code NoSuchElementException}.
      *
      * @apiNote
-     * The methods {@link #orElse(int) orElse} and
-     * {@link #orElseGet(IntSupplier) orElseGet}
-     * are generally preferable to this method, as they return a substitute
-     * value if the value is absent, instead of throwing an exception.
+     * The preferred alternative to this method is {@link #orElseThrow()}.
      *
      * @return the value described by this {@code OptionalInt}
      * @throws NoSuchElementException if no value is present
-     * @see OptionalInt#isPresent()
      */
     public int getAsInt() {
         if (!isPresent) {
@@ -225,6 +222,21 @@
     }
 
     /**
+     * If a value is present, returns the value, otherwise throws
+     * {@code NoSuchElementException}.
+     *
+     * @return the value described by this {@code OptionalInt}
+     * @throws NoSuchElementException if no value is present
+     * @since 10
+     */
+    public int orElseThrow() {
+        if (!isPresent) {
+            throw new NoSuchElementException("No value present");
+        }
+        return value;
+    }
+
+    /**
      * If a value is present, returns the value, otherwise throws an exception
      * produced by the exception supplying function.
      *
--- a/src/java.base/share/classes/java/util/OptionalLong.java	Wed Dec 13 17:28:24 2017 -0800
+++ b/src/java.base/share/classes/java/util/OptionalLong.java	Wed Dec 13 18:47:20 2017 -0800
@@ -30,9 +30,10 @@
 import java.util.stream.LongStream;
 
 /**
- * A container object which may or may not contain a {@code long} value.  If a
- * value is present, {@code isPresent()} returns {@code true} and
- * {@code getAsLong()} returns the value.
+ * A container object which may or may not contain a {@code long} value.
+ * If a value is present, {@code isPresent()} returns {@code true}. If no
+ * value is present, the object is considered <i>empty</i> and
+ * {@code isPresent()} returns {@code false}.
  *
  * <p>Additional methods that depend on the presence or absence of a contained
  * value are provided, such as {@link #orElse(long) orElse()}
@@ -117,14 +118,10 @@
      * {@code NoSuchElementException}.
      *
      * @apiNote
-     * The methods {@link #orElse(long) orElse} and
-     * {@link #orElseGet(LongSupplier) orElseGet}
-     * are generally preferable to this method, as they return a substitute
-     * value if the value is absent, instead of throwing an exception.
+     * The preferred alternative to this method is {@link #orElseThrow()}.
      *
      * @return the value described by this {@code OptionalLong}
      * @throws NoSuchElementException if no value is present
-     * @see OptionalLong#isPresent()
      */
     public long getAsLong() {
         if (!isPresent) {
@@ -225,6 +222,21 @@
     }
 
     /**
+     * If a value is present, returns the value, otherwise throws
+     * {@code NoSuchElementException}.
+     *
+     * @return the value described by this {@code OptionalLong}
+     * @throws NoSuchElementException if no value is present
+     * @since 10
+     */
+    public long orElseThrow() {
+        if (!isPresent) {
+            throw new NoSuchElementException("No value present");
+        }
+        return value;
+    }
+
+    /**
      * If a value is present, returns the value, otherwise throws an exception
      * produced by the exception supplying function.
      *
--- a/test/jdk/java/util/Optional/Basic.java	Wed Dec 13 17:28:24 2017 -0800
+++ b/test/jdk/java/util/Optional/Basic.java	Wed Dec 13 18:47:20 2017 -0800
@@ -132,6 +132,13 @@
         Boolean got = empty.orElseThrow(ObscureException::new);
     }
 
+    @Test(expectedExceptions=NoSuchElementException.class)
+    public void testEmptyOrElseThrowNoArg() throws Exception {
+        Optional<Boolean> empty = Optional.empty();
+
+        Boolean got = empty.orElseThrow();
+    }
+
     @Test(groups = "unit")
     public void testPresent() {
         Optional<Boolean> empty = Optional.empty();
@@ -147,6 +154,7 @@
         assertTrue(!present.toString().equals(presentEmptyString.toString()));
         assertTrue(-1 != present.toString().indexOf(Boolean.TRUE.toString()));
         assertSame(Boolean.TRUE, present.get());
+        assertSame(Boolean.TRUE, present.orElseThrow());
 
         AtomicBoolean presentCheck = new AtomicBoolean();
         present.ifPresent(v -> presentCheck.set(true));
@@ -191,6 +199,7 @@
         instance = Optional.ofNullable("Duke");
         assertTrue(instance.isPresent());
         assertEquals(instance.get(), "Duke");
+        assertEquals(instance.orElseThrow(), "Duke");
     }
 
     @Test(groups = "unit")
@@ -214,11 +223,13 @@
         result = duke.filter(s -> s.startsWith("D"));
         assertTrue(result.isPresent());
         assertEquals(result.get(), "Duke");
+        assertEquals(result.orElseThrow(), "Duke");
 
         Optional<String> emptyString = Optional.of("");
         result = emptyString.filter(String::isEmpty);
         assertTrue(result.isPresent());
         assertEquals(result.get(), "");
+        assertEquals(result.orElseThrow(), "");
     }
 
     @Test(groups = "unit")
@@ -287,6 +298,7 @@
         l = duke.flatMap(s -> Optional.of(s.length()));
         assertTrue(l.isPresent());
         assertEquals(l.get().intValue(), 4);
+        assertEquals(l.orElseThrow().intValue(), 4);
 
         // Verify same instance
         l = duke.flatMap(s -> fixture);
--- a/test/jdk/java/util/Optional/BasicDouble.java	Wed Dec 13 17:28:24 2017 -0800
+++ b/test/jdk/java/util/Optional/BasicDouble.java	Wed Dec 13 18:47:20 2017 -0800
@@ -124,6 +124,13 @@
         double got = empty.orElseThrow(ObscureException::new);
     }
 
+    @Test(expectedExceptions=NoSuchElementException.class)
+    public void testEmptyOrElseThrowNoArg() throws Exception {
+        OptionalDouble empty = OptionalDouble.empty();
+
+        double got = empty.orElseThrow();
+    }
+
     @Test(groups = "unit")
     public void testPresent() {
         OptionalDouble empty = OptionalDouble.empty();
@@ -137,7 +144,9 @@
         assertTrue(Double.hashCode(1.0) == present.hashCode());
         assertFalse(present.toString().isEmpty());
         assertTrue(-1 != present.toString().indexOf(Double.toString(present.getAsDouble()).toString()));
+        assertTrue(-1 != present.toString().indexOf(Double.toString(present.orElseThrow()).toString()));
         assertEquals(1.0, present.getAsDouble());
+        assertEquals(1.0, present.orElseThrow());
 
         AtomicBoolean presentCheck = new AtomicBoolean();
         present.ifPresent(v -> presentCheck.set(true));
--- a/test/jdk/java/util/Optional/BasicInt.java	Wed Dec 13 17:28:24 2017 -0800
+++ b/test/jdk/java/util/Optional/BasicInt.java	Wed Dec 13 18:47:20 2017 -0800
@@ -124,6 +124,13 @@
         int got = empty.orElseThrow(ObscureException::new);
     }
 
+    @Test(expectedExceptions=NoSuchElementException.class)
+    public void testEmptyOrElseThrowNoArg() throws Exception {
+        OptionalInt empty = OptionalInt.empty();
+
+        int got = empty.orElseThrow();
+    }
+
     @Test(groups = "unit")
     public void testPresent() {
         OptionalInt empty = OptionalInt.empty();
@@ -137,7 +144,9 @@
         assertTrue(Integer.hashCode(1) == present.hashCode());
         assertFalse(present.toString().isEmpty());
         assertTrue(-1 != present.toString().indexOf(Integer.toString(present.getAsInt()).toString()));
+        assertTrue(-1 != present.toString().indexOf(Integer.toString(present.orElseThrow()).toString()));
         assertEquals(1, present.getAsInt());
+        assertEquals(1, present.orElseThrow());
 
         AtomicBoolean presentCheck = new AtomicBoolean();
         present.ifPresent(v -> presentCheck.set(true));
--- a/test/jdk/java/util/Optional/BasicLong.java	Wed Dec 13 17:28:24 2017 -0800
+++ b/test/jdk/java/util/Optional/BasicLong.java	Wed Dec 13 18:47:20 2017 -0800
@@ -124,6 +124,13 @@
         long got = empty.orElseThrow(ObscureException::new);
     }
 
+    @Test(expectedExceptions=NoSuchElementException.class)
+    public void testEmptyOrElseThrowNoArg() throws Exception {
+        OptionalLong empty = OptionalLong.empty();
+
+        long got = empty.orElseThrow();
+    }
+
     @Test(groups = "unit")
     public void testPresent() {
         OptionalLong empty = OptionalLong.empty();
@@ -137,7 +144,9 @@
         assertTrue(Long.hashCode(1) == present.hashCode());
         assertFalse(present.toString().isEmpty());
         assertTrue(-1 != present.toString().indexOf(Long.toString(present.getAsLong()).toString()));
+        assertTrue(-1 != present.toString().indexOf(Long.toString(present.orElseThrow()).toString()));
         assertEquals(1L, present.getAsLong());
+        assertEquals(1L, present.orElseThrow());
 
         AtomicBoolean presentCheck = new AtomicBoolean();
         present.ifPresent(v -> presentCheck.set(true));