I understand you can't return from a ifPresent() so this example does not work:
public boolean checkSomethingIfPresent() {
mightReturnAString().ifPresent((item) -> {
if (item.equals("something")) {
// Do some other stuff like use "something" in API calls
return true; // Does not compile
}
});
return false;
}
Where mightReturnAString() could return a valid string or an empty optional. What I have done that works is:
public boolean checkSomethingIsPresent() {
Optional<String> result = mightReturnAString();
if (result.isPresent()) {
String item = result.get();
if (item.equals("something") {
// Do some other stuff like use "something" in API calls
return true;
}
}
return false;
}
which is longer and does not feel much different to just checking for nulls in the first place. I feel like there must be a more succinct way using Optional.
I think all you're looking for is simply filter and check for the presence then:
return result.filter(a -> a.equals("something")).isPresent();
How about mapping to a boolean?
public boolean checkSomethingIfPresent() {
return mightReturnAString().map(item -> {
if (item.equals("something")) {
// Do some other stuff like use "something" in API calls
return true; // Does not compile
}
return false; // or null
}).orElse(false);
}
While #nullpointer and #Ravindra showed how to merge the Optional with another condition, you'll have to do a bit more to be able to call APIs and do other stuff as you asked in the question. The following looks quite readable and concise in my opinion:
private static boolean checkSomethingIfPresent() {
Optional<String> str = mightReturnAString();
if (str.filter(s -> s.equals("something")).isPresent()) {
//call APIs here using str.get()
return true;
}
return false;
}
A better design would be to chain methods:
private static void checkSomethingIfPresent() {
mightReturnFilteredString().ifPresent(s -> {
//call APIs here
});
}
private static Optional<String> mightReturnFilteredString() {
return mightReturnAString().filter(s -> s.equals("something"));
}
private static Optional<String> mightReturnAString() {
return Optional.of("something");
}
The ideal solution is “command-query separation”: Make one method (command) for doing something with the string if it is present. And another method (query) to tell you whether it was there.
However, we don’t live an ideal world, and perfect solutions are never possible. If in your situation you cannot separate command and query, my taste is for the idea already presented by shmosel: map to a boolean. As a detail I would use filter rather than the inner if statement:
public boolean checkSomethingIfPresent() {
return mightReturnAString().filter(item -> item.equals("something"))
.map(item -> {
// Do some other stuff like use "something" in API calls
return true; // (compiles)
})
.orElse(false);
}
What I don’t like about it is that the call chain has a side effect, which is not normally expected except from ifPresent and ifPresentOrElse (and orElseThrow, of course).
If we insist on using ifPresent to make the side effect clearer, that is possible:
AtomicBoolean result = new AtomicBoolean(false);
mightReturnAString().filter(item -> item.equals("something"))
.ifPresent(item -> {
// Do some other stuff like use "something" in API calls
result.set(true);
});
return result.get();
I use AtomicBoolean as a container for the result since we would not be allowed to assign to a primitive boolean from within the lambda. We don’t need its atomicity, but it doesn’t harm either.
Link: Command–query separation on Wikipedia
By the way if you really want to get value from Optional, use:
Optional<User> user = service.getCurrentUset();
return user.map(User::getId);
I want my code to repeat a certain asynchronous operation until this operation is successful (i.e. until it returns true).
At the moment I'm using the following workaround:
Supplier<Observable<Boolean>> myOperation = () -> {
// do something useful and return 'true' if it was successful
// NOTE: GENERATING A RANDOM NUMBER IS JUST AN EXAMPLE HERE
// I WANT TO RUN AN ASYNCHRONOUS OPERATION (LIKE PINGING A SERVER
// OR THE LIKE) AND RETRY IT UNTIL IT SUCCEEDS.
System.out.println("Try");
return Observable.just(Math.random() > 0.9);
};
final Throwable retry = new IllegalStateException();
Observable.<Boolean>create(subscriber -> {
myOperation.get().subscribe(subscriber);
}).flatMap(b -> b ? Observable.just(b) : Observable.error(retry))
.retryWhen(exceptions -> exceptions.flatMap(exception -> {
if (exception == retry) {
return Observable.timer(1, TimeUnit.SECONDS);
}
return Observable.error(exception);
}))
.toBlocking()
.forEach(b -> {
System.out.println("Connected.");
});
It works well and prints out something like this:
Try
Try
...
Try
Connected.
The code does what I want, but it doesn't look very elegant. I'm sure there must be a better way. Maybe by using a custom Operator?
Does anybody know how to achieve the same thing in RxJava but in a more readable manner and without the artificial Throwable?
Not enough time, so this is going to be by memory...
public class Randomizer implements Iterable<Double>, Iterator<Double> {
public Iterator<Double> getIterator() {return this;}
public boolean hasNext() {return true;}
public Double next() {return Math.random();}
}
...
Observable.from(new Randomizer())
.takeWhile(value -> value < 0.99);
// or takeUntil(value -> value > 0.99); can't remember their differences.
OTOH if you need to do something more complex, look into Observable.defer() and / or a BehaviorSubject.
Edit: Now there's a bit more time to read your post, you could try something like this:
Observable.defer(() -> createConnectionObservable())
.retry((count, err) -> {
if(count>9) return false;
if(!(err instanceof IOException)) return false;
return true;
})
Keep in mind that if you use Retrofit you shouldn't need defer(), as retrofit will re-initiate the call when a new subscription happens.
In Java 8, I want to do something to an Optional object if it is present, and do another thing if it is not present.
if (opt.isPresent()) {
System.out.println("found");
} else {
System.out.println("Not found");
}
This is not a 'functional style', though.
Optional has an ifPresent() method, but I am unable to chain an orElse() method.
Thus, I cannot write:
opt.ifPresent( x -> System.out.println("found " + x))
.orElse( System.out.println("NOT FOUND"));
In reply to #assylias, I don't think Optional.map() works for the following case:
opt.map( o -> {
System.out.println("while opt is present...");
o.setProperty(xxx);
dao.update(o);
return null;
}).orElseGet( () -> {
System.out.println("create new obj");
dao.save(new obj);
return null;
});
In this case, when opt is present, I update its property and save to the database. When it is not available, I create a new obj and save to the database.
Note in the two lambdas I have to return null.
But when opt is present, both lambdas will be executed. obj will be updated, and a new object will be saved to the database . This is because of the return null in the first lambda. And orElseGet() will continue to execute.
If you are using Java 9+, you can use ifPresentOrElse() method:
opt.ifPresentOrElse(
value -> System.out.println("Found: " + value),
() -> System.out.println("Not found")
);
For me the answer of #Dane White is OK, first I did not like using Runnable but I could not find any alternatives.
Here another implementation I preferred more:
public class OptionalConsumer<T> {
private Optional<T> optional;
private OptionalConsumer(Optional<T> optional) {
this.optional = optional;
}
public static <T> OptionalConsumer<T> of(Optional<T> optional) {
return new OptionalConsumer<>(optional);
}
public OptionalConsumer<T> ifPresent(Consumer<T> c) {
optional.ifPresent(c);
return this;
}
public OptionalConsumer<T> ifNotPresent(Runnable r) {
if (!optional.isPresent()) {
r.run();
}
return this;
}
}
Then:
Optional<Any> o = Optional.of(...);
OptionalConsumer.of(o).ifPresent(s -> System.out.println("isPresent " + s))
.ifNotPresent(() -> System.out.println("! isPresent"));
Update 1:
the above solution for the traditional way of development when you have the value and want to process it but what if I want to define the functionality and the execution will be then, check below enhancement;
public class OptionalConsumer<T> implements Consumer<Optional<T>> {
private final Consumer<T> c;
private final Runnable r;
public OptionalConsumer(Consumer<T> c, Runnable r) {
super();
this.c = c;
this.r = r;
}
public static <T> OptionalConsumer<T> of(Consumer<T> c, Runnable r) {
return new OptionalConsumer(c, r);
}
#Override
public void accept(Optional<T> t) {
if (t.isPresent()) {
c.accept(t.get());
}
else {
r.run();
}
}
Then could be used as:
Consumer<Optional<Integer>> c = OptionalConsumer.of(
System.out::println,
() -> System.out.println("Not fit")
);
IntStream.range(0, 100)
.boxed()
.map(i -> Optional.of(i)
.filter(j -> j % 2 == 0))
.forEach(c);
In this new code you have 3 things:
can define the functionality before the existing of an object easy.
not creating object reference for each Optional, only one, you have so less memory than less GC.
it is implementing consumer for better usage with other components.
By the way, now its name is more descriptive it is actually Consumer<Optional<?>>
Java 9 introduces
ifPresentOrElse if a value is present, performs the given action with the value, otherwise performs the given empty-based action.
See excellent Optional in Java 8 cheat sheet.
It provides all answers for most use cases.
Short summary below
ifPresent() - do something when Optional is set
opt.ifPresent(x -> print(x));
opt.ifPresent(this::print);
filter() - reject (filter out) certain Optional values.
opt.filter(x -> x.contains("ab")).ifPresent(this::print);
map() - transform value if present
opt.map(String::trim).filter(t -> t.length() > 1).ifPresent(this::print);
orElse()/orElseGet() - turning empty Optional to default T
int len = opt.map(String::length).orElse(-1);
int len = opt.
map(String::length).
orElseGet(() -> slowDefault()); //orElseGet(this::slowDefault)
orElseThrow() - lazily throw exceptions on empty Optional
opt.
filter(s -> !s.isEmpty()).
map(s -> s.charAt(0)).
orElseThrow(IllegalArgumentException::new);
An alternative is:
System.out.println(opt.map(o -> "Found")
.orElse("Not found"));
I don't think it improves readability though.
Or as Marko suggested, use a ternary operator:
System.out.println(opt.isPresent() ? "Found" : "Not found");
Another solution would be to use higher-order functions as follows
opt.<Runnable>map(value -> () -> System.out.println("Found " + value))
.orElse(() -> System.out.println("Not Found"))
.run();
There isn't a great way to do it out of the box. If you want to be using your cleaner syntax on a regular basis, then you can create a utility class to help out:
public class OptionalEx {
private boolean isPresent;
private OptionalEx(boolean isPresent) {
this.isPresent = isPresent;
}
public void orElse(Runnable runner) {
if (!isPresent) {
runner.run();
}
}
public static <T> OptionalEx ifPresent(Optional<T> opt, Consumer<? super T> consumer) {
if (opt.isPresent()) {
consumer.accept(opt.get());
return new OptionalEx(true);
}
return new OptionalEx(false);
}
}
Then you can use a static import elsewhere to get syntax that is close to what you're after:
import static com.example.OptionalEx.ifPresent;
ifPresent(opt, x -> System.out.println("found " + x))
.orElse(() -> System.out.println("NOT FOUND"));
If you can use only Java 8 or lower:
1) if you don't have spring-data the best way so far is:
opt.<Runnable>map(param -> () -> System.out.println(param))
.orElse(() -> System.out.println("no-param-specified"))
.run();
Now I know it's not so readable and even hard to understand for someone, but looks fine for me personally and I don't see another nice fluent way for this case.
2) if you're lucky enough and you can use spring-data the best way is
Optionals#ifPresentOrElse:
Optionals.ifPresentOrElse(opt, System.out::println,
() -> System.out.println("no-param-specified"));
If you can use Java 9, you should definitely go with:
opt.ifPresentOrElse(System.out::println,
() -> System.out.println("no-param-specified"));
You cannot call orElse after ifPresent, the reason is, orElse is called on an optiional but ifPresent returns void. So the best approach to achieve is ifPresentOrElse.
It could be like this:
op.ifPresentOrElse(
(value)
-> { System.out.println(
"Value is present, its: "
+ value); },
()
-> { System.out.println(
"Value is empty"); });
The described behavior can be achieved by using Vavr (formerly known as Javaslang), an object-functional library for Java 8+, that implements most of Scala constructs (being Scala a more expressive language with a way richer type system built on JVM). It is a very good library to add to your Java projects to write pure functional code.
Vavr provides the Option monad that provides functions to work with the Option type such as:
fold: to map the value of the option on both cases (defined/empty)
onEmpty: allows to execute a Runnable when option is empty
peek: allows to consume the value of the option (when defined).
and it is also Serializable on the contrary of Optional which means you can safely use it as method argument and instance member.
Option follows the monad laws at difference to the Java's Optional "pseudo-monad" and provides a richer API. And of course you can make it from a Java's Optional (and the other way around): Option.ofOptional(javaOptional) –Vavr is focused on interoperability.
Going to the example:
// AWESOME Vavr functional collections (immutable for the gread good :)
// fully convertible to Java's counterparts.
final Map<String, String> map = Map("key1", "value1", "key2", "value2");
final Option<String> opt = map.get("nonExistentKey"); // you're safe of null refs!
final String result = opt.fold(
() -> "Not found!!!", // Option is None
val -> "Found the value: " + val // Option is Some(val)
);
Moreover, all Vavr types are convertible to its Java counterparts, for the sake of the example: Optional javaOptional = opt.toJava(), very easy :) Of course the conversion also exists in the other way: Option option = Option.ofOptional(javaOptional).
N.B. Vavr offers a io.vavr.API class with a lot of convenient static methods =)
Further reading
Null reference, the billion dollar mistake
N.B. This is only a very little example of what Vavr offers (pattern matching, streams a.k.a. lazy evaluated lists, monadic types, immutable collections,...).
The problem here:
optional
.map(object -> {
System.out.println("If present.");
return null;
})
.orElseGet( () -> {
System.out.println("If empty.");
return null;
});
Is that map() converts the null returned by the first function to empty(); it then returns empty(). As it returns empty(), it prompts the invocation of the second function. Note that orElseGet() does not convert the null returned by the second function to empty(), so it will return null.
See the implementation of map():
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Optional.ofNullable(mapper.apply(value));
}
}
And the implementation of orElseGet():
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
Thus when executed:
if optional.isPresent(), the system will print If present., then If empty., and the expression will evaluate to null.
if !optional.isPresent(), the system will print If empty., and the expression will evaluate to null.
If the function provided to map() returned any other value - any other value - the code would work as you expect, with the function provided to map() being executed if isPresent() and the function provided to orElseGet() if !isPresent():
For example, this:
optional
.map(data -> {
System.out.println("If present.");
return 0;
})
.orElseGet( () -> {
System.out.println("If empty.");
return 0;
});
When executed:
if optional.isPresent(), the system will print If present., and the expression will evaluate to 0.
if !optional.isPresent(), the system will print If empty., and the expression will evaluate to 0.
If your specific case, I suggest that your insert and update methods return, say, the persisted object, or the id of the persisted object, or something similarly useful; then you can use code similar to this:
final Object persist = optional
.map(object -> {
System.out.println("If present.");
return update(object);
})
.orElseGet( () -> {
System.out.println("If empty.");
return insert(new Object());
});
Another solution could be following:
This is how you use it:
final Opt<String> opt = Opt.of("I'm a cool text");
opt.ifPresent()
.apply(s -> System.out.printf("Text is: %s\n", s))
.elseApply(() -> System.out.println("no text available"));
Or in case you in case of the opposite use case is true:
final Opt<String> opt = Opt.of("This is the text");
opt.ifNotPresent()
.apply(() -> System.out.println("Not present"))
.elseApply(t -> /*do something here*/);
This are the ingredients:
Little modified Function interface, just for the "elseApply" method
Optional enhancement
A little bit of curring :-)
The "cosmetically" enhanced Function interface.
#FunctionalInterface
public interface Fkt<T, R> extends Function<T, R> {
default R elseApply(final T t) {
return this.apply(t);
}
}
And the Optional wrapper class for enhancement:
public class Opt<T> {
private final Optional<T> optional;
private Opt(final Optional<T> theOptional) {
this.optional = theOptional;
}
public static <T> Opt<T> of(final T value) {
return new Opt<>(Optional.of(value));
}
public static <T> Opt<T> of(final Optional<T> optional) {
return new Opt<>(optional);
}
public static <T> Opt<T> ofNullable(final T value) {
return new Opt<>(Optional.ofNullable(value));
}
public static <T> Opt<T> empty() {
return new Opt<>(Optional.empty());
}
private final BiFunction<Consumer<T>, Runnable, Void> ifPresent = (present, notPresent) -> {
if (this.optional.isPresent()) {
present.accept(this.optional.get());
} else {
notPresent.run();
}
return null;
};
private final BiFunction<Runnable, Consumer<T>, Void> ifNotPresent = (notPresent, present) -> {
if (!this.optional.isPresent()) {
notPresent.run();
} else {
present.accept(this.optional.get());
}
return null;
};
public Fkt<Consumer<T>, Fkt<Runnable, Void>> ifPresent() {
return Opt.curry(this.ifPresent);
}
public Fkt<Runnable, Fkt<Consumer<T>, Void>> ifNotPresent() {
return Opt.curry(this.ifNotPresent);
}
private static <X, Y, Z> Fkt<X, Fkt<Y, Z>> curry(final BiFunction<X, Y, Z> function) {
return (final X x) -> (final Y y) -> function.apply(x, y);
}
}
This should do the trick and could serve as a basic template how to deal with such requirements.
The basic idea here is following. In a non functional style programming world you would probably implement a method taking two parameter where the first is a kind of runnable code which should be executed in case the value is available and the other parameter is the runnable code which should be run in case the value is not available. For the sake of better readability, you can use curring to split the function of two parameter in two functions of one parameter each. This is what I basically did here.
Hint: Opt also provides the other use case where you want to execute a piece of code just in case the value is not available. This could be done also via Optional.filter.stuff but I found this much more readable.
Hope that helps!
Additional Info:
There is another way to have say "if then else" using currying:
public static <X, Y> Function<Predicate<X>, Function<Function<X, Y>, Function<Function<X, Y>, Y>>> ifThenElse(X input) {
return (final Predicate<X> pred) -> (final Function<X, Y> ifPresent) -> (final Function<X, Y> ifNotPresent) -> pred.test(input) ? ifPresent.apply(input) : ifNotPresent.apply(input);
}
This way it is possible to say:
final String result = ifThenElse("fancy")
.apply(input -> input.contains("fancy")) /* test */
.apply(input -> input.toUpperCase()) /* if-case */
.apply(input -> input.toLowerCase()); /* else-case */
In case you want store the value:
Pair.of<List<>, List<>> output = opt.map(details -> Pair.of(details.a, details.b))).orElseGet(() -> Pair.of(Collections.emptyList(), Collections.emptyList()));
Supposing that you have a list and avoiding the isPresent() issue (related with optionals) you could use .iterator().hasNext() to check if not present.
How can I express this with java8 streaming-API?
I want to perform itemConsumer for every item of a stream. If there
are no items I want to perform emptyAction.
Of course I could write something like this:
Consumer<Object> itemConsumer = System.out::println;
Runnable emptyAction = () -> {System.out.println("no elements");};
Stream<Object> stream = Stream.of("a","b"); // or Stream.empty()
List<Object> list = stream.collect(Collectors.toList());
if (list.isEmpty())
emptyAction.run();
else
list.stream().forEach(itemConsumer);
But I would prefer to avoid any Lists.
I also thought about setting a flag in a peek method - but that flag would be non-final and therefore not allowed. Using a boolean container also seems to be too much of a workaround.
You could coerce reduce to do this. The logic would be to reduce on false, setting the value to true if any useful data is encountered.
The the result of the reduce is then false then no items have been encountered. If any items were encountered then the result would be true:
boolean hasItems = stream.reduce(false, (o, i) -> {
itemConsumer.accept(i);
return true;
}, (l, r) -> l | r);
if (!hasItems) {
emptyAction.run();
}
This should work fine for parallel streams, as any stream encountering an item would set the value to true.
I'm not sure, however, that I like this as it's a slightly obtuse use of the reduce operation.
An alternative would be to use AtomicBoolean as a mutable boolean container:
final AtomicBoolean hasItems = new AtomicBoolean(false);
stream.forEach(i -> {
itemConsumer.accept(i);
hasItems.set(true);
});
if (!hasItems.get()) {
emptyAction.run();
}
I don't know if I like that more or less however.
Finally, you could have your itemConsumer remember state:
class ItemConsumer implements Consumer<Object> {
private volatile boolean hasConsumedAny;
#Override
public void accept(Object o) {
hasConsumedAny = true;
//magic magic
}
public boolean isHasConsumedAny() {
return hasConsumedAny;
}
}
final ItemConsumer itemConsumer = new ItemConsumer();
stream.forEach(itemConsumer::accept);
if (!itemConsumer.isHasConsumedAny()) {
emptyAction.run();
}
This seems a bit neater, but might not be practical. So maybe a decorator pattern -
class ItemConsumer<T> implements Consumer<T> {
private volatile boolean hasConsumedAny;
private final Consumer<T> delegate;
ItemConsumer(final Consumer<T> delegate) {
this.delegate = delegate;
}
#Override
public void accept(T t) {
hasConsumedAny = true;
delegate.accept(t);
}
public boolean isHasConsumedAny() {
return hasConsumedAny;
}
}
final ItemConsumer<Object> consumer = new ItemConsumer<Object>(() -> /** magic **/);
TL;DR: something has to remember whether you encountered anything during the consumption of the Stream, be it:
the Stream itself in case of reduce;
AtomicBoolean; or
the consumer
I think the consumer is probably best placed, from a logic point of view.
A solution without any additional variables:
stream.peek(itemConsumer).reduce((a, b) -> a).orElseGet(() -> {
emptyAction.run();
return null;
});
Note that if the stream is parallel, then itemConsumer could be called simultaneously for different elements in different threads (like in forEach, not in forEachOrdered). Also this solution will fail if the first stream element is null.
There’s a simple straight-forward solution:
Spliterator<Object> sp=stream.spliterator();
if(!sp.tryAdvance(itemConsumer))
emptyAction.run();
else
sp.forEachRemaining(itemConsumer);
You can even keep parallel support for the elements after the first, if you wish:
Spliterator<Object> sp=stream.parallel().spliterator();
if(!sp.tryAdvance(itemConsumer))
emptyAction.run();
else
StreamSupport.stream(sp, true).forEach(itemConsumer);
In my opinion, it is much easier to understand as a reduce based solution.
You could do this:
if(stream.peek(itemConsumer).count() == 0){
emptyAction.run();
}
But it seems that count may be changed to skip the peek if it knows the size of the Stream in Java 9 (see here), so if you want it to work in the future you could use:
if(stream.peek(itemConsumer).mapToLong(e -> 1).sum() == 0){
emptyAction.run();
}
Another attempt to use reduce:
Stream<Object> stream = Stream.of("a","b","c");
//Stream<Object> stream = Stream.empty();
Runnable defaultRunnable = () -> System.out.println("empty Stream");
Consumer<Object> printConsumer = System.out::println;
Runnable runnable = stream.map(x -> toRunnable(x, printConsumer)).reduce((a, b) -> () -> {
a.run();
b.run();
}).orElse(defaultRunnable);
runnable.run(); // prints a, b, c (or empty stream when it is empty)
// for type inference
static <T> Runnable toRunnable(T t, Consumer<T> cons){
return ()->cons.accept(t);
}
This approach does not use peek() which according to Javadoc "mainly exists to support debugging"
Is there a prettier way of doing the following in Java 8, avoiding isPresent and get?
void doStuff(String someValue, Optional<Boolean> doIt) {
if (doIt.isPresent()) {
if (doIt.get()) {
trueMethod(someValue);
} else {
falseMethod(someValue);
}
}
}
I tried using map, without success. But I probably didn't try hard enough?
You can use ifPresent instead of isPresent and get :
void doStuff(String someValue, Optional<Boolean> doIt) {
doIt.ifPresent (b -> {
if (b)
trueMethod(someValue);
else
falseMethod(someValue);
});
}
EDIT: fixed my code, since you can't use the ternary operator if trueMethod and falseMethod don't return anything.
This would be the functional approach using map:
Function<Boolean, Void> logic = isTrue -> {
if (isTrue) trueMethod(someValue);
else falseMethod(someValue);
return null;
};
doIt.map(logic);
However, it is really ugly, mostly because of your "not-very-functional" trueMethod/falseMethod, which both return void (leading to the ugly return null).