# HG changeset patch # User psandoz # Date 1423822407 -3600 # Node ID 8498cdb7c54bf65f03765630abf377a1af69aa36 # Parent e3028445a1ffce6fcce68b12b75f42f1fe0d72e9 8071670: java.util.Optional: please add a way to specify if-else behavior Reviewed-by: dfuchs, lowasser diff -r e3028445a1ff -r 8498cdb7c54b jdk/src/java.base/share/classes/java/util/Optional.java --- a/jdk/src/java.base/share/classes/java/util/Optional.java Fri Feb 13 11:03:57 2015 +0800 +++ b/jdk/src/java.base/share/classes/java/util/Optional.java Fri Feb 13 11:13:27 2015 +0100 @@ -38,8 +38,8 @@ * <p>Additional methods that depend on the presence or absence of a contained * value are provided, such as {@link #orElse(java.lang.Object) orElse()} * (return a default value if value not present) and - * {@link #ifPresent(java.util.function.Consumer) ifPresent()} (execute a block - * of code if the value is present). + * {@link #ifPresent(java.util.function.Consumer) ifPresent()} (perform an + * action if the value is present). * * <p>This is a <a href="../lang/doc-files/ValueBased.html">value-based</a> * class; use of identity-sensitive operations (including reference equality @@ -148,16 +148,35 @@ } /** - * If a value is present, invoke the specified consumer with the value, + * If a value is present, perform the given action with the value, * otherwise do nothing. * - * @param consumer block to be executed if a value is present - * @throws NullPointerException if value is present and {@code consumer} is + * @param action the action to be performed if a value is present + * @throws NullPointerException if a value is present and {@code action} is * null */ - public void ifPresent(Consumer<? super T> consumer) { + public void ifPresent(Consumer<? super T> action) { if (value != null) { - consumer.accept(value); + action.accept(value); + } + } + + /** + * If a value is present, perform the given action with the value, + * otherwise perform the given empty-based action. + * + * @param action the action to be performed if a value is present + * @param emptyAction the empty-based action to be performed if a value is + * not present + * @throws NullPointerException if a value is present and {@code action} is + * null, or a value is not present and {@code emptyAction} is null. + * @since 1.9 + */ + public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction) { + if (value != null) { + action.accept(value); + } else { + emptyAction.run(); } } diff -r e3028445a1ff -r 8498cdb7c54b jdk/src/java.base/share/classes/java/util/OptionalDouble.java --- a/jdk/src/java.base/share/classes/java/util/OptionalDouble.java Fri Feb 13 11:03:57 2015 +0800 +++ b/jdk/src/java.base/share/classes/java/util/OptionalDouble.java Fri Feb 13 11:13:27 2015 +0100 @@ -37,8 +37,8 @@ * <p>Additional methods that depend on the presence or absence of a contained * value are provided, such as {@link #orElse(double) orElse()} * (return a default value if value not present) and - * {@link #ifPresent(java.util.function.DoubleConsumer) ifPresent()} (execute a block - * of code if the value is present). + * {@link #ifPresent(java.util.function.DoubleConsumer) ifPresent()} (perform an + * action if the value is present). * * <p>This is a <a href="../lang/doc-files/ValueBased.html">value-based</a> * class; use of identity-sensitive operations (including reference equality @@ -131,16 +131,35 @@ } /** - * Have the specified consumer accept the value if a value is present, + * If a value is present, perform the given action with the value, * otherwise do nothing. * - * @param consumer block to be executed if a value is present - * @throws NullPointerException if value is present and {@code consumer} is + * @param action the action to be performed if a value is present + * @throws NullPointerException if a value is present and {@code action} is * null */ - public void ifPresent(DoubleConsumer consumer) { + public void ifPresent(DoubleConsumer action) { if (isPresent) { - consumer.accept(value); + action.accept(value); + } + } + + /** + * If a value is present, perform the given action with the value, + * otherwise perform the given empty-based action. + * + * @param action the action to be performed if a value is present + * @param emptyAction the empty-based action to be performed if a value is + * not present + * @throws NullPointerException if a value is present and {@code action} is + * null, or a value is not present and {@code emptyAction} is null. + * @since 1.9 + */ + public void ifPresentOrElse(DoubleConsumer action, Runnable emptyAction) { + if (isPresent) { + action.accept(value); + } else { + emptyAction.run(); } } diff -r e3028445a1ff -r 8498cdb7c54b jdk/src/java.base/share/classes/java/util/OptionalInt.java --- a/jdk/src/java.base/share/classes/java/util/OptionalInt.java Fri Feb 13 11:03:57 2015 +0800 +++ b/jdk/src/java.base/share/classes/java/util/OptionalInt.java Fri Feb 13 11:13:27 2015 +0100 @@ -37,8 +37,8 @@ * <p>Additional methods that depend on the presence or absence of a contained * value are provided, such as {@link #orElse(int) orElse()} * (return a default value if value not present) and - * {@link #ifPresent(java.util.function.IntConsumer) ifPresent()} (execute a block - * of code if the value is present). + * {@link #ifPresent(java.util.function.IntConsumer) ifPresent()} (perform an + * action if the value is present). * * <p>This is a <a href="../lang/doc-files/ValueBased.html">value-based</a> * class; use of identity-sensitive operations (including reference equality @@ -131,16 +131,35 @@ } /** - * Have the specified consumer accept the value if a value is present, + * If a value is present, perform the given action with the value, * otherwise do nothing. * - * @param consumer block to be executed if a value is present - * @throws NullPointerException if value is present and {@code consumer} is + * @param action the action to be performed if a value is present + * @throws NullPointerException if value is present and {@code action} is * null */ - public void ifPresent(IntConsumer consumer) { + public void ifPresent(IntConsumer action) { if (isPresent) { - consumer.accept(value); + action.accept(value); + } + } + + /** + * If a value is present, perform the given action with the value, + * otherwise perform the given empty-based action. + * + * @param action the action to be performed if a value is present + * @param emptyAction the empty-based action to be performed if a value is + * not present + * @throws NullPointerException if a value is present and {@code action} is + * null, or a value is not present and {@code emptyAction} is null. + * @since 1.9 + */ + public void ifPresentOrElse(IntConsumer action, Runnable emptyAction) { + if (isPresent) { + action.accept(value); + } else { + emptyAction.run(); } } diff -r e3028445a1ff -r 8498cdb7c54b jdk/src/java.base/share/classes/java/util/OptionalLong.java --- a/jdk/src/java.base/share/classes/java/util/OptionalLong.java Fri Feb 13 11:03:57 2015 +0800 +++ b/jdk/src/java.base/share/classes/java/util/OptionalLong.java Fri Feb 13 11:13:27 2015 +0100 @@ -37,8 +37,8 @@ * <p>Additional methods that depend on the presence or absence of a contained * value are provided, such as {@link #orElse(long) orElse()} * (return a default value if value not present) and - * {@link #ifPresent(java.util.function.LongConsumer) ifPresent()} (execute a block - * of code if the value is present). + * {@link #ifPresent(java.util.function.LongConsumer) ifPresent()} (perform an + * action if the value is present). * * <p>This is a <a href="../lang/doc-files/ValueBased.html">value-based</a> * class; use of identity-sensitive operations (including reference equality @@ -131,16 +131,35 @@ } /** - * Have the specified consumer accept the value if a value is present, + * If a value is present, perform the given action with the value, * otherwise do nothing. * - * @param consumer block to be executed if a value is present - * @throws NullPointerException if value is present and {@code consumer} is + * @param action the action to be performed if a value is present + * @throws NullPointerException if a value is present and {@code action} is * null */ - public void ifPresent(LongConsumer consumer) { + public void ifPresent(LongConsumer action) { if (isPresent) { - consumer.accept(value); + action.accept(value); + } + } + + /** + * If a value is present, perform the given action with the value, + * otherwise perform the given empty-based action. + * + * @param action the action to be performed if a value is present + * @param emptyAction the empty-based action to be performed if a value is + * not present + * @throws NullPointerException if a value is present and {@code action} is + * null, or a value is not present and {@code emptyAction} is null. + * @since 1.9 + */ + public void ifPresentOrElse(LongConsumer action, Runnable emptyAction) { + if (isPresent) { + action.accept(value); + } else { + emptyAction.run(); } } diff -r e3028445a1ff -r 8498cdb7c54b jdk/test/java/util/Optional/Basic.java --- a/jdk/test/java/util/Optional/Basic.java Fri Feb 13 11:03:57 2015 +0800 +++ b/jdk/test/java/util/Optional/Basic.java Fri Feb 13 11:13:27 2015 +0100 @@ -27,8 +27,12 @@ * @run testng Basic */ +import java.lang.AssertionError; +import java.lang.NullPointerException; +import java.lang.Throwable; import java.util.NoSuchElementException; import java.util.Optional; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Stream; import static org.testng.Assert.*; @@ -51,7 +55,23 @@ assertTrue(!empty.toString().isEmpty()); assertTrue(!empty.toString().equals(presentEmptyString.toString())); assertTrue(!empty.isPresent()); - empty.ifPresent(v -> { fail(); }); + + empty.ifPresent(v -> fail()); + + AtomicBoolean emptyCheck = new AtomicBoolean(); + empty.ifPresentOrElse(v -> fail(), () -> emptyCheck.set(true)); + assertTrue(emptyCheck.get()); + + try { + empty.ifPresentOrElse(v -> fail(), () -> { throw new ObscureException(); }); + fail(); + } catch (ObscureException expected) { + } catch (AssertionError e) { + throw e; + } catch (Throwable t) { + fail(); + } + assertSame(null, empty.orElse(null)); RuntimeException orElse = new RuntimeException() { }; assertSame(Boolean.FALSE, empty.orElse(Boolean.FALSE)); @@ -59,6 +79,31 @@ assertSame(Boolean.FALSE, empty.orElseGet(() -> Boolean.FALSE)); } + @Test(groups = "unit") + public void testIfPresentAndOrElseAndNull() { + Optional<Boolean> empty = Optional.empty(); + Optional<Boolean> present = Optional.of(Boolean.TRUE); + + // No NPE + present.ifPresentOrElse(v -> {}, null); + empty.ifPresent(null); + empty.ifPresentOrElse(null, () -> {}); + + // NPE + try { + present.ifPresent(null); + fail(); + } catch (NullPointerException ex) {} + try { + present.ifPresentOrElse(null, () -> {}); + fail(); + } catch (NullPointerException ex) {} + try { + empty.ifPresentOrElse(v -> {}, null); + fail(); + } catch (NullPointerException ex) {} + } + @Test(expectedExceptions=NoSuchElementException.class) public void testEmptyGet() { Optional<Boolean> empty = Optional.empty(); @@ -102,12 +147,33 @@ assertTrue(!present.toString().equals(presentEmptyString.toString())); assertTrue(-1 != present.toString().indexOf(Boolean.TRUE.toString())); assertSame(Boolean.TRUE, present.get()); + + AtomicBoolean presentCheck = new AtomicBoolean(); + present.ifPresent(v -> presentCheck.set(true)); + assertTrue(presentCheck.get()); + presentCheck.set(false); + present.ifPresentOrElse(v -> presentCheck.set(true), () -> fail()); + assertTrue(presentCheck.get()); + try { present.ifPresent(v -> { throw new ObscureException(); }); fail(); } catch (ObscureException expected) { + } catch (AssertionError e) { + throw e; + } catch (Throwable t) { + fail(); + } + try { + present.ifPresentOrElse(v -> { throw new ObscureException(); }, () -> fail()); + fail(); + } catch (ObscureException expected) { + } catch (AssertionError e) { + throw e; + } catch (Throwable t) { + fail(); + } - } assertSame(Boolean.TRUE, present.orElse(null)); assertSame(Boolean.TRUE, present.orElse(Boolean.FALSE)); assertSame(Boolean.TRUE, present.orElseGet(null)); diff -r e3028445a1ff -r 8498cdb7c54b jdk/test/java/util/Optional/BasicDouble.java --- a/jdk/test/java/util/Optional/BasicDouble.java Fri Feb 13 11:03:57 2015 +0800 +++ b/jdk/test/java/util/Optional/BasicDouble.java Fri Feb 13 11:13:27 2015 +0100 @@ -29,6 +29,7 @@ import java.util.NoSuchElementException; import java.util.OptionalDouble; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.DoubleStream; import static org.testng.Assert.*; @@ -49,41 +50,82 @@ assertTrue(0 == empty.hashCode()); assertTrue(!empty.toString().isEmpty()); assertTrue(!empty.isPresent()); + empty.ifPresent(v -> { fail(); }); + + AtomicBoolean emptyCheck = new AtomicBoolean(); + empty.ifPresentOrElse(v -> fail(), () -> emptyCheck.set(true)); + assertTrue(emptyCheck.get()); + + try { + empty.ifPresentOrElse(v -> fail(), () -> { throw new ObscureException(); }); + fail(); + } catch (ObscureException expected) { + } catch (AssertionError e) { + throw e; + } catch (Throwable t) { + fail(); + } + assertEquals(2.0, empty.orElse(2.0)); assertEquals(2.0, empty.orElseGet(()-> 2.0)); } - @Test(expectedExceptions=NoSuchElementException.class) - public void testEmptyGet() { - OptionalDouble empty = OptionalDouble.empty(); + @Test(groups = "unit") + public void testIfPresentAndOrElseAndNull() { + OptionalDouble empty = OptionalDouble.empty(); + OptionalDouble present = OptionalDouble.of(1.0); - double got = empty.getAsDouble(); - } + // No NPE + present.ifPresentOrElse(v -> {}, null); + empty.ifPresent(null); + empty.ifPresentOrElse(null, () -> {}); - @Test(expectedExceptions=NullPointerException.class) - public void testEmptyOrElseGetNull() { - OptionalDouble empty = OptionalDouble.empty(); - - double got = empty.orElseGet(null); - } + // NPE + try { + present.ifPresent(null); + fail(); + } catch (NullPointerException ex) {} + try { + present.ifPresentOrElse(null, () -> {}); + fail(); + } catch (NullPointerException ex) {} + try { + empty.ifPresentOrElse(v -> {}, null); + fail(); + } catch (NullPointerException ex) {} + } - @Test(expectedExceptions=NullPointerException.class) - public void testEmptyOrElseThrowNull() throws Throwable { - OptionalDouble empty = OptionalDouble.empty(); + @Test(expectedExceptions=NoSuchElementException.class) + public void testEmptyGet() { + OptionalDouble empty = OptionalDouble.empty(); + + double got = empty.getAsDouble(); + } - double got = empty.orElseThrow(null); - } + @Test(expectedExceptions=NullPointerException.class) + public void testEmptyOrElseGetNull() { + OptionalDouble empty = OptionalDouble.empty(); + + double got = empty.orElseGet(null); + } - @Test(expectedExceptions=ObscureException.class) - public void testEmptyOrElseThrow() throws Exception { - OptionalDouble empty = OptionalDouble.empty(); + @Test(expectedExceptions=NullPointerException.class) + public void testEmptyOrElseThrowNull() throws Throwable { + OptionalDouble empty = OptionalDouble.empty(); + + double got = empty.orElseThrow(null); + } - double got = empty.orElseThrow(ObscureException::new); - } + @Test(expectedExceptions=ObscureException.class) + public void testEmptyOrElseThrow() throws Exception { + OptionalDouble empty = OptionalDouble.empty(); - @Test(groups = "unit") - public void testPresent() { + double got = empty.orElseThrow(ObscureException::new); + } + + @Test(groups = "unit") + public void testPresent() { OptionalDouble empty = OptionalDouble.empty(); OptionalDouble present = OptionalDouble.of(1.0); @@ -96,12 +138,33 @@ assertFalse(present.toString().isEmpty()); assertTrue(-1 != present.toString().indexOf(Double.toString(present.getAsDouble()).toString())); assertEquals(1.0, present.getAsDouble()); + + AtomicBoolean presentCheck = new AtomicBoolean(); + present.ifPresent(v -> presentCheck.set(true)); + assertTrue(presentCheck.get()); + presentCheck.set(false); + present.ifPresentOrElse(v -> presentCheck.set(true), () -> fail()); + assertTrue(presentCheck.get()); + try { present.ifPresent(v -> { throw new ObscureException(); }); fail(); - } catch(ObscureException expected) { + } catch (ObscureException expected) { + } catch (AssertionError e) { + throw e; + } catch (Throwable t) { + fail(); + } + try { + present.ifPresentOrElse(v -> { throw new ObscureException(); }, () -> fail()); + fail(); + } catch (ObscureException expected) { + } catch (AssertionError e) { + throw e; + } catch (Throwable t) { + fail(); + } - } assertEquals(1.0, present.orElse(2.0)); assertEquals(1.0, present.orElseGet(null)); assertEquals(1.0, present.orElseGet(()-> 2.0)); diff -r e3028445a1ff -r 8498cdb7c54b jdk/test/java/util/Optional/BasicInt.java --- a/jdk/test/java/util/Optional/BasicInt.java Fri Feb 13 11:03:57 2015 +0800 +++ b/jdk/test/java/util/Optional/BasicInt.java Fri Feb 13 11:13:27 2015 +0100 @@ -29,6 +29,7 @@ import java.util.NoSuchElementException; import java.util.OptionalInt; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.IntStream; import static org.testng.Assert.*; @@ -49,11 +50,52 @@ assertTrue(0 == empty.hashCode()); assertTrue(!empty.toString().isEmpty()); assertTrue(!empty.isPresent()); + empty.ifPresent(v -> { fail(); }); + + AtomicBoolean emptyCheck = new AtomicBoolean(); + empty.ifPresentOrElse(v -> fail(), () -> emptyCheck.set(true)); + assertTrue(emptyCheck.get()); + + try { + empty.ifPresentOrElse(v -> fail(), () -> { throw new ObscureException(); }); + fail(); + } catch (ObscureException expected) { + } catch (AssertionError e) { + throw e; + } catch (Throwable t) { + fail(); + } + assertEquals(2, empty.orElse(2)); assertEquals(2, empty.orElseGet(()-> 2)); } + @Test(groups = "unit") + public void testIfPresentAndOrElseAndNull() { + OptionalInt empty = OptionalInt.empty(); + OptionalInt present = OptionalInt.of(1); + + // No NPE + present.ifPresentOrElse(v -> {}, null); + empty.ifPresent(null); + empty.ifPresentOrElse(null, () -> {}); + + // NPE + try { + present.ifPresent(null); + fail(); + } catch (NullPointerException ex) {} + try { + present.ifPresentOrElse(null, () -> {}); + fail(); + } catch (NullPointerException ex) {} + try { + empty.ifPresentOrElse(v -> {}, null); + fail(); + } catch (NullPointerException ex) {} + } + @Test(expectedExceptions=NoSuchElementException.class) public void testEmptyGet() { OptionalInt empty = OptionalInt.empty(); @@ -96,12 +138,33 @@ assertFalse(present.toString().isEmpty()); assertTrue(-1 != present.toString().indexOf(Integer.toString(present.getAsInt()).toString())); assertEquals(1, present.getAsInt()); + + AtomicBoolean presentCheck = new AtomicBoolean(); + present.ifPresent(v -> presentCheck.set(true)); + assertTrue(presentCheck.get()); + presentCheck.set(false); + present.ifPresentOrElse(v -> presentCheck.set(true), () -> fail()); + assertTrue(presentCheck.get()); + try { present.ifPresent(v -> { throw new ObscureException(); }); fail(); - } catch(ObscureException expected) { + } catch (ObscureException expected) { + } catch (AssertionError e) { + throw e; + } catch (Throwable t) { + fail(); + } + try { + present.ifPresentOrElse(v -> { throw new ObscureException(); }, () -> fail()); + fail(); + } catch (ObscureException expected) { + } catch (AssertionError e) { + throw e; + } catch (Throwable t) { + fail(); + } - } assertEquals(1, present.orElse(2)); assertEquals(1, present.orElseGet(null)); assertEquals(1, present.orElseGet(()-> 2)); diff -r e3028445a1ff -r 8498cdb7c54b jdk/test/java/util/Optional/BasicLong.java --- a/jdk/test/java/util/Optional/BasicLong.java Fri Feb 13 11:03:57 2015 +0800 +++ b/jdk/test/java/util/Optional/BasicLong.java Fri Feb 13 11:13:27 2015 +0100 @@ -29,6 +29,7 @@ import java.util.NoSuchElementException; import java.util.OptionalLong; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.LongStream; import static org.testng.Assert.*; @@ -49,41 +50,82 @@ assertTrue(0 == empty.hashCode()); assertTrue(!empty.toString().isEmpty()); assertTrue(!empty.isPresent()); + empty.ifPresent(v -> { fail(); }); + + AtomicBoolean emptyCheck = new AtomicBoolean(); + empty.ifPresentOrElse(v -> fail(), () -> emptyCheck.set(true)); + assertTrue(emptyCheck.get()); + + try { + empty.ifPresentOrElse(v -> fail(), () -> { throw new ObscureException(); }); + fail(); + } catch (ObscureException expected) { + } catch (AssertionError e) { + throw e; + } catch (Throwable t) { + fail(); + } + assertEquals(2, empty.orElse(2)); assertEquals(2, empty.orElseGet(()-> 2)); } - @Test(expectedExceptions=NoSuchElementException.class) - public void testEmptyGet() { - OptionalLong empty = OptionalLong.empty(); + @Test(groups = "unit") + public void testIfPresentAndOrElseAndNull() { + OptionalLong empty = OptionalLong.empty(); + OptionalLong present = OptionalLong.of(1); - long got = empty.getAsLong(); - } + // No NPE + present.ifPresentOrElse(v -> {}, null); + empty.ifPresent(null); + empty.ifPresentOrElse(null, () -> {}); - @Test(expectedExceptions=NullPointerException.class) - public void testEmptyOrElseGetNull() { - OptionalLong empty = OptionalLong.empty(); - - long got = empty.orElseGet(null); - } + // NPE + try { + present.ifPresent(null); + fail(); + } catch (NullPointerException ex) {} + try { + present.ifPresentOrElse(null, () -> {}); + fail(); + } catch (NullPointerException ex) {} + try { + empty.ifPresentOrElse(v -> {}, null); + fail(); + } catch (NullPointerException ex) {} + } - @Test(expectedExceptions=NullPointerException.class) - public void testEmptyOrElseThrowNull() throws Throwable { - OptionalLong empty = OptionalLong.empty(); + @Test(expectedExceptions=NoSuchElementException.class) + public void testEmptyGet() { + OptionalLong empty = OptionalLong.empty(); + + long got = empty.getAsLong(); + } - long got = empty.orElseThrow(null); - } + @Test(expectedExceptions=NullPointerException.class) + public void testEmptyOrElseGetNull() { + OptionalLong empty = OptionalLong.empty(); + + long got = empty.orElseGet(null); + } - @Test(expectedExceptions=ObscureException.class) - public void testEmptyOrElseThrow() throws Exception { - OptionalLong empty = OptionalLong.empty(); + @Test(expectedExceptions=NullPointerException.class) + public void testEmptyOrElseThrowNull() throws Throwable { + OptionalLong empty = OptionalLong.empty(); + + long got = empty.orElseThrow(null); + } - long got = empty.orElseThrow(ObscureException::new); - } + @Test(expectedExceptions=ObscureException.class) + public void testEmptyOrElseThrow() throws Exception { + OptionalLong empty = OptionalLong.empty(); - @Test(groups = "unit") - public void testPresent() { + long got = empty.orElseThrow(ObscureException::new); + } + + @Test(groups = "unit") + public void testPresent() { OptionalLong empty = OptionalLong.empty(); OptionalLong present = OptionalLong.of(1L); @@ -96,12 +138,35 @@ assertFalse(present.toString().isEmpty()); assertTrue(-1 != present.toString().indexOf(Long.toString(present.getAsLong()).toString())); assertEquals(1L, present.getAsLong()); + + AtomicBoolean presentCheck = new AtomicBoolean(); + present.ifPresent(v -> presentCheck.set(true)); + assertTrue(presentCheck.get()); + presentCheck.set(false); + present.ifPresentOrElse(v -> presentCheck.set(true), () -> fail()); + assertTrue(presentCheck.get()); + try { present.ifPresent(v -> { throw new ObscureException(); }); fail(); - } catch(ObscureException expected) { + } catch (ObscureException expected) { + } catch (AssertionError e) { + throw e; + } catch (Throwable t) { + fail(); + } + try { + present.ifPresentOrElse(v -> { + throw new ObscureException(); + }, () -> fail()); + fail(); + } catch (ObscureException expected) { + } catch (AssertionError e) { + throw e; + } catch (Throwable t) { + fail(); + } - } assertEquals(1, present.orElse(2)); assertEquals(1, present.orElseGet(null)); assertEquals(1, present.orElseGet(()-> 2));