Syntax is:

arguments -> body

where arguments can be either

  • ()

  • a single variable if the type of that variable can be inferred from the context

  • a sequence of variables, with or without types (or since Java 11, with var), in parentheses.
    Examples: (x), (x, y), (int x, int y), (var x, var y) (Java 11+).
    The following are invalid: (int x, y), (x, var y), (var x, int y)

and body can be either an expression or a {...} block with statements. The expression (other than a method or constructor call) is simply returned, i.e. () -> 2 is equivalent to () -> {return 2;}


In case of lambda expressions like () -> f() (the body is a method or constructor call expression):

  • if f() returns void, they are equivalent to () -> { f(); }

  • otherwise, they are equivalent to either () -> { f(); } or () -> { return f(); }). The compiler infers it from the calling context, but usually it will prefer the latter.

Therefore, if you have two methods: void handle(Supplier<T>) and void handle(Runnable), then:

  • handle(() -> { return f(); }) and handle(() -> x) will call the first one,

  • handle(() -> { f(); } will call the second one, and

  • handle(() -> f()):

    • if f() returns void or a type that is not convertible to T, then it will call the second one

    • if f() returns a type that is convertible to T, then it will call the first one


The compiler tries to match the type of the lambda to the context. I don't know the exact rules, but the answer to:

What would happen if there were two SwingUtilities.invokeLater methods which differ only in parameter list?

is: it depends on what would be those parameter lists. If the other invokeLater had also exactly one parameter and that parameter would be of type that is also an interface with one method of type void*(), well, then it would complain that it cannot figure out which method you mean.

Why are they written as they are? Well, I think it's because syntax in C# and Scala is almost the same (they use => rather than ->).

Answer from Karol S on Stack Overflow
🌐
W3Schools
w3schools.com › java › java_lambda.asp
Java Lambda Expressions
The lambda must match that method's parameters and return type. Java includes many built-in functional interfaces, such as Consumer (from the java.util package) used with lists.
🌐
GeeksforGeeks
geeksforgeeks.org › java › lambda-expressions-java-8
Java Lambda Expressions - GeeksforGeeks
lambda expressions, introduced in Java 8, allow developers to write concise, functional-style code by representing anonymous functions.
Published: August 29, 2026
Discussions

What is the breakdown for Java's lambda syntax? - Stack Overflow
Explore Stack Internal ... Save this question. Show activity on this post. Please explain the syntax for Java 8's lambda methods. There are a lot of explanations out there for what lambda functions are, but I can't find a thorough explanation of the syntax, and I am finding it very difficult ... More on stackoverflow.com
🌐 stackoverflow.com
Meaning of lambda () -> { } in Java - Stack Overflow
I am looking at the following Stack Overflow answer: How to change Spring's @Scheduled fixedDelay at runtime And in the code there is the following line: schedulerFuture = taskScheduler.sched... More on stackoverflow.com
🌐 stackoverflow.com
java - Do lambda expressions have any use other than saving lines of code? - Stack Overflow
Given the differences regarding both, semantic and performance, lambda expressions may change the way programmers will solve certain problems in the future, of course, also due to the new APIs embracing ideas of functional programming utilizing the new language features. See also Java 8 lambda ... More on stackoverflow.com
🌐 stackoverflow.com
What is the most popular language to use in lambda. Java/Node/Python?
I don't have statistics to back this up, but my guess would be Node and Python More on reddit.com
🌐 r/aws
40
29
January 10, 2022
🌐
Reddit
reddit.com › r/learnprogramming › can someone explain lambdas?
r/learnprogramming on Reddit: Can someone explain lambdas?
November 14, 2023 -

So I’m reading a book on Java, and it’s talking about lambdas. The syntax seems simple enough, but the author hasn’t described why you would use them over a regular function. They’re being used in the context of functions that don’t have bodies (abstracts, I think?), but I don’t understand why I would use those either.

Top answer
1 of 16
61
Lambdas are typically used when you're passing a callback function as a parameter to another object or method. Technically, functions in Java are not objects, so a "lambda function" actually gives you an object that implements an interface. There are other ways to do this, but lambdas are very concise and keep the code of the callback "inline" at the point where you're using it. Consider, for instance, the Swing JButton class. To make the button actually do something when clicked, you call addActionListener which expects as its parameter an implementation of the ActionListener interface. Say you want to print the string "Hello world!" when the button is clicked. You could write a whole separate HelloWorldActionListener class that implements ActionListener. Or you could write it as an inline anonymous class: button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.out.println("Hello world!"); } }); A lambda function lets you do the same thing much more concisely: button.addActionListener(e -> System.out.println("Hello world!"));
2 of 16
18
Lambdas are basically anonymous, ad-hoc functions which are treated as first-class variables and can be passed around like any other object. They allow you to inject behavior as a dependency/parameter. They are very useful for cutting down on boilerplate. For example, let's say you have the following boilerplate in C#: StartTimer(); result = DoSomething(); StopTimer(); LogResultAndTime(result); StartTimer(); result = DoSomethingElse(); StopTimer(); LogResultAndTime(result); //ad nauseum Creating a regular method like so: void BoilerplateCode(int result) { StartTimer(); //What do you put here? StopTimer(); LogResultAndTime(result); //result was already calculated before it was passed in, so the result was not properly timed! } Will not work. However, if you use a lambda, you can make it work: void Boilerplate(Func lambda) { StartTimer(); var result = lambda(); //Invoke the lambda on behalf of the caller so that we can time the function that was passed in. StopTimer(); LogResultAndTime(result); } //Usage example: Boilerplate(() => DoSomething()/*This does not get executed until the lambda is invoked*/); Boilerplate(() => DoSomethingElse()); Boilerplate(() => DoSomethingOther()); // ad nauseum As you can see, using a lambda allows me to only define my boilerplate code once, instead of needing to repeat it each time I want to use it. This allows me to easily make an enhancement, such as adding exception handling: void Boilerplate(Func lambda) { try { StartTimer(); var result = lambda(); //Invoke the lambda on behalf of the caller so that we can time the function that was passed in. StopTimer(); LogResultAndTime(result); } catch (Exception ex) { LogExceptionAndTime(ex); } } And all usages of the boilerplate get the updated/enhanced behavior immediately without the need for me to hunt down every instance of the boilerplate and update them by hand. Lambdas can also capture contextual data from the local scope, which allows your boilerplate to ignore implementation details about your lambda, like parameters and dependencies. var myParam = CalculateExpensiveDependency(); Boilerplate(() => DoSomething(myParam)); Boilerplate(() => DoSomethingElse(myParam)); Because we are using lambdas, Boilerplate() doesn't need to know anything about the parameters which DoSomething() or DoSomethingElse() requires. This reduces coupling, and makes your code more resusable, more resilient and more maintainable
🌐
Oracle
docs.oracle.com › javase › tutorial › java › javaOO › lambdaexpressions.html
Lambda Expressions (The Java™ Tutorials > Learning the Java Language > Classes and Objects)
In these cases, you're usually trying to pass functionality as an argument to another method, such as what action should be taken when someone clicks a button. Lambda expressions enable you to do this, to treat functionality as method argument, or code as data.
🌐
Medium
devcookies.medium.com › a-complete-guide-to-lambda-expressions-in-java-0aea2e1cea42
A Complete Guide to Lambda Expressions in Java
December 3, 2024 - Lambda expressions can only be used with functional interfaces. Java 8 introduced several functional interfaces in the java.util.function package.
🌐
Amazon Web Services
docs.aws.amazon.com › aws lambda › developer guide › aws lambda functions › programming languages › building lambda functions with java
Building Lambda functions with Java - AWS Lambda
Lambda provides runtimes for Java ... environment that includes AWS credentials from an AWS Identity and Access Management (IAM) role that you manage. Lambda supports the following Java runtimes. AWS provides the following libraries for Java functions....
Find elsewhere
🌐
Dev.java
dev.java › learn › lambdas
Lambda Expressions - Dev.java
Lambda expressions were a powerful ... in Java 8. This is a series of tutorials aimed at introducing the concept of lambdas while incrementally teaching how to use them in practice as you progress through each tutorial. The tutorials in this series are listed below. We recommend starting with the first and working your way through, but you are free to start wherever you'd like! ... Writing your first lambda, finding the type of a lambda. ... Discovering the most useful functional interfaces ...
Top answer
1 of 4
65

