They're both ways to pass in functions as argument to another function. They don't have anything to do with forEach in particular, it's just that forEach is an example of when passing in a function is useful. In Java, it's technically not possible to actually just pass in a function. So you need to instantiate an object that implement a function interface and pass that in, instead. This is annoying, especially if you literally only want this function for this particular line. Lambda is a way to skipping through this entire process; it let you define a function (and the corresponding object) and pass it in right there, you don't even need to give them names. But unfortunately, this creates the annoying scenario where, you already have a function with names and everything, but you don't have a functional interface for that, so you write a lambda expression that literally just invoke this function. So a band-aid fix was added: you can literally just write in the name of the function, and Java will automatically do the rest for you. This is method reference. It lets you write code in such a way that it looks like you pass in a function as an argument, while technically do not allow you to do so. Answer from CrouchonaHammock on reddit.com
🌐
Reddit
reddit.com › r/java › subtle difference between lambda and method reference
r/java on Reddit: Subtle difference between lambda and method reference
September 23, 2022 -

So. Turns out there's a subtle difference between lambdas and method references. For instance, compare: myInstance::getStuff and () -> myInstance.getStuff()

This will mostly be considered equivalent. But. If myInstance happens to be null, the lambda will throw a null pointer when the lambda gets evaluated, but the method reference will throw right away when trying to access the reference.

So what? Well. This IS important if the code evaluating the lambda is inside a null-pointer try-catch.

Say I have a function mightBeNull(Supplier<T> function) that does something along the lines of:

try {
    doStuff(function.get().getSomeMore().getSomeMore());
} catch (NullPointerException e) {
    doOtherStuff();
}

If so. The call: mightBeNull(() -> myNullVariable.getStuff()) will work without exceptions, but the "equivalent": mightBeNull(myNullVariable::getStuff) will throw a null pointer exception right att the function call.

🌐
W3Schools
w3schools.com › python › python_lambda.asp
Python Lambda
Python Overview Python Built-in ... Interview Q&A Python Bootcamp Python Certificate Python Training ... A lambda function is a small anonymous function....
🌐
Python Reference
python-reference.readthedocs.io › en › latest › docs › operators › lambda.html
lambda — Python Reference (The Right Way) 0.1 documentation
>>> # this example shows how to use lambda with sorted function >>> # lambda function is grabage collected after it has been used >>> # (there is no reference to it to keep it alive) >>> sorted(['A', 'b', 'C'], key=lambda x: x.lower()) ['A', 'b', 'C']
🌐
Real Python
realpython.com › python-lambda
How to Use Python Lambda Functions – Real Python
December 1, 2023 - The identity function, a function that returns its argument, is expressed with a standard Python function definition using the keyword def as follows: ... Note: In the context of this article, a bound variable is an argument to a lambda function. In contrast, a free variable is not bound and may be referenced in the body of the expression.
Top answer
1 of 6
308

Let me offer some perspective on why we added this feature to the language, when clearly we didn't strictly need to (all methods refs can be expressed as lambdas).

Note that there isn't any right answer. Anyone who says "always use a method ref instead of a lambda" or "always use a lambda instead of a method ref" should be ignored.

This question is very similar in spirit to "when should I use a named class vs an anonymous class"? And the answer is the same: when you find it more readable. There are certainly cases that are definitely one or definitely the other, but there's a host of grey in the middle, and judgment must be used.

The theory behind method refs is simple: names matter. If a method has a name, then referring to it by name, rather than by an imperative bag of code that ultimately just turns around and invokes it, is often (but not always!) more clear and readable.

The arguments about performance or about counting characters are mostly red herrings, and you should ignore them. The goal is writing code that is crystal clear what it does. Very often (but not always!) method refs win on this metric, so we included them as an option, to be used in those cases.

