How can I map an optional into a primitive optional? - java

I know I can map an Optional into an another wrapper type optional.
Optional<Long> millis(Date date) {
return ofNullable(date).map(Date::getTime);
}
How can I map or flatMap into an OptionalLong?
OptionalLong millis(Date date) {
}
I tried but had no luck.
ofNullable(value).flatMap(v -> { // javac has never liked me
return OptionalLong.of(v.getTime());
});

You can use map to get an Optional<OptionalLong> then orElse to remove the outer Optional like this:
OptionalLong millis(Date date) {
return Optional.ofNullable(date).map(Date::getTime)
.map(OptionalLong::of).orElse(OptionalLong.empty());
}
Another (shorter in this case) way is to use the ternary operator instead:
OptionalLong millis(Date date) {
return date == null ? OptionalLong.empty() : OptionalLong.of(date.getTime());
}
Or if you already have the Optional<Long>:
OptionalLong toOptionalLong(Optional<Long> o) {
return o.map(OptionalLong::of).orElse(OptionalLong.empty());
}
OptionalLong toOptionalLong(Optional<Long> o) {
return o.isPresent() ? OptionalLong.of(o.get()) : OptionalLong.empty();
}

Keep in mind that you will take a performance hit in this scenario if you involve Optional<Long> in any way. From Joshua Bloch's Effective Java, 3rd Edition:
"Returning an optional that contains a boxed primitive type is prohibitively expensive compared to returning the primitive type because the optional has two levels of boxing instead of zero. [...] Therefore you should never return an optional of a boxed primitive type, with the possible exception of the "minor primitive types," Boolean, Byte, Character, Short, and Float"
There is no reason to involve Optional here. The best solution is to do the null check yourself, and then return an OptionalLong, e.g.
OptionalLong millis(Date date) {
return date == null ? OptionalLong.empty() : OptionalLong.of(date.getTime());
}

Using the StreamEx library
OptionalLong millis(final Date date) {
return StreamEx.ofNullable(date).mapToLong(Date::getTime).findAny();
}
or
OptionalLong toLong(Optional<Long> o) {
return StreamEx.of(o).mapToLong(Long::longValue).findAny();
}
or
OptionalLong toLong(final Optional<Date> o) {
return StreamEx.of(o).mapToLong(Date::getTime).findAny();
}

I would implement it as follows:
OptionalLong toOptionalLong(Optional<Long> optionalValue) {
return optionalValue.map(OptionalLong::of).orElseGet(OptionalLong::empty);
}
The function OptionalLong::empty is called if and only if the optionalValue is empty.
But I'm not sure I would cast an Optional<Long> into an OptionalLong unless I'm really obliged to. As said in former answers, using a ternary operator is probably a better approach in this case.

Related

How to interpret and use Java 1.8 Optional Class

This is a code segment from another StackOverflow question:
#Override
public String convertToDatabaseColumn(final UUID entityValue) {
return ofNullable(entityValue).map(entityUuid -> entityUuid.toString()).orElse(null);
}
I am really struggling to understand the use of the Optional class. Is the return code saying "return the value of the map (a String) or NULL if that fails?
How can return be acting on a method rather than a Class - that is Optional.ofNullable()?
This is a really bad use of Optional. In fact the java developers themself say that optional should not be used in such cases, but only as a return argument from a method. More can be read in this great answer: Is it good practice to use optional as an attribute in a class
The code can be rewritten to this:
#Override
public String convertToDatabaseColumn(final UUID entityValue) {
return entityValue == null ? null : entityValue.toString();
}
Is the return code saying "return the value of the map (a String) or NULL if that fails?
Yes. You can check the documentation of Optional here. It tells you exactly what map and orElse do.
How can return be acting on a method rather than a Class - that is Optional.ofNullable()?
You are not returning the method. You are returning the return value of a method. Look at this simple example:
int myMethod() {
return foo();
}
int foo() { return 10; }
See? I am not returning foo the method, I am returning 10, the return value of foo.
Note that it is possible to return methods, with functional interfaces.
In this case, you are returning the return value of the last method in the method chain, orElse. ofNullable creates an Optional<T>, then map is called on this object and returns a new Optional<T>, then orElse is called and its return value is returned.
Lets go step by step:
ofNullable(entityValue)
creates an Optional of the incoming parameter (which is allowed to be null, using of() a NPE gets thrown for null input)
.map(entityUuid -> entityUuid.toString())
Then you pick the actual value, and invoke toString() on that value ... which only happens if entityValue isn't null. If it is null, the result comes from orElse(null).
In the end, the result of that operation on the Optional is returned as result of the method.
The above code is nothing but a glorified version of
if (entityValue == null) return null;
return entityValue.toString();
Optionals have their place in Java, but your example isn't a good one.
It doesn't help readability a bit, and you are not alone with wondering "what is going on here".
The code can be turn like this :
public String convertToDatabaseColumn(final UUID entityValue) {
if(entityValue==null){
return null;
}else{
return entityValue.toString();
}
}
Your initial code have two statements:
Optional.ofNullable(entityValue): create an Optional Object to say the value can be present or not.
.map(entityUuid -> entityUuid.toString()).orElse(null); you apply some operation to your Optional object, return a string of it or null.
This will avoid a null pointer exception in a more elegant way.
Optional.ofNullable(T value):
Returns an Optional describing the specified value, if non-null, otherwise returns an empty Optional.
Optional.orElse(null)
Return the value if present, otherwise return null.
Follow this link