Syntax is:

arguments -> body

where arguments can be either

  • ()

  • a single variable if the type of that variable can be inferred from the context

  • a sequence of variables, with or without types (or since Java 11, with var), in parentheses.
    Examples: (x), (x, y), (int x, int y), (var x, var y) (Java 11+).
    The following are invalid: (int x, y), (x, var y), (var x, int y)

and body can be either an expression or a {...} block with statements. The expression (other than a method or constructor call) is simply returned, i.e. () -> 2 is equivalent to () -> {return 2;}


In case of lambda expressions like () -> f() (the body is a method or constructor call expression):

  • if f() returns void, they are equivalent to () -> { f(); }

  • otherwise, they are equivalent to either () -> { f(); } or () -> { return f(); }). The compiler infers it from the calling context, but usually it will prefer the latter.

Therefore, if you have two methods: void handle(Supplier<T>) and void handle(Runnable), then:

  • handle(() -> { return f(); }) and handle(() -> x) will call the first one,

  • handle(() -> { f(); } will call the second one, and

  • handle(() -> f()):

    • if f() returns void or a type that is not convertible to T, then it will call the second one

    • if f() returns a type that is convertible to T, then it will call the first one


The compiler tries to match the type of the lambda to the context. I don't know the exact rules, but the answer to:

What would happen if there were two SwingUtilities.invokeLater methods which differ only in parameter list?

is: it depends on what would be those parameter lists. If the other invokeLater had also exactly one parameter and that parameter would be of type that is also an interface with one method of type void*(), well, then it would complain that it cannot figure out which method you mean.

Why are they written as they are? Well, I think it's because syntax in C# and Scala is almost the same (they use => rather than ->).

2 of 4
13

The syntax is

(parameter_list_here) -> { stuff_to_do; }

The curly braces can be omitted if it's a single expression. The regular parentheses around the parameter list can be omitted if it's a single parameter.

The syntax only works for all functional interfaces. The @FunctionalInterface annotation tells the compiler that you intend to write such an interface and gives a compile error if you do not meet the requirement(s) - for example it must only have 1 overrideable method.

@FunctionalInterface
interface TestInterface {
    void dostuff();
}

Runnable is also declared like that. Other interfaces are not, and they cannot be used with lambda functions.

Now that we've made a new functional interface with a method that takes no parameters, how about we test the question you had about "collision" in the signatures?

public class Main {
    private void test(Runnable r) {

    }
    private void test(TestInterface ti) {

    }
    public static void main(String[] args) { 
        test(() -> { System.out.println("test");})
    }

    @FunctionalInterface
    interface TestInterface {
        void dostuff();
    }
}

Result: compile error: ambigouous call to method test.

You see, the compiler/VM(if done runtime) finds the appropriate methods and their parameter list and sees if the parameter is a functional interface and if it is it creates an anonymous implementation of that interface. Technically (in byte code) it's different from an anonymous class, but otherwise identical (you won't see Main$1.class files).