A key consideration about whether method refs clarify or obfuscate intent is whether it is obvious from context what is the shape of the function being represented. In some cases (e.g., map(Person::getLastName), it's quite clear from the context that a function that maps one thing to another is required, and in cases like this, method references shine. In others, using a method ref requires the reader to wonder about what kind of function is being described; this is a warning sign that a lambda might be more readable, even if it is longer.

Finally, what we've found is that most people at first steer away from method refs because they feel even newer and weirder than lambdas, and so initially find them "less readable", but over time, when they get used to the syntax, generally change their behavior and gravitate towards method references when they can. So be aware that your own subjective initial "less readable" reaction almost certainly entails some aspect of familiarity bias, and you should give yourself a chance to get comfortable with both before rendering a stylistic opinion.

2 of 6
19

Long lambda expressions consisting of several statements may reduce the readability of your code. In such a case, extracting those statements in a method and referencing it may be a better choice.

The other reason may be re-usability. Instead of copy&pasting your lambda expression of few statements, you can construct a method and call it from different places of your code.

Top answer
1 of 1
3

Your variables hour and minute change before the lambda is called.

hour = 1
minute = 30

# the values of `hour` and `minute` right now are irrelevant
t1 = Test(lambda x: x.replace(hour=hour, minute=minute))

hour=2
minute=30

# the values of `hour` and `minute` right now are irrelevant
t2 = Test(lambda x: x.replace(hour=hour, minute=minute))

# the values of `hour` and `minute` RIGHT NOW are relevant
# and RIGHT NOW they are 2 and 30, respectively
print(t1.getDate())
print(t2.getDate())

The lambda references the variables, it does not copy their values. In other words, the values at the time of execution of the lambda functions are used, not the values at the time of setting them up.

Your options:

  • Hard-code the values in the lambda:

    t1 = Test(lambda x: x.replace(hour=1, minute=30))
    
  • Change the order of execution. Call the lambda before you change the values of hour and minute.

    hour1 = 1
    minute1 = 30
    
    t1 = Test(lambda x: x.replace(hour=hour, minute=minute))
    print(t1.getDate())
    
    hour1 = 2
    minute1 = 30
    
  • Use different variable names for each lambda.

    hour1 = 1
    minute1 = 30
    
    t1 = Test(lambda x: x.replace(hour=hour1, minute=minute1))
    print(t1.getDate())
    
  • Use different scopes to avoid that the lambdas reference the same hour and minute, e.g. by using a function. Essentially that's like using different variable names.

    def helper_function(hour, minute)
        return Test(lambda x: x.replace(hour=hour, minute=minute))
    
    t1 = helper_function(1, 30)
    t2 = helper_function(2, 30)
    
    print(t1.getDate())
    print(t2.getDate())
    

Using different scopes probably is the most elegant approach.

Find elsewhere
🌐
Coderanch
coderanch.com › t › 737852 › java › Surprise-Instance-Method-References-Behave
Surprise!! Instance Method References Can Behave Very Differently From Lambda Expressions (Features new in Java 8 forum at Coderanch)
December 30, 2020 - Method references are so compact and so flexible, but I still feel there are numerous tricky little areas surrounding them, especially in the different capture semantics versus lambdas. Add an order of magnitude of complexity if one finds themselves jumping between using lambdas in C++, C#, Java and Python...
🌐
Medium
medium.com › @afinlay › lambda-expressions-in-java-python-c-c-8cdbca5a5e8b
Lambda Expressions in Java, Python, C#, C++ | by Adrian D. Finlay | Medium
May 1, 2018 - + "Restarting.\n\n"); main(args); } //Method Reference (Lambda Expression) doMath = Math::min; //Print Result out.println("The result is:\t" + doMath.binaryMathOp(expr1, expr2) + "\n"); //Close Input Stream in.close(); } } ... Lambda Expressions work a little differently in python.
🌐
Medium
medium.com › codimis › what-is-method-reference-and-why-is-it-used-in-place-of-lambda-expressions-2a97fe01b07b
What is Method Reference and Why is It Used in Place of Lambda Expressions? | by Büşra Bozgöz | Codimis | Medium
March 22, 2024 - To briefly describe method references, we need to say that method references are a concise and more readable way of writing lambda expressions, but there are only particular use cases in which we can use them.
🌐
JetBrains
jetbrains.com › help › inspectopedia › Convert2MethodRef.html
Lambda can be replaced with method reference | Inspectopedia Documentation
3 weeks ago - While often it could be a matter of taste, method references are more clear and readable compared to lambdas.
🌐
Medium
proandroiddev.com › kotlin-lambda-vs-method-reference-fdbd175f6845
Kotlin. Lambda vs Method Reference | by Gurgen Gevondov | ProAndroidDev
March 13, 2021 - To sum up, the difference between ... is that when we use method reference, the instance of variable, the method of which we use, is fixed at the moment the reference is created, not when it is called, unlike what happens when lambda is used...
🌐
Trey Hunner
treyhunner.com › 2018 › 09 › stop-writing-lambda-expressions
Overusing lambda expressions in Python
September 27, 2018 - I’ll call the lambda syntax itself a lambda expression and the function you get back from this I’ll call a lambda function. Python’s lambda expressions allow a function to be created and passed around (often into another function) all in one line of code.
🌐
Stack Overflow
stackoverflow.com › questions › 46480787 › python-difference-between-method-and-lambda
Python difference between method and lambda - Stack Overflow
– juanpa.arrivillaga Commented Sep 29, 2017 at 2:31 ... Both do the same, but neither is a method; the first is a function, the second, an anonymous function that you named by assigning it to a variable.
🌐
Towards Data Science
towardsdatascience.com › home › latest › should you define named python functions using lambda?
Should You Define Named Python Functions Using lambda? | Towards Data Science
November 26, 2024 - When we define a lambda function and assign it to a name (sort_fun), it can be used elsewhere in the code. Also, in Python, functions are functions irrespective of how they were defined, whether using def or lambda; hence, sort_fun() is a valid Python function.
🌐
Dataquest
dataquest.io › blog › tutorial-lambda-functions-in-python
Tutorial: Lambda Functions in Python
March 6, 2023 - We use a lambda function to evaluate only one short expression (ideally, a single-line) and only once, meaning that we aren't going to apply this function later. Usually, we pass a lambda function as an argument to a higher-order function (the one that takes in other functions as arguments), such as Python built-in functions like filter(), map(), or reduce().