OptionalDouble, OptionalInt, and OptionalLong
Optional class is introduced in Java 8 as a container object which may or may not contain a non-null value. Together with Optional, there are three more container classes that added to contain primitive values of double, int, and long. They are:
- OptionalDouble: A container object which may or may not contain a double value.
- OptionalInt: A container object which may or may not contain an int value.
- OptionalLong: A container object which may or may not contain a long value.
Same as Optional, these three classes also evolving from their release in Java 8, until now (Java 11). Additional methods are added, which is share similarity with their sister class, Optional. For references, please check previous article about Java 8 Optional and it's current features.
This article we give you an introduction and guides about OptionalDouble, OptionalInt, and OptionalLong
OptionalDouble Example
OptionalDouble is a container object which may or may not contain a double value. If a value is present, isPresent() returns true. If no value is present, the object is considered empty and isPresent() returns false.
The double data type is a double-precision 64-bit IEEE 754 floating point. Its range of values is specified in the Floating-Point Types, Formats, and Values section of the Java Language Specification. For decimal values, this data type is generally the default choice. This data type should never be used for precise values, such as currency.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.OptionalDouble;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class OptionalDoubleExample {
public static void main(String[] args) {
OptionalDouble optionalDouble = OptionalDouble.of(8.88);
System.out.println(8.88 == optionalDouble.getAsDouble());
optionalDouble = OptionalDouble.empty();
System.out.println(optionalDouble.orElse(9.99));
List<OptionalDouble> doubles = Arrays.asList(
OptionalDouble.of(1.01),
OptionalDouble.of(2.12),
OptionalDouble.of(8.88),
OptionalDouble.of(9.99)
);
List<Double> list1 = doubles.stream()
.map(OptionalDouble::getAsDouble)
.collect(Collectors.toList());
System.out.println(list1);
List<OptionalDouble> otherDoubles = new ArrayList<>();
otherDoubles.addAll(doubles);
otherDoubles.addAll(Arrays.asList(OptionalDouble.empty()));
List<Double> list2 = otherDoubles.stream()
.filter(OptionalDouble::isPresent)
.filter(o -> o.getAsDouble() > 5.05)
.map(OptionalDouble::getAsDouble)
.collect(Collectors.toList());
System.out.println(list2);
List<String> list3 = otherDoubles.stream()
.flatMap(o -> o.isPresent() ? Stream.of(o.getAsDouble()) : Stream.of(Double.valueOf("5.05")))
.map(d -> Double.toString(d))
.collect(Collectors.toList());
System.out.println(list3);
Double d = doubles.stream().findFirst()
.orElse(OptionalDouble.of(5.05)).getAsDouble();
System.out.println(d);
}
}
true 9.99 [1.01, 2.12, 8.88, 9.99] [8.88, 9.99] [1.01, 2.12, 8.88, 9.99, 5.05] 1.01
OptionalInt Example
OptionalInt is a container object which may or may not contain an int value. If a value is present, isPresent() returns true. If no value is present, the object is considered empty and isPresent() returns false.
By default, the int data type is a 32-bit signed two's complement integer, which has a minimum value of -231 and a maximum value of 231-1. In Java SE 8 and later, you can use the int data type to represent an unsigned 32-bit integer, which has a minimum value of 0 and a maximum value of 232-1.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.OptionalInt;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class OptionalIntExample {
public static void main(String[] args) {
OptionalInt optionalInt = OptionalInt.of(888);
System.out.println(888 == optionalInt.getAsInt());
optionalInt = OptionalInt.empty();
System.out.println(optionalInt.orElse(999));
List<OptionalInt> integers = Arrays.asList(
OptionalInt.of(101),
OptionalInt.of(212),
OptionalInt.of(888),
OptionalInt.of(999)
);
List<Integer> list1 = integers.stream()
.map(OptionalInt::getAsInt)
.collect(Collectors.toList());
System.out.println(list1);
List<OptionalInt> otherInts = new ArrayList<>();
otherInts.addAll(integers);
otherInts.addAll(Arrays.asList(OptionalInt.empty()));
List<Integer> list2 = otherInts.stream()
.filter(OptionalInt::isPresent)
.filter(o -> o.getAsInt() > 500)
.map(OptionalInt::getAsInt)
.collect(Collectors.toList());
System.out.println(list2);
List<String> list3 = otherInts.stream()
.flatMap(o -> o.isPresent() ? Stream.of(o.getAsInt()) : Stream.of(Integer.valueOf("500")))
.map(i -> Integer.toString(i))
.collect(Collectors.toList());
System.out.println(list3);
Integer i = integers.stream().findFirst()
.orElse(OptionalInt.of(500)).getAsInt();
System.out.println(i);
}
}
true 999 [101, 212, 888, 999] [888, 999] [101, 212, 888, 999, 500] 101
OptionalLong Example
OptionalLong is a container object which may or may not contain a long value. If a value is present, isPresent() returns true. If no value is present, the object is considered empty andisPresent() returns false.
The long data type is a 64-bit two's complement integer. The signed long has a minimum value of -263 and a maximum value of 263-1. In Java SE 8 and later, you can use the long data type to represent an unsigned 64-bit long, which has a minimum value of 0 and a maximum value of 264-1. Use this data type when you need a range of values wider than those provided by int.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.OptionalLong;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class OptionalLongExample {
public static void main(String[] args) {
OptionalLong optionalLong = OptionalLong.of(2147483648l);
System.out.println(2147483648l == optionalLong.getAsLong());
optionalLong = OptionalLong.empty();
System.out.println(optionalLong.orElse(2147484646l));
List<OptionalLong> longs = Arrays.asList(
OptionalLong.of(2147483748l),
OptionalLong.of(2147483859l),
OptionalLong.of(2147484535l),
OptionalLong.of(2147484646l)
);
List<Long> list1 = longs.stream()
.map(OptionalLong::getAsLong)
.collect(Collectors.toList());
System.out.println(list1);
List<OptionalLong> otherLongs = new ArrayList<>();
otherLongs.addAll(longs);
otherLongs.addAll(Arrays.asList(OptionalLong.empty()));
List<Long> list2 = otherLongs.stream()
.filter(OptionalLong::isPresent)
.filter(o -> o.getAsLong() > 2147484147l)
.map(OptionalLong::getAsLong)
.collect(Collectors.toList());
System.out.println(list2);
List<String> list3 = otherLongs.stream()
.flatMap(o -> o.isPresent() ? Stream.of(o.getAsLong()) : Stream.of(Long.MAX_VALUE))
.map(l -> Long.toString(l))
.collect(Collectors.toList());
System.out.println(list3);
Long l = longs.stream().findFirst()
.orElse(OptionalLong.of(Long.MAX_VALUE)).getAsLong();
System.out.println(l);
}
}
true 2147484646 [2147483748, 2147483859, 2147484535, 2147484646] [2147484535, 2147484646] [2147483748, 2147483859, 2147484535, 2147484646, 9223372036854775807] 2147483748
Conclusion
Java Optional, and its three Optional for primitive friends, is very useful when used as a return type from an operation where previously you might have returned null.