Your example code (courtesy of Netbeans) can also be replaced with

SwingUtilities.invokeLater(MainAppJFrame::new);

Btw. :)

🌐
Medium
medium.com › @AlexanderObregon › lambda-expressions-and-functional-programming-in-java-ce81613380a5
Lambda Expressions and Functional Programming in Java
December 5, 2023 - As Java applications grew in complexity, there was a growing need for a more streamlined approach to handle such routine tasks. A lambda expression is essentially an anonymous function; that is, a function without a name.
🌐
DZone
dzone.com › coding › java › java 8: lambda functions—usage and examples
Java 8: Lambda Functions—Usage and Examples
May 4, 2016 - Oracle decided to bring lambdas to the mainstream language on the JVM—the Java language itself—with Java 8. The introduction of lambdas required coordinated changes in the language, library, and the VM implementation: The arrow operator (“->”) for defining lambda functions, the double colon operator (“::”) used for method references, and the default keyword.
🌐
TutorialsPoint
tutorialspoint.com › java › index.htm
Java Tutorial
This means that compiled Java code can run on all platforms that support Java without the need to recompile. In this tutorial, you will learn everything about Java, starting from basics to advanced concepts such as overview, history, installations, basic input/output, conditional & control statements, arrays, classes, inheritances, method overloading & overriding, exception handling, and many more.
Top answer
1 of 11
137

Lambda expressions do not change the set of problems you can solve with Java in general, but definitely make solving certain problems easier, just for the same reason we’re not programming in assembly language anymore. Removing redundant tasks from the programmer’s work makes life easier and allows to do things you wouldn’t even touch otherwise, just for the amount of code you would have to produce (manually).

But lambda expressions are not just saving lines of code. Lambda expressions allow you to define functions, something for which you could use anonymous inner classes as a workaround before, that’s why you can replace anonymous inner classes in these cases, but not in general.

Most notably, lambda expressions are defined independently to the functional interface they will be converted to, so there are no inherited members they could access, further, they can not access the instance of the type implementing the functional interface. Within a lambda expression, this and super have the same meaning as in the surrounding context, see also this answer. Also, you can not create new local variables shadowing local variables of the surrounding context. For the intended task of defining a function, this removes a lot of error sources, but it also implies that for other use cases, there might be anonymous inner classes which can not be converted to a lambda expression, even if implementing a functional interface.

