8050820: Please add java.util.Optional.stream() to convert Optional<T> to Stream<T>

Reviewed-by: alundblad, forax, chegar, jrose
This commit is contained in:
Paul Sandoz 2015-02-02 14:19:12 +01:00
parent 3b9021981f
commit dd21d2c4db
8 changed files with 225 additions and 42 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015, 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,7 @@ import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Stream;
/**
* A container object which may or may not contain a non-null value.
@ -155,8 +156,9 @@ public final class Optional<T> {
* null
*/
public void ifPresent(Consumer<? super T> consumer) {
if (value != null)
if (value != null) {
consumer.accept(value);
}
}
/**
@ -172,10 +174,11 @@ public final class Optional<T> {
*/
public Optional<T> filter(Predicate<? super T> predicate) {
Objects.requireNonNull(predicate);
if (!isPresent())
if (!isPresent()) {
return this;
else
} else {
return predicate.test(value) ? this : empty();
}
}
/**
@ -209,9 +212,9 @@ public final class Optional<T> {
*/
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
if (!isPresent()) {
return empty();
else {
} else {
return Optional.ofNullable(mapper.apply(value));
}
}
@ -235,13 +238,36 @@ public final class Optional<T> {
*/
public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
if (!isPresent()) {
return empty();
else {
} else {
return Objects.requireNonNull(mapper.apply(value));
}
}
/**
* If a value is present return a sequential {@link Stream} containing only
* that value, otherwise return an empty {@code Stream}.
*
* @apiNote This method can be used to transform a {@code Stream} of
* optional elements to a {@code Stream} of present value elements:
*
* <pre>{@code
* Stream<Optional<T>> os = ..
* Stream<T> s = os.flatMap(Optional::stream)
* }</pre>
*
* @return the optional value as a {@code Stream}
* @since 1.9
*/
public Stream<T> stream() {
if (!isPresent()) {
return Stream.empty();
} else {
return Stream.of(value);
}
}
/**
* Return the value if present, otherwise return {@code other}.
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015, 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
@ -27,6 +27,7 @@ package java.util;
import java.util.function.DoubleConsumer;
import java.util.function.DoubleSupplier;
import java.util.function.Supplier;
import java.util.stream.DoubleStream;
/**
* A container object which may or may not contain a {@code double} value.
@ -138,8 +139,32 @@ public final class OptionalDouble {
* null
*/
public void ifPresent(DoubleConsumer consumer) {
if (isPresent)
if (isPresent) {
consumer.accept(value);
}
}
/**
* If a value is present return a sequential {@link DoubleStream} containing
* only that value, otherwise return an empty {@code DoubleStream}.
*
* @apiNote This method can be used to transform a {@code Stream} of
* optional doubles to a {@code DoubleStream} of present doubles:
*
* <pre>{@code
* Stream<OptionalDouble> os = ..
* DoubleStream s = os.flatMapToDouble(OptionalDouble::stream)
* }</pre>
*
* @return the optional value as a {@code DoubleStream}
* @since 1.9
*/
public DoubleStream stream() {
if (isPresent) {
return DoubleStream.of(value);
} else {
return DoubleStream.empty();
}
}
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015, 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
@ -27,6 +27,7 @@ package java.util;
import java.util.function.IntConsumer;
import java.util.function.IntSupplier;
import java.util.function.Supplier;
import java.util.stream.IntStream;
/**
* A container object which may or may not contain a {@code int} value.
@ -138,8 +139,32 @@ public final class OptionalInt {
* null
*/
public void ifPresent(IntConsumer consumer) {
if (isPresent)
if (isPresent) {
consumer.accept(value);
}
}
/**
* If a value is present return a sequential {@link IntStream} containing
* only that value, otherwise return an empty {@code IntStream}.
*
* @apiNote This method can be used to transform a {@code Stream} of
* optional integers to an {@code IntStream} of present integers:
*
* <pre>{@code
* Stream<OptionalInt> os = ..
* IntStream s = os.flatMapToInt(OptionalInt::stream)
* }</pre>
*
* @return the optional value as an {@code IntStream}
* @since 1.9
*/
public IntStream stream() {
if (isPresent) {
return IntStream.of(value);
} else {
return IntStream.empty();
}
}
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015, 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
@ -27,6 +27,7 @@ package java.util;
import java.util.function.LongConsumer;
import java.util.function.LongSupplier;
import java.util.function.Supplier;
import java.util.stream.LongStream;
/**
* A container object which may or may not contain a {@code long} value.
@ -138,8 +139,32 @@ public final class OptionalLong {
* null
*/
public void ifPresent(LongConsumer consumer) {
if (isPresent)
if (isPresent) {
consumer.accept(value);
}
}
/**
* If a value is present return a sequential {@link LongStream} containing
* only that value, otherwise return an empty {@code LongStream}.
*
* @apiNote This method can be used to transform a {@code Stream} of
* optional longs to a {@code LongStream} of present longs:
*
* <pre>{@code
* Stream<OptionalLong> os = ..
* LongStream s = os.flatMapToLong(OptionalLong::stream)
* }</pre>
*
* @return the optional value as a {@code LongStream}
* @since 1.9
*/
public LongStream stream() {
if (isPresent) {
return LongStream.of(value);
} else {
return LongStream.empty();
}
}
/**

View File

@ -29,6 +29,7 @@
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.stream.Stream;
import static org.testng.Assert.*;
import org.testng.annotations.Test;
@ -54,8 +55,8 @@ public class Basic {
assertSame(null, empty.orElse(null));
RuntimeException orElse = new RuntimeException() { };
assertSame(Boolean.FALSE, empty.orElse(Boolean.FALSE));
assertSame(null, empty.orElseGet(()-> null));
assertSame(Boolean.FALSE, empty.orElseGet(()-> Boolean.FALSE));
assertSame(null, empty.orElseGet(() -> null));
assertSame(Boolean.FALSE, empty.orElseGet(() -> Boolean.FALSE));
}
@Test(expectedExceptions=NoSuchElementException.class)
@ -104,15 +105,15 @@ public class Basic {
try {
present.ifPresent(v -> { throw new ObscureException(); });
fail();
} catch(ObscureException expected) {
} catch (ObscureException expected) {
}
assertSame(Boolean.TRUE, present.orElse(null));
assertSame(Boolean.TRUE, present.orElse(Boolean.FALSE));
assertSame(Boolean.TRUE, present.orElseGet(null));
assertSame(Boolean.TRUE, present.orElseGet(()-> null));
assertSame(Boolean.TRUE, present.orElseGet(()-> Boolean.FALSE));
assertSame(Boolean.TRUE, present.<RuntimeException>orElseThrow( null));
assertSame(Boolean.TRUE, present.orElseGet(() -> null));
assertSame(Boolean.TRUE, present.orElseGet(() -> Boolean.FALSE));
assertSame(Boolean.TRUE, present.<RuntimeException>orElseThrow(null));
assertSame(Boolean.TRUE, present.<RuntimeException>orElseThrow(ObscureException::new));
}
@ -226,6 +227,26 @@ public class Basic {
assertSame(l, fixture);
}
@Test(groups = "unit")
public void testStream() {
{
Stream<String> s = Optional.<String>empty().stream();
assertFalse(s.isParallel());
Object[] es = s.toArray();
assertEquals(es.length, 0);
}
{
Stream<String> s = Optional.of("Duke").stream();
assertFalse(s.isParallel());
String[] es = s.toArray(String[]::new);
assertEquals(es.length, 1);
assertEquals(es[0], "Duke");
}
}
private static class ObscureException extends RuntimeException {
}

View File

@ -29,6 +29,7 @@
import java.util.NoSuchElementException;
import java.util.OptionalDouble;
import java.util.stream.DoubleStream;
import static org.testng.Assert.*;
import org.testng.annotations.Test;
@ -109,6 +110,26 @@ public class BasicDouble {
assertEquals(1.0, present.<RuntimeException>orElseThrow(ObscureException::new));
}
@Test(groups = "unit")
public void testStream() {
{
DoubleStream s = OptionalDouble.empty().stream();
assertFalse(s.isParallel());
double[] es = s.toArray();
assertEquals(es.length, 0);
}
{
DoubleStream s = OptionalDouble.of(42.0).stream();
assertFalse(s.isParallel());
double[] es = s.toArray();
assertEquals(es.length, 1);
assertEquals(es[0], 42.0);
}
}
private static class ObscureException extends RuntimeException {
}

View File

@ -29,6 +29,7 @@
import java.util.NoSuchElementException;
import java.util.OptionalInt;
import java.util.stream.IntStream;
import static org.testng.Assert.*;
import org.testng.annotations.Test;
@ -53,36 +54,36 @@ public class BasicInt {
assertEquals(2, empty.orElseGet(()-> 2));
}
@Test(expectedExceptions=NoSuchElementException.class)
public void testEmptyGet() {
OptionalInt empty = OptionalInt.empty();
@Test(expectedExceptions=NoSuchElementException.class)
public void testEmptyGet() {
OptionalInt empty = OptionalInt.empty();
int got = empty.getAsInt();
}
int got = empty.getAsInt();
}
@Test(expectedExceptions=NullPointerException.class)
public void testEmptyOrElseGetNull() {
OptionalInt empty = OptionalInt.empty();
@Test(expectedExceptions=NullPointerException.class)
public void testEmptyOrElseGetNull() {
OptionalInt empty = OptionalInt.empty();
int got = empty.orElseGet(null);
}
int got = empty.orElseGet(null);
}
@Test(expectedExceptions=NullPointerException.class)
public void testEmptyOrElseThrowNull() throws Throwable {
OptionalInt empty = OptionalInt.empty();
@Test(expectedExceptions=NullPointerException.class)
public void testEmptyOrElseThrowNull() throws Throwable {
OptionalInt empty = OptionalInt.empty();
int got = empty.orElseThrow(null);
}
int got = empty.orElseThrow(null);
}
@Test(expectedExceptions=ObscureException.class)
public void testEmptyOrElseThrow() throws Exception {
OptionalInt empty = OptionalInt.empty();
@Test(expectedExceptions=ObscureException.class)
public void testEmptyOrElseThrow() throws Exception {
OptionalInt empty = OptionalInt.empty();
int got = empty.orElseThrow(ObscureException::new);
}
int got = empty.orElseThrow(ObscureException::new);
}
@Test(groups = "unit")
public void testPresent() {
@Test(groups = "unit")
public void testPresent() {
OptionalInt empty = OptionalInt.empty();
OptionalInt present = OptionalInt.of(1);
@ -109,6 +110,26 @@ public class BasicInt {
assertEquals(1, present.<RuntimeException>orElseThrow(ObscureException::new));
}
@Test(groups = "unit")
public void testStream() {
{
IntStream s = OptionalInt.empty().stream();
assertFalse(s.isParallel());
int[] es = s.toArray();
assertEquals(es.length, 0);
}
{
IntStream s = OptionalInt.of(42).stream();
assertFalse(s.isParallel());
int[] es = OptionalInt.of(42).stream().toArray();
assertEquals(es.length, 1);
assertEquals(es[0], 42);
}
}
private static class ObscureException extends RuntimeException {
}

View File

@ -29,6 +29,7 @@
import java.util.NoSuchElementException;
import java.util.OptionalLong;
import java.util.stream.LongStream;
import static org.testng.Assert.*;
import org.testng.annotations.Test;
@ -109,6 +110,24 @@ public class BasicLong {
assertEquals(1, present.<RuntimeException>orElseThrow(ObscureException::new));
}
@Test(groups = "unit")
public void testStream() {
{
LongStream s = OptionalLong.empty().stream();
long[] es = s.toArray();
assertEquals(es.length, 0);
}
{
LongStream s = OptionalLong.of(42L).stream();
long[] es = s.toArray();
assertEquals(es.length, 1);
assertEquals(es[0], 42L);
}
}
private static class ObscureException extends RuntimeException {
}