Skip to content

Commit cae3f2a

Browse files
treblereelcopybara-github
authored andcommitted
Add Java 9 Optional APIs
Closes #224 PiperOrigin-RevId: 606390605
1 parent d0eb4fb commit cae3f2a

13 files changed

+317
-13
lines changed

jre/java/java/util/Optional.java

+9
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.function.Function;
2424
import java.util.function.Predicate;
2525
import java.util.function.Supplier;
26+
import java.util.stream.Stream;
2627

2728
/**
2829
* See <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html">
@@ -130,6 +131,14 @@ public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSuppli
130131
throw exceptionSupplier.get();
131132
}
132133

134+
public Stream<T> stream() {
135+
if (isPresent()) {
136+
return Stream.of(ref);
137+
} else {
138+
return Stream.empty();
139+
}
140+
}
141+
133142
@Override
134143
public boolean equals(Object obj) {
135144
if (obj == this) {

jre/java/java/util/OptionalDouble.java

+19-2
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@
1515
*/
1616
package java.util;
1717

18+
import static javaemul.internal.InternalPreconditions.checkCriticalElement;
19+
1820
import java.util.function.DoubleConsumer;
1921
import java.util.function.DoubleSupplier;
2022
import java.util.function.Supplier;
21-
22-
import static javaemul.internal.InternalPreconditions.checkCriticalElement;
23+
import java.util.stream.DoubleStream;
2324

2425
/**
2526
* See <a href="https://docs.oracle.com/javase/8/docs/api/java/util/OptionalDouble.html">
@@ -65,6 +66,14 @@ public void ifPresent(DoubleConsumer consumer) {
6566
}
6667
}
6768

69+
public void ifPresentOrElse(DoubleConsumer action, Runnable emptyAction) {
70+
if (isPresent()) {
71+
action.accept(ref);
72+
} else {
73+
emptyAction.run();
74+
}
75+
}
76+
6877
public double orElse(double other) {
6978
return present ? ref : other;
7079
}
@@ -80,6 +89,14 @@ public <X extends Throwable> double orElseThrow(Supplier<X> exceptionSupplier) t
8089
throw exceptionSupplier.get();
8190
}
8291

92+
public DoubleStream stream() {
93+
if (isPresent()) {
94+
return DoubleStream.of(ref);
95+
} else {
96+
return DoubleStream.empty();
97+
}
98+
}
99+
83100
@Override
84101
public boolean equals(Object obj) {
85102
if (obj == this) {

jre/java/java/util/OptionalInt.java

+19-2
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@
1515
*/
1616
package java.util;
1717

18+
import static javaemul.internal.InternalPreconditions.checkCriticalElement;
19+
1820
import java.util.function.IntConsumer;
1921
import java.util.function.IntSupplier;
2022
import java.util.function.Supplier;
21-
22-
import static javaemul.internal.InternalPreconditions.checkCriticalElement;
23+
import java.util.stream.IntStream;
2324

2425
/**
2526
* See <a href="https://docs.oracle.com/javase/8/docs/api/java/util/OptionalInt.html">
@@ -65,6 +66,14 @@ public void ifPresent(IntConsumer consumer) {
6566
}
6667
}
6768

69+
public void ifPresentOrElse(IntConsumer action, Runnable emptyAction) {
70+
if (present) {
71+
action.accept(ref);
72+
} else {
73+
emptyAction.run();
74+
}
75+
}
76+
6877
public int orElse(int other) {
6978
return present ? ref : other;
7079
}
@@ -80,6 +89,14 @@ public <X extends Throwable> int orElseThrow(Supplier<X> exceptionSupplier) thro
8089
throw exceptionSupplier.get();
8190
}
8291

92+
public IntStream stream() {
93+
if (present) {
94+
return IntStream.of(ref);
95+
} else {
96+
return IntStream.empty();
97+
}
98+
}
99+
83100
@Override
84101
public boolean equals(Object obj) {
85102
if (obj == this) {

jre/java/java/util/OptionalLong.java

+19-2
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@
1515
*/
1616
package java.util;
1717

18+
import static javaemul.internal.InternalPreconditions.checkCriticalElement;
19+
1820
import java.util.function.LongConsumer;
1921
import java.util.function.LongSupplier;
2022
import java.util.function.Supplier;
21-
22-
import static javaemul.internal.InternalPreconditions.checkCriticalElement;
23+
import java.util.stream.LongStream;
2324