Further, the construct new Type() { … } guarantees to produce a new distinct instance (as new always does). Anonymous inner class instances always keep a reference to their outer instance if created in a non-static context¹. In contrast, lambda expressions only capture a reference to this when needed, i.e. if they access this or a non-static member. And they produce instances of an intentionally unspecified identity, which allows the implementation to decide at runtime whether to reuse existing instances (see also “Does a lambda expression create an object on the heap every time it's executed?”).

These differences apply to your example. Your anonymous inner class construct will always produce a new instance, also it may capture a reference to the outer instance, whereas your (Developer o1, Developer o2) -> o1.getName().compareTo(o2.getName()) is a non-capturing lambda expression that will evaluate to a singleton in typical implementations. Further, it doesn’t produce a .class file on your hard drive.

Given the differences regarding both, semantic and performance, lambda expressions may change the way programmers will solve certain problems in the future, of course, also due to the new APIs embracing ideas of functional programming utilizing the new language features. See also Java 8 lambda expression and first-class values.


¹ From JDK 1.1 to JDK 17. Starting with JDK 18, inner classes may not retain a reference to the outer instance if it is not used. For compatibility reasons, this requires the inner class not be serializable. This only applies if you (re)compile the inner class under JDK 18 or newer with target JDK 18 or newer. See also JDK-8271717

2 of 11
57

Programming languages are not for machines to execute.

They are for programmers to think in.

Languages are a conversation with a compiler to turn our thoughts into something a machine can execute. One of the chief complaints about Java from people who come to it from other languages (or leave it for other languages) used to be that it forces a certain mental model on the programmer (i.e. everything is a class).

I'm not going to weigh in on whether that's good or bad: everything is trade-offs. But Java 8 lambdas allow programmers to think in terms of functions, which is something you previously could not do in Java.

It's the same thing as a procedural programmer learning to think in terms of classes when they come to Java: you see them gradually move from classes that are glorified structs and have 'helper' classes with a bunch of static methods and move on to something that more closely resembles a rational OO design (mea culpa).

If you just think of them as a shorter way to express anonymous inner classes then you are probably not going to find them very impressive in the same way that the procedural programmer above probably didn't think classes were any great improvement.

🌐
Medium
medium.com › javarevisited › java-lambda-expressions-6696793a6c38
Functional Programming & Lambda Expressions | Javarevisited
March 28, 2021 - Do we have to create a functional interface for every lambda expression? Actually yes, but considering this situation, Java designers have created many functional interfaces under the java.util.function package with Java 8, suitable for common use-case scenarios.
🌐
GeeksforGeeks
geeksforgeeks.org › java › java-8-interview-questions-and-answers
Top 30 Java 8 Interview Questions and Answers for 2025 - GeeksforGeeks
July 31, 2026 - Lambda Expression basically shows an instance of functional interface in other words you could say that it provides a clear and concise way to represent a method of performing functional interface using an expression Lambda Expressions have ...
🌐
Ably
ably.com › home
Ably | Realtime platform for chat, AI and live apps at scale
September 12, 2025 - Java · .NET · Ruby · Flutter · Obj-C · Swift · PHP · Go · C#.NET · Connect with pre-built integrations for Webhooks, Lambdas, databases, cloud services, observability tools and stream processors. View all integrations · Amazon Lambda functions · Azure functions ·
🌐
Hevo
hevodata.com › home › learn › data integration
What are Java Lambda Expressions? Syntax, Rules & ...
July 21, 2026 - Pluggable InputFormat interfaces allow parsing of custom file formats including compressed archives, XML, and proprietary binary formats · Combiner functions execute reduce-like aggregations locally before the shuffle phase to reduce intermediate data volume across the network
🌐
Medium
medium.com › @kumar.atul.2122 › java-8-lambda-functional-interface-method-reference-stream-api-and-optional-class-f685143635fb
Java 8: lambda, functional interface, method reference, Stream API and Optional class | by Atul Kumar | Medium
February 19, 2023 - Lambda functions are a new feature introduced in Java 8 that provides a concise way to represent an anonymous function. An anonymous function is a function that has no name and can be passed around as a value, stored in a variable, or used as ...
🌐
Medium
medium.com › @nagarjun_nagesh › introduction-to-java-lambda-functions-94e0fbcd4cfe
Introduction to Java Lambda Functions | by Nagarjun (Arjun) Nagesh | Medium
February 23, 2024 - In Java, lambda functions are based on functional interfaces, which are interfaces with a single abstract method (SAM). The presence of only one abstract method ensures that the interface can be used with lambda expressions.
🌐
Tutorialspoint
tutorialspoint.com › java › java-lambda-expressions.htm
Java - Lambda Expressions
Using lambda expression, we've created four different implementations of MathOperation operate method to add,subtract,multiply and divide two integers and get the relative result. Then we've another functional interface GreetingService with a method sayMessage, which we've used to print a message to the console. package com.tutorialspoint; public class JavaTester { public static void main(String args[]) { JavaTester tester = new JavaTester(); //with type declaration MathOperation addition = (int a, int b) -> a + b; //with out type declaration MathOperation subtraction = (a, b) -> a - b; //with