0

I want to exit the current method/function in case a value of an Optional is not present.

i tried a naive approach to put a return statement into the .orElseGet() but that didn't seem to work. The best alternative so far seems to be:

private void foo(Set<ISomeObject> someIterable) {

    Optional<ISomeObject> myObjectOpt = someIterable
        .stream()
        .filter(...)
        .findFirst();

    if(!myObjectOpt.isPresent()){
        return;
    }

    ISomeObject myObject = myObjectOpt.get();
    // do something with myObject
}

This doesn't seem better readable than the good old Nullcheck, any alternatives?

4
  • maybe myObject is a field? if so: do you want to update it only if someIterable returns a value? If not... are you using it later in the same method and only want to use it, if it is present? the if might be ok for the first... (but the else is not necessary then)... ifPresent might be what you are looking for in the latter case... Commented May 22, 2019 at 10:26
  • @Michael thx, i was missing that comment in the pseudocode Commented May 22, 2019 at 10:52
  • 1
    Note that using optionals is not necessarily resulting in code “better readable than the good old Nullcheck”. The key point here, is that the check can not be easily forgotten and there’s no ambiguity between a matching element being null and no matching element. So using a statement like if(!myObjectOpt.isPresent()) return might be fine in some situations. When it comes to readability, there is no reason to declare the myObject long before its initialization. Just write ISomeObject myObject = myObjectOpt.get(); after the presence has been checked… Commented May 22, 2019 at 10:58
  • @ Holger, that's a good remark about the purpose of Optionals and the declaration. i adjusted the question. I guess there is no syntactical better way then. Commented May 22, 2019 at 11:23

2 Answers 2

2

You can pass a Consumer to ifPresent and do whatever you want in the consumer instead:

private void foo(Set<ISomeObject> someIterable) {
    someIterable
        .stream()
        .filter(...)
        .findFirst()
        .ifPresent(x -> {
            // do something with x
        });
    // do nothing!
}
Sign up to request clarification or add additional context in comments.

2 Comments

That works, but would result in nesting, which is harder to read :/
I would consider this the conventional solution. For most purposes I like it. There may of course be situations where it will not be the most readable. If you keep myObjectOpt form your question and then do myObjectOpt.ifPresent();, you may find it clearer? Or would it help putting what you want to do with myObject/x into a separate method? Then you only got .ifPresent(this::yourNewMethod);.
0

Well, it seems you want to set the value of ISomeObject myObject in case that Optional is present, one way to do it:

ISomeObject [] myObject = new ISomeObject[1]; // effectively final strikes again!

Optional<ISomeObject> myObjectOpt = someIterable
    .stream()
    .filter(...)
    .findFirst()
    .ifPresent(x -> myObject[0] = x);

But even simpler would be:

myObject = someIterable
        .stream()
        .filter(...)
        .findFirst()
        .orElse(null); // in your code myObject is null by default anyway

But even this makes very little sense, you are setting that field and then doing nothing with it? Why do that in the first place then?

Also, findFirst from a Set makes little sense, of course.

7 Comments

why should findFirst make little sense in a Set? if the filter is just very basic, e.g. someObj -> someObj.getName().contains("x"), there can be several matches...
@Roland does a Set has any order? Run this String first = Set.of("aa", "ba", "ca", "da") .stream() .filter(x -> x.contains("a")) .findFirst() .get(); System.out.println(first); a few times in java-9 or higher
A Set can have a meaningful order, e.g. it might be a SortedSet or a LinkedHashSet. Besides that, I don’t see any advantage in showing the dubious array based solution before the simpler and cleaner one.
@Eugene Both of your solutions would still necessitate a Nullcheck of myObject. Remember, my main problem is to exit the function if myObject == Null
@JulianDm why not ifPresent(x -> do something with that x)?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.