2425
/**
2526
* See <a href="https://docs.oracle.com/javase/8/docs/api/java/util/OptionalLong.html">
@@ -65,6 +66,14 @@ public void ifPresent(LongConsumer consumer) {
6566
}
6667
}
6768

69+
public void ifPresentOrElse(LongConsumer action, Runnable emptyAction) {
70+
if (present) {
71+
action.accept(ref);
72+
} else {
73+
emptyAction.run();
74+
}
75+
}
76+
6877
public long orElse(long other) {
6978
return present ? ref : other;
7079
}
@@ -80,6 +89,14 @@ public <X extends Throwable> long orElseThrow(Supplier<X> exceptionSupplier) thr
8089
throw exceptionSupplier.get();
8190
}
8291

92+
public LongStream stream() {
93+
if (present) {
94+
return LongStream.of(ref);
95+
} else {
96+
return LongStream.empty();
97+
}
98+
}
99+
83100
@Override
84101
public boolean equals(Object obj) {
85102
if (obj == this) {

jre/javatests/com/google/j2cl/jre/EmulJava9Suite.java

+13-1
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,24 @@
1717

1818
import com.google.j2cl.jre.java9.util.ListTest;
1919
import com.google.j2cl.jre.java9.util.MapTest;
20+
import com.google.j2cl.jre.java9.util.OptionalDoubleTest;
21+
import com.google.j2cl.jre.java9.util.OptionalIntTest;
22+
import com.google.j2cl.jre.java9.util.OptionalLongTest;
23+
import com.google.j2cl.jre.java9.util.OptionalTest;
2024
import com.google.j2cl.jre.java9.util.SetTest;
2125
import org.junit.runner.RunWith;
2226
import org.junit.runners.Suite;
2327
import org.junit.runners.Suite.SuiteClasses;
2428

2529
/** Test JRE emulations. */
2630
@RunWith(Suite.class)
27-
@SuiteClasses({ListTest.class, SetTest.class, MapTest.class})
31+
@SuiteClasses({
32+
ListTest.class,
33+
MapTest.class,
34+
OptionalDoubleTest.class,
35+
OptionalIntTest.class,
36+
OptionalLongTest.class,
37+
OptionalTest.class,
38+
SetTest.class
39+
})
2840
public class EmulJava9Suite {}

jre/javatests/com/google/j2cl/jre/java8/util/OptionalDoubleTest.java

+18
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,24 @@ public void testIfPresent() {
108108
assertTrue("Consumer not executed", mutableFlag[0]);
109109
}
110110

111+
public void testIfPresentOrElse() {
112+
// empty case
113+
empty.ifPresentOrElse(
114+
(wrapped) -> fail("Empty Optional should not call non-empty consumer"),
115+
() -> mutableFlag[0] = true);
116+
assertTrue("Consumer not executed", mutableFlag[0]);
117+
118+
// non-empty case
119+
mutableFlag[0] = false;
120+
present.ifPresentOrElse(
121+
(wrapped) -> {
122+
assertEquals(REFERENCE, wrapped);
123+
mutableFlag[0] = true;
124+
},
125+
() -> fail("Non-Empty Optional should not call empty consumer"));
126+
assertTrue("Consumer not executed", mutableFlag[0]);
127+
}
128+
111129
public void testOrElse() {
112130
// empty case
113131
assertEquals(OTHER_REFERENCE, empty.orElse(OTHER_REFERENCE));

jre/javatests/com/google/j2cl/jre/java8/util/OptionalIntTest.java

+18
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,24 @@ public void testIfPresent() {
107107
assertTrue("Consumer not executed", mutableFlag[0]);
108108
}
109109

110+
public void testIfPresentOrElse() {
111+
// empty case
112+
empty.ifPresentOrElse(
113+
(wrapped) -> fail("Empty Optional should not call non-empty consumer"),
114+
() -> mutableFlag[0] = true);
115+
assertTrue("Consumer not executed", mutableFlag[0]);
116+
117+
// non-empty case
118+
mutableFlag[0] = false;
119+
present.ifPresentOrElse(
120+
(wrapped) -> {
121+
assertEquals(REFERENCE, wrapped);
122+
mutableFlag[0] = true;
123+
},
124+
() -> fail("Non-Empty Optional should not call empty consumer"));
125+
assertTrue("Consumer not executed", mutableFlag[0]);
126+
}
127+
110128
public void testOrElse() {
111129
// empty case
112130
assertEquals(OTHER_REFERENCE, empty.orElse(OTHER_REFERENCE));

jre/javatests/com/google/j2cl/jre/java8/util/OptionalLongTest.java

+18
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,24 @@ public void testIfPresent() {
107107
assertTrue("Consumer not executed", mutableFlag[0]);
108108
}
109109

110+
public void testIfPresentOrElse() {
111+
// empty case
112+
empty.ifPresentOrElse(
113+
(wrapped) -> fail("Empty Optional should not call non-empty consumer"),
114+
() -> mutableFlag[0] = true);
115+
assertTrue("Consumer not executed", mutableFlag[0]);
116+
117+
// non-empty case
118+
mutableFlag[0] = false;
119+
present.ifPresentOrElse(
120+
(wrapped) -> {
121+
assertEquals(REFERENCE, wrapped);
122+
mutableFlag[0] = true;
123+
},
124+
() -> fail("Non-Empty Optional should not call empty consumer"));
125+
assertTrue("Consumer not executed", mutableFlag[0]);
126+
}
127+
110128
public void testOrElse() {
111129
// empty case
112130
assertEquals(OTHER_REFERENCE, empty.orElse(OTHER_REFERENCE));

jre/javatests/com/google/j2cl/jre/java8/util/OptionalTest.java

+5-6
Original file line numberDiff line numberDiff line change
@@ -141,21 +141,20 @@ public void testIfPresent() {
141141

142142
public void testIfPresentOrElse() {
143143
// empty case
144-
empty.ifPresentOrElse(wrapped -> fail("Empty Optional should not execute consumer"), () -> {});
144+
empty.ifPresentOrElse(
145+
(wrapped) -> fail("Empty Optional should not call non-empty consumer"),
146+
() -> mutableFlag[0] = true);
147+
assertTrue("Consumer not executed", mutableFlag[0]);
145148

146149
// non-empty case
150+
mutableFlag[0] = false;
147151
present.ifPresentOrElse(
148152
(wrapped) -> {
149153
assertSame(REFERENCE, wrapped);
150154
mutableFlag[0] = true;
151155
},
152156
() -> fail("Non-Empty Optional should not call empty consumer"));
153157
assertTrue("Consumer not executed", mutableFlag[0]);
154-
mutableFlag[0] = false;
155-
empty.ifPresentOrElse(
156-
(wrapped) -> fail("Empty Optional should not call non-empty consumer"),
157-
() -> mutableFlag[0] = true);
158-
assertTrue("Consumer not executed", mutableFlag[0]);
159158
}
160159

161160
public void testFilter() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright 2024 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
5+
* use this file except in compliance with the License. You may obtain a copy of
6+
* the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations under
14+
* the License.
15+
*/
16+
package com.google.j2cl.jre.java9.util;
17+
18+
import com.google.j2cl.jre.java.util.EmulTestBase;
19+
import java.util.OptionalDouble;
20+
import java.util.stream.Stream;
21+
22+
/** Tests for java.util.OptionalDouble Java 9 API emulation. */
23+
public class OptionalDoubleTest extends EmulTestBase {
24+
25+
public void testStream() {
26+
assertEquals(0, OptionalDouble.empty().stream().count());
27+
assertEquals(1, OptionalDouble.of(10.0).stream().count());
28+
29+
assertEquals(
30+
new double[] {10.0, 100.0, 1000.0},
31+
Stream.of(
32+
OptionalDouble.of(10.0),
33+
OptionalDouble.empty(),
34+
OptionalDouble.of(100.0),
35+
OptionalDouble.of(1000.0))
36+
.flatMapToDouble(OptionalDouble::stream)
37+
.toArray());
38+
}
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright 2024 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
5+
* use this file except in compliance with the License. You may obtain a copy of
6+
* the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations under
14+
* the License.
15+
*/
16+
package com.google.j2cl.jre.java9.util;
17+
18+
import com.google.j2cl.jre.java.util.EmulTestBase;
19+
import java.util.OptionalInt;
20+
import java.util.stream.Stream;
21+
22+
/** Tests for java.util.OptionalInt Java 9 API emulation. */
23+
public class OptionalIntTest extends EmulTestBase {
24+
25+
public void testStream() {
26+
assertEquals(0, OptionalInt.empty().stream().count());
27+
assertEquals(1, OptionalInt.of(10).stream().count());
28+
29+
assertEquals(
30+
new int[] {10, 100, 1000},
31+
Stream.of(
32+
OptionalInt.of(10), OptionalInt.empty(), OptionalInt.of(100), OptionalInt.of(1000))
33+
.flatMapToInt(OptionalInt::stream)
34+
.toArray());
35+
}
36+
}

0 commit comments

Comments
 (0)