paul paul - 1 month ago 12
Groovy Question

FindFirst and orElse operators return different class type

I´m using Stream with findFirst() which return optional, but añso there´s a chance where my stream maybe does not emit anything, so I ad orElse operator at the bottom.

The problem is that orElse does not return an optional but the class type that the optional findFirst operator wrap.

def optional = categories.categories.stream()
.filter { category -> category.name == selCategory }
.map { category -> loadUniqueIds.call(category) }
.map { UUIDs -> new JsonArray(UUIDs) }
.findFirst().orElse{Optional.of(new JsonArray())}
optional.get()


So I end up without the possibility of use findFirst and orElse.

What I´m doing wrong here?

Thanks

UPDATE:

I end up removing the orElse after the findFirst and check the optional later

optional.isPresent() ? optional.get(): new JsonArray()


Anyway if somebody has a better/elegant solution, please let me know.

Regards.

Answer

If you use findFirst() you get an Optional, but if you use orElse() (which is Optional's method) you get the unwrapped object, since there's no way you can get an Optional anymore. Either you get what was found in findFirst() unwrapped or you get the "default" value from orElse().

It doesn't make sense to return an optional from orElse(), because it's always guaranteed to exist.

Optional.of("foo").orElse("bar");  // Returns String "foo"
Optional.empty().orElse("bar");    // Returns String "bar"