Software Engineering Stack Exchange is a question and answer site for professionals, academics, and students working within the systems development life cycle. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have recently mastered the Lambda expression that was introduced in java 8. I find that whenever I am using a functional interface, I tend to always use a Lambda expression instead of creating a class that implements the functional interface.

Is this considered good practice? Or are their situations where using a Lambda for a functional interface is not appropriate?

share|improve this question
87  
To the question "Is using technique X whenever possible good practice" the only correct answer is "no, use technique X not whenever possible, but whenever sensible". – Doc Brown yesterday
    
The choice of when to use a lambda (which is anonymous) versus some other kind of functional implementation (e.g. a method reference) is a really interesting question. I had the opportunity to meet Josh Bloch a couple of days ago, and this was one of the points he talked about. From what he said I understand he's planning to add a new item to the next edition of Effective Java dealing with this exact question. – Daniel Pryden yesterday
    
@DocBrown That should be an answer, not a comment. – gnasher729 12 hours ago
    
@gnasher729: definitely not. – Doc Brown 3 hours ago
up vote 68 down vote accepted

There are a number of criteria that should make you consider not using a lambda:

  • Size The larger a lambda gets, the more difficult it makes it to follow the logic surrounding it.
  • Repetition It's better to create a named function for repeated logic, although it's okay to repeat very simple lambdas that are spread apart.
  • Naming If you can think of a great semantic name, you should use that instead, as it adds a lot of clarity to your code. I'm not talking names like priceIsOver100. x -> x.price > 100 is just as clear as that name. I mean names like isEligibleVoter that replace a long list of conditions.
  • Nesting Nested lambdas are really, really hard to read.

Don't go overboard. Remember, software is easily changed. When in doubt, write it both ways and see which is easier to read.

share|improve this answer
1  
It is also important to consider the amount of data that is to processed through the lambda, as lambdas are rather inefficient at small amounts of data processing. They really shine in parallelization of large data sets. – CraigR8806 yesterday
1  
@CraigR8806 I don't think performance is a concern here. Using an anonymous function or creating a class extending the functional interface should be the same performance wise. Performance considerations come in when you talk about using the streams/higher-order-functions api over an imperative style loop, but in this question we are using functional interfaces in both cases just with different syntax. – puhlen yesterday
12  
"although it's okay to repeat very simple lambdas that are spread apart" Only if they don't necessarily change together. If they must all be the same logic for your code to be correct, you should make them all actually the same method so that changes only need to be made in one place. – jpmc26 yesterday
    
Overall this is a really good answer. Mentioning the use of a method reference as an alternate to a lambda would patch to only hole I see in this answer. – Morgen yesterday
1  
When in doubt, writing it both ways and ask someone else who maintains the code which is easier to read. – corsiKa yesterday

It depends. Whenever you find yourself using the same lambda in different places you should consider implementing a class that implements the interface. But if you would've used an anonymous inner class otherwise I think a lambda is far better.

share|improve this answer
6  
Don't forget the possibility of using a method reference! Oracle has added (and is adding even more in Java 9) static methods and default methods all over the place for exactly that reason. – Jörg W Mittag yesterday

I support Karl Bielefeldt's answer, but want to provide a brief addition.

  • Debugging Some IDE's struggle with scope inside of a lambda, and struggle to display member variables inside the context of a lambda. While hopefully this situation will change down the line, it can be annoying to maintain someone else's code when it is littered with lambdas.
share|improve this answer
    
Definitely true of .NET. Doesn't make me avoid lambdas, necessarily, but I certainly don't feel any guilt if I do something else instead. – user1172763 yesterday
2  
If that's the case you're using the wrong IDE. Both IntelliJ and Netbeans do pretty well in that particular area. – David Foerster yesterday
    
@user1172763 In Visual Studio, if you want to view member variables, I've found that you can travel up the call stack until you get to the context of the lambda. – Zev Spitz 17 hours ago

Access to local variables of the enclosing scope

The accepted Answer by Karl Bielefeldt is correct. I can add one more distinction:

  • Scope

The lambda code nested inside a method inside a class can access any effectively-final variables found within that method & class.

Creating a class that implements the functional interface does yield such direct access to the state of the calling code.

To quote the Java Tutorial (emphasis mine):

Like local and anonymous classes, lambda expressions can capture variables; they have the same access to local variables of the enclosing scope. However, unlike local and anonymous classes, lambda expressions do not have any shadowing issues (see Shadowing for more information). Lambda expressions are lexically scoped. This means that they do not inherit any names from a supertype or introduce a new level of scoping. Declarations in a lambda expression are interpreted just as they are in the enclosing environment.

So while there are benefits to pulling out long code and naming it, you must weigh that against the simplicity of direct access to the state of the enclosing method & class.

See:

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.