166

I have the following search code in Java:

return getTableViewController().getMe().getColumns().stream()
    .filter($ -> Database.equalsColumnName($.getId(), columnId))
    .findFirst()
    .get();

I was wishing to find column by name and return first one found.

I understand there is a case when nothing found and it should be processed, but how?

Is this what it wants by this swearing:

'Optional.get()' without 'isPresent()' check

?

How to fix? I wish to return null if nothing found.

UPDATE

Okay, okay, I just didn't realize, that findFirst() returns Optional.

basseur
  • 153
  • 1
  • 1
  • 11
Dims
  • 47,675
  • 117
  • 331
  • 600
  • 7
    Note that you shouldn't use `$` as an identifier in Java: [JLS Sec 3.8](https://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.8): "The $ sign should be used only in mechanically generated source code or, rarely, to access pre-existing names on legacy systems." – Andy Turner Mar 22 '17 at 20:09

5 Answers5

316

Replace get() with orElse(null).

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • 5
    Why? :) Why `orElse` starts with "or"? – Dims Aug 02 '16 at 16:06
  • 17
    Because that's the method name. And `else` is a keyword. – Andy Turner Aug 02 '16 at 16:06
  • 12
    @Dims its just a short form of getOrElse, just leaving out the get. With optional you should normally use `orElse` instead of `get` because `get` will throw an exception if the value is null. – puhlen Aug 02 '16 at 16:18
  • 4
    @puhlen `orElseGet()` takes a `Supplier`, whereas `orElse()` takes a `T`. These are not equivalent. – bcsb1001 Aug 02 '16 at 16:37
  • 8
    @bcsb1001 that's not what he tried to say, "getOrElse" is a name he invented to explain the purpose of `orElse`; there is no reference to `orElseGet` in his comment ;) – Rorrim Nov 14 '19 at 16:07
  • As Erwin Smout answered, optional is created to avoid null. Although this answer "works" but you are destroying the purpose of `Optional` if you return `null`. IMHO the better approach is to just write what should be done after `findFirst()` is done, instead of returning the actual value. – M4HdYaR Jun 27 '23 at 13:07
36
...findFirst().orElse(null);

Returns the value if present, otherwise returns null. The documentation says that the passed parameter may be null (what is forbidden for orElseGet and orElseThrow).

Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
  • 1
    that is partly true. findFirst() has following rule: "When there is no encounter order it returns any element from the Stream." -> so if your filter does not return the matched element, findFirst() will return the first one (except the stream is empty beforehand) – Fl0R1D3R Oct 01 '18 at 13:43
7

my solution was to check it this way

if(item.isPresent()){
  item.get().setId("1q2w3e4r5t6y")
}
Yakup Ad
  • 1,591
  • 16
  • 13
4

Optional was created so code could after all these decades, finally start avoiding null.

Remove the .get(), return the Optional itself and make the calling code deal with it appropriately (just as it would have to do in the case you'd be returning null).

Erwin Smout
  • 18,113
  • 4
  • 33
  • 52
  • This is an accurate but deceptive statement as optionals still throw errors when accessed if they don't exist. From the perspective of avoiding null, all an optional does is change the error type as you still have to, in effect, null check it. In this case, what an optional provides is controlling where the null pointer error happens. Anyone who has had to debug null points while developing with streams knows this is very tricky to debug. Optionals allow us to pass this error to a higher level allowing us to target the issue precisely. – lvoelk Nov 22 '21 at 18:26
  • 4
    That was what I meant with "deal with it appropriately". If info can possibly be "absent" then for robustness of the code, the "presence" check ***has to be written somewhere*** (one way or another) but the point is that nullable objects make it too easy to just forget while if the typesystem explicitly tells you "Hey this is not a Foo but an optional, you have to .get() it first", then professionals might be reminded they have to do the "presence" check too and above all, they might be reminded that they should also be giving thought to what to do in the case the info sin't there. – Erwin Smout Nov 27 '21 at 20:17
-2

we can use like below

.map(Object)
.filter(Optional::isPresent)
.map(Optional::get)
.orElse(null)
Apostolos
  • 10,033
  • 5
  • 24
  • 39