2

Someone raised a question on another SO Answer about whether it is bad practice or inefficient to do this:

Optional<User> user = ...
user.ifPresent(u -> doSomethingWithoutUser());

instead of

if (user.isPresent()) doSomethingWithoutUser();

Specifically, the fact that we're adapting a zero-arg method into a Consumer<User> which ignores its parameter u.

  • As this isn't a Stream non-terminal operation, the fact doSomethingWithoutUser() likely has side-effects isn't a concern.
  • I'm not bothered about the specifics of this one-line Optional example, it could the result of a long chain of functional/Stream calls that simply feels natural to finish inline with the lambda call.
Naman
  • 27,789
  • 26
  • 218
  • 353
drekbour
  • 2,895
  • 18
  • 28
  • There is no point in invoking `ifPresent` if there is no side effect. Useful consumers are always side-effectful (or intentionally do nothing, like `u -> {}`). – Andy Turner Nov 06 '19 at 16:26
  • 1
    If the comment is (fundamentally) because a condition on `u` doesn't in fact use `u`... then that's a different question. Otherwise, in my opinion, if any one of those is bad, so is the other. – ernest_k Nov 06 '19 at 16:32
  • A basic concept while I made the comment to the linked answer could be related to [this answer](https://stackoverflow.com/a/40153253/1746118) and as explained in the other answers there as well. A nitpick, there could be the type inference while using lambda within `ifPresent`. Another, that `ifPresent` would not be of much use when both `if` and `else` are required. Given that is solved by the inbuilt API `ifPresentOrElse()` since JDK-9 which then exposes a Runnable for the `else`, considering the value cannot be used. (But I would wait as well for an authoritative answer to this +1.) – Naman Nov 06 '19 at 17:12
  • 2
    @Naman I still don’t get the concern about this usage, i.e. what should be “bad practice” or “inefficient” about this usage. – Holger Nov 06 '19 at 17:40
  • @Holger The concern that I had was about the misuse of the API, and the efficiency was something that I chose not to comment on without the benchmarks, which by the implementation of both the APIs looks to be not much of usefulness as well. By the misuse I meant, treating a `Consumer` as a `Runnable`. Not that I am pointing that it couldn't be implemented, but that it looks to be inappropriate and that's just an opinion by the way. – Naman Nov 06 '19 at 18:02
  • 1
    @Naman there’s no requirement that an action has to utilize every variable that is in scope. How many times do event listeners perform an action without accessing the provided event? In fact, unused parameters are so common that the language designers are planning [to add a special syntax for it](https://openjdk.java.net/jeps/302#Treatment-of-underscores). – Holger Nov 07 '19 at 08:27
  • I was going to make the point that Scala uses `_` for anonymous variables. I'm glad that Java is co-opting this. @Holger, that reference canonically answers the "bad practice" angle. Maybe I'll JMH the two variants for some an arbitrary quantification on efficiency and then self-answer this one before it gets closed as discussion. – drekbour Nov 07 '19 at 13:56

0 Answers0