Java 8: Lambda Functions
In Java SE 8, Lambda Expressions were introduced as a way to simplify coding and enable functional programming. They provide a concise way to write the implementation of functional interfaces (interfaces with a single abstract method), allowing developers to represent functionality as code blocks that can be passed around and executed.
What Are Lambda Expressions?
Lambda expressions eliminate the need for verbose anonymous classes when implementing functional interfaces. With Lambda, you can write cleaner and more expressive code.
Get Nikhil Sharma’s stories in your inbox
Join Medium for free to get updates from this writer.
For example, before Java 8, implementing a functional interface required writing a separate class:
Code Without Lambda Expressions:
interface FunctionalInterfaceExample {
void abstractMethod(String str);
}
class InterfaceImplementation implements FunctionalInterfaceExample {
@Override
public void abstractMethod(String str) {
System.out.println(str.length());
}
}
public class Main {
public static void main(String[] args) {
FunctionalInterfaceExample pie = new InterfaceImplementation();
pie.abstractMethod("String Example");
}
}With Lambda Expressions, the same functionality can be achieved concisely:
Code With Lambda Expressions:
interface FunctionalInterfaceExample {
void abstractMethod(String str);
}
public class Main {
public static void main(String[] args) {
FunctionalInterfaceExample pie = (x) -> System.out.println(x.length());
pie.abstractMethod("String Example");
}
}Syntax of Lambda Expressions
The general syntax of a lambda expression is:
(arguments) -> {body of the expression}Components of Lambda Expressions:- Arguments: Parameters passed to the method.
- Arrow Token (
->): Separates the arguments from the body. - Body: Logic to be executed.
Example:
(int a) -> System.out.println(a * 2);Types of Lambda Expressions
Based on Lines of Code:
- Single-line Lambda: Contains a single statement.
Example:
() -> System.out.println("Hello World");2. Block Lambda: Contains multiple statements enclosed in braces {}.
Example:
() -> {
System.out.println("Hello");
System.out.println("World");
};Based on Parameters:
- Zero Parameter: Lambda expression with no arguments.
() -> System.out.println("Zero parameter lambda");2. Single Parameter: Lambda expression with one argument.
(x) -> System.out.println("Single parameter: " + x);
// Parentheses can be omitted if there's one parameter
x -> System.out.println("Single parameter: " + x);3. Multiple Parameters: Lambda expression with more than one argument.
(x, y) -> System.out.println("Multiple parameters: " + x + y);Examples Using Lambda Expressions
Below is an example demonstrating the use of zero, single, and multiple-parameter Lambda expressions:
interface FunctionalInterfaceNoParam {
void noParamMethod();
}
interface FunctionalInterfaceOneParam {
void oneParam(String str);
}
interface FunctionalInterfaceMultipleParam {
void multiParamMethod(String a, String b);
}
public class Main {
public static void main(String[] args) {
FunctionalInterfaceNoParam noParam = () -> System.out.println("No Parameter Lambda Example");
noParam.noParamMethod();
FunctionalInterfaceOneParam singleParam = (str) -> System.out.println(str);
singleParam.oneParam("Single Parameter Lambda Example");
FunctionalInterfaceOneParam singleParam1 = str -> System.out.println(str);
singleParam1.oneParam("Single Parameter Lambda Example");
FunctionalInterfaceMultipleParam multiParam = (a, b) -> System.out.println(a + b);
multiParam.multiParamMethod("Multi", " Param");
}
}Output:
No Parameter Lambda Example
Single Parameter Lambda Example
Single Parameter Lambda Example
Multi ParamUsing Predefined Functional Interfaces
Instead of creating custom functional interfaces, we can use predefined functional interfaces like Runnable, Consumer, and BiConsumer.
Example:
import java.util.function.Consumer;
import java.util.function.BiConsumer;
public class Main {
public static void main(String[] args) {
Runnable noParamPredefined = () -> System.out.println("No Parameter Predefined Example");
noParamPredefined.run();
Consumer<String> singleParamPredefined = str -> System.out.println(str);
singleParamPredefined.accept("Single Parameter Predefined Example");
BiConsumer<String, String> multiParamPredefined = (a, b) -> System.out.println(a + b);
multiParamPredefined.accept("Multi", " Param Predefined");
}
}Output:
No Parameter Predefined Example
Single Parameter Predefined Example
Multi Param PredefinedLambda Expressions With Collections
Lambda expressions can be seamlessly used with Collections for operations like iteration.
1. Using List:
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.forEach(x -> System.out.println("The value is " + x));
}
}2. Using Set:
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) {
Set<Integer> set = new HashSet<>();
set.add(1);
set.add(2);
set.forEach(x -> System.out.println("The value is " + x));
}
}3. Using Map:
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
Map<Integer, Character> map = new HashMap<>();
map.put(1, 'a');
map.put(2, 'b');
map.forEach((key, value) -> {
System.out.println("Key: " + key + ", Value: " + value);
});
}
}Scope of Variables
- We cannot modify a variable directly inside a lambda expression unless it is effectively final, the code is an example.
2. The variable can be accessed by just creating a local variable and providing our actual output.
3. The variable can be modified but it has to be assigned to a local variable of lambda body, We can perform the task but it won’t modify the count variable.
4. Now to increment the value of count, we’ll have to use multithreading concepts. Like here we can try to use AtomicInteger.
Conclusion
Lambda Expressions in Java 8 have revolutionized the way functional programming is approached. By introducing a concise and readable syntax, they enable developers to simplify the implementation of functional interfaces. Whether you’re working with single-line expressions or handling multiple parameters, Lambdas empower you to write cleaner, more expressive code. They are especially useful when combined with Java’s predefined functional interfaces and Collections API, making tasks like iteration and data processing seamless.
Furthermore, understanding the scope of variables in Lambda expressions is key to effectively utilizing them, especially when dealing with multithreading or shared state.
As we move forward, exploring the scope of variables in Lambda expressions will enhance your understanding of how to manage variables within functional programming paradigms.