Tranforming Guava Optional with function that might return null

TL;DR
What is the best (i.e. most compact/readable) way of transforming a Guava Optional, using a function that might return null? (So that in that case, we should get an Optional.absent(), instead of an NPE.)
Bonus question: is there an advantage, in the Guava way, namely to throw NPE, if the transformer function returns null? (Instead of converting it to Optional.absent(), like in case of Java 8 Optionals.) Or is it just a shortcoming of the design?
Problem
As per the documentation of Guava Optional.transform:
Comparison to java.util.Optional: this method is similar to Java 8's
Optional.map, except when function returns null. In this case this
method throws an exception, whereas the Java 8 method returns
Optional.absent().
Example
The following function is common to both examples:
public String methodThatMighReturnNull(boolean returnNull, Integer input) {
return returnNull ? null : String.valueOf(input);
}
With Java 8 this does not throw an NPE, but returns an empty Optional:
Optional<Integer> input = Optional.of(42);
Optional<String> result = input.map(new Function<Integer, String>() {
public String apply(Integer input) {
return methodThatMighReturnNull(true, input);
}
});
The following, similar code with Guava throws an NPE:
Optional<Integer> input = Optional.of(42);
Optional<String> result = input.transform(new Function<Integer, String>() {
public String apply(Integer input) {
return methodThatMighReturnNull(true, input);
}
});
Possible alternatives
I have found/considered some alternatives, but, as described below, all are problematic:
Wrap the return value into an Optional. Problem: too cumbersome, more difficult to read;
Optional<Integer> input = Optional.of(42);
Optional<String> result = input.transform(new Function<Integer, Optional<String>>() {
public Optional<String> apply(Integer input) {
return fromNullable(methodThatMighReturnNull(true, input));
}
}).get();
Use if/else, by checking ifPresent. Problem: kind of kills the point of Optional. (We could just use the reference and check against null instead.)
Optional<Integer> input = Optional.of(42);
Optional<String> result;
if (input.isPresent()) {
result = fromNullable(methodThatMighReturnNull(true, input.get()));
} else {
result = Optional.absent();
}
Just applying the function, and wrapping it in fromNullable. (As found on GitHub, where the same problem was seemingly already brought up.) Problem: this is slightly different, than the original example. In this case, methodThatMighReturnNull could end up receiving null, while in the original case this was impossible.
Optional<Integer> input = Optional.of(42);
Optional<String> result;
result = fromNullable(new Function<Integer, String>() {
public String apply(Integer input) {
return methodThatMighReturnNull(true, input);
}
}.apply(input.orNull()));
Apart from the alternatives you listed in your question, here are two other possibilities:
If you are on Java 8 or higher, starting from Guava 21.0, you have the Optional.toJavaUtil() instance method, which transforms your Guava Optional instance into a java.util.Optional one, and also the Optional.fromJavaUtil static method, which creates a Guava Optional instance from a java.util.Optional one.
You can use them to let java.util.Optional take a function that invokes your method in its Optional.map method, applying its own semantics (it won't throw NullPointerException if the function returns null, but an empty java.util.Optional instead). Then, if you need it, convert this mapped java.util.Optional back to a Guava Optional via the Optional.fromJavaUtil method.
Here's the code that shows this approach:
Optional<Integer> input = Optional.of(42);
java.util.Optional<String> temp = input.toJavaUtil()
.map(i -> methodThatMighReturnNull(true, i));
Optional<String> result = Optional.fromJavaUtil(temp);
If you are not in Java 8 or higher yet (or if you are but don't like the previous approach), I would go for a variant of your 2nd alternative. For this, I would implement a transformNullSafe method with the semantics you need:
public static <T, R> Optional<R> transformNullSafe(
Optional<T> optional,
Function<T, R> function) {
if (optional.isPresent()) {
return Optional.fromNullable(function.apply(optional.get()));
} else {
return Optional.absent();
}
}
Usage:
Optional<Integer> input = Optional.of(42);
Optional<String> result = transformNullSafe(
input,
new Function<Integer, String>() {
public String apply(Integer i) {
return methodThatMighReturnNull(true, i);
}
});

How to convert an Optional to an OptionalInt?

I have an Optional that I want to "convert" to an OptionalInt, but there doesn't seem to be a simple way to do this.
Here's what I want to do (contrived example):
public OptionalInt getInt() {
return Optional.ofNullable(someString).filter(s -> s.matches("\\d+")).mapToInt(Integer::parseInt);
}
However, there's no mapToInt() method for Optional.
The best I could come up with is:
return Optional.ofNullable(someString)
.filter(s -> s.matches("\\d+"))
.map(s -> OptionalInt.of(Integer.parseInt(s)))
.orElse(OptionalInt.empty());
but that seems inelegant.
Am I missing something from the JDK that can make the conversion more elegant?
While the code isn't more readable than an ordinary conditional expression, there is a simple solution:
public OptionalInt getInt() {
return Stream.of(someString).filter(s -> s != null && s.matches("\\d+"))
.mapToInt(Integer::parseInt).findAny();
}
With Java 9, you could use
public OptionalInt getInt() {
return Stream.ofNullable(someString).filter(s -> s.matches("\\d+"))
.mapToInt(Integer::parseInt).findAny();
}
As said, neither is more readable than an ordinary conditional expression, but I think, it still looks better than using mapOrElseGet (and the first variant doesn't need Java 9.
No, there's no way to do it in more elegant way using standard Java API. I asked Paul Sandoz about adding mapToInt, etc., here's his answer:
Me:
Isn't it a good idea to provide also a way
to transfer between Optional types like mapToInt, mapToObj, etc.,
like it's done in Stream API?
Paul:
I don’t wanna go there, my response is transform Optional* into a *Stream. An argument for adding mapOrElseGet (notice that the primitive variants return U) is that other functionality can be composed from it.
So you will likely to have in Java-9:
return Optional.of(someString).filter(s -> s.matches("\\d+"))
.mapOrElseGet(s -> OptionalInt.of(Integer.parseInt(s)), OptionalInt::empty);
But nothing more.
That's because JDK authors insist that the Optional class and its primitive friends (especially primitive friends) should not be widely used, it's just a convenient way to perform a limited set of operations on the return value of methods which may return "the absence of the value". Also primitive optionals are designed for performance improvement, but actually it's much less significant than with streams, so using Optional<Integer> is also fine. With Valhalla project you will be able to use Optional<int> and OptionalInt will become unnecessary.
In your particular case the better way to do it is using ternary operator:
return someString != null && someString.matches("\\d+") ?
OptionalInt.of(Integer.parseInt(someString)) : OptionalInt.empty();
I assume that you want to return the OptionalInt from the method. Otherwise it's even more questionable why you would need it.
If you have any object and not just a String, you can temporarily go through a Stream:
public static <T> OptionalInt toOptionalInt(Optional<T> optional, ToIntFunction<? super T> func) {
return optional.map(Stream::of).orElseGet(Stream::empty)
.mapToInt(func)
.findFirst();
}
This solution has the advantage to be a one-liner, meaning you can copy/paste the content of the method and just change func to whatever you want. The disadvantage is going through a Stream to achieve what you want. But if you want a generic one-liner, this is it.
If you want a utility method, you probably prefer to use the following:
public static <T> OptionalInt toOptionalInt(Optional<T> optional, ToIntFunction<? super T> func) {
if (optional.isPresent()) {
return OptionalInt.of(func.applyAsInt(optional.get()));
} else {
return OptionalInt.empty();
}
}
This is how I convert an Optional<String> to OptionalInt
OptionalInt lastSeenId = Optional.of("123").map(Integer::parseInt).map(OptionalInt::of).orElseGet(OptionalInt::empty);
Here's another option that doesn't need to use a Stream and avoids compiling regex every time:
private static final Predicate<String> IS_DIGITS = Pattern.compile("^\\d+$")
.asPredicate();
public OptionalInt getInt() {
return Optional.ofNullable(someString)
.filter(IS_DIGITS)
.map(Integer::valueOf)
.map(OptionalInt::of)
.orElseGet(OptionalInt::empty);
}
Note that you need to anchor the regex because asPredicate() uses find() instead of matches().
Or if you're using Guava, you can eliminate the regex entirely and use their Ints class:
public OptionalInt getInt() {
return Optional.ofNullable(someString)
.map(Ints::tryParse)
.map(OptionalInt::of)
.orElseGet(OptionalInt::empty);
}

Good way to convert Optional<Integer> to Optional<Long>

I am trying to find a clean and code-efficient way to convert Optional<Integer> to Optional<Long>. I am working in Java 7 with Guava.
So in one place in the code I have an optional integer created
Optional<Integer> optionalInt = Optional.fromNullable(someInt);
And in another area I need it as an optional long.
The nicest thing I could come up with is this:
Optional<Long> optionalLong = optionalInt.transform(new Function<Integer, Long>() {
#Override
public Long apply(Integer inputInt) {
if (inputInt != null)
return inputInt.longValue();
else
return null;
}
});
But this is cumbersome, especially if you consider how easy it was to cast the type when I was using primitive types.
Any good ideas out there?
TL;DR: In Java 7, No.
Sadly this is the best Java 7 has to offer in terms of support for functions.
I would just say that transform will never be called with null so you can do:
Optional<Long> optionalLong = optionalInt.transform(new Function<Integer, Long>() {
#Override
public Long apply(Integer inputInt) {
return inputInt.longValue();
}
});
From the documentation:
If the instance is present, it is transformed with the given
Function; otherwise, absent() is returned. If the function returns
null, a NullPointerException is thrown.
So never return null from a Function passed to transform.
If you reuse this a lot, then you could use the enum singleton pattern:
public enum IntToLong implements Function<Integer, Long> {
INSTANCE;
#Override
public Long apply(Integer input) {
return input.longValue();
}
}
Then:
optionalInt.transform(IntToLong.INSTANCE);
This obviously reduces the code at the call site at the expense of having extra classes in the code base - something I wouldn't be too worried about.
close to the cast:
Optional<Long> optionalLong = Optional.fromNullable(optionalInt.isPresent() ?
optionalInt.get().longValue() : null);
basically this avoids the overhead of invoking transform. Invoking isPresent could be simplified to checking the value for null directly.

Does Java allow nullable types?

In C# I can a variable to allow nulls with the question mark. I want to have a true/false/null result. I want to have it set to null by default. The boolean will be set to true/false by a test result, but sometimes the test is not run and a boolean is default to false in java, so 3rd option to test against would be nice.
c# example:
bool? bPassed = null;
Does java have anything similar to this?
No.
Instead, you can use the boxed Boolean class (which is an ordinary class rather a primitive type), or a three-valued enum.
you can use :
Boolean b = null;
that is, the java.lang.Boolean object in Java.
And then also set true or false by a simple assignment:
Boolean b = true;
or
Boolean b = false;
No, in java primitives cannot have null value, if you want this feature, you might want to use Boolean instead.
Sure you can go with Boolean, but to make it more obvious that your type can have "value" or "no value", it's very easy to make a wrapper class that does more or less what ? types do in C#:
public class Nullable<T> {
private T value;
public Nullable() { value = null; }
public Nullable(T init) { value = init; }
public void set(T v) { value = v; }
public boolean hasValue() { return value != null; }
public T value() { return value; }
public T valueOrDefault(T defaultValue) { return value == null ? defaultValue : value; }
}
Then you can use it like this:
private Nullable<Integer> myInt = new Nullable<>();
...
myInt.set(5);
...
if (myInt.hasValue())
....
int foo = myInt.valueOrDefault(10);
Note that something like this is standard since Java8: the Optional class.
https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html
Yes you can.
To do this sort of thing, java has a wrapper class for every primitive type. If you make your variable an instance of the wrapper class, it can be assigned null just like any normal variable.
Instead of:
boolean myval;
... you can use:
Boolean myval = null;
You can assign it like this:
myval = new Boolean(true);
... And get its primitive value out like this:
if (myval.booleanValue() == false) {
// ...
}
Every primitive type (int, boolean, float, ...) has a corresponding wrapper type (Integer, Boolean, Float, ...).
Java's autoboxing feature allows the compiler to sometimes automatically coerce the wrapper type into its primitive value and vice versa. But, you can always do it manually if the compiler can't figure it out.
In Java, primitive types can't be null. However, you could use Boolean and friends.
No but you may use Boolean class instead of primitive boolean type to put null
If you are using object, it allows null
If you are using Primitive Data Types, it does not allow null
That the reason Java has Wrapper Class

Categories