The Use of Lambda Expressions in Java Development
1. So, what the heck is a Lambda expression?
To put it simply, a Lambda expression is like a “laziness booster” that Java 8 gifted us hardworking developers. It lets you write cleaner, more elegant code.
In plain terms: it kicks out those long-winded, smelly anonymous inner classes and gives your code-base a fresh, minimalist vibe.
Especially when you’re wrangling collections like `List`, `Map`, and the like—once you bring in a Lambda, your code shrinks in half and suddenly feels way more readable.
Here's an example without Lambda (Traditional Java approach) :
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
// Print names in uppercase (before Java 8)
for (String name : names) {
System.out.println(name.toUpperCase());
}
Here's an example with Lambda (Java 8 or later) :
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
// Print names in uppercase using lambda
names.forEach(name -> System.out.println(name.toUpperCase()));
Back in the day, if you wanted to handle a button click, you had to either `new` up a listener or write a bunch of interfaces. Now? Just one Lambda line and done. It’s like a programmer’s dream tool for getting more done with less typing.
But you can’t just go slapping Lambdas everywhere. They need a trusty sidekick called a functional interface.
What’s that?
Easy—just an interface with one abstract method. Not two, not three—just one. Be greedy and try to sneak in more? Java’s not having it.
Of course, you can create your own functional interfaces, but Java’s got you covered with a bunch of ready-made ones like `Runnable`, `Callable`, `Comparator`, and more. Just grab one and roll with it—super convenient!
2. Functional Interfaces
If an interface is marked with the @FunctionalInterface annotation, then it's officially a functional interface—which means it can only have one abstract method. Here's an example of what a functional interface looks like:
@FunctionalInterface
public interface MyInterface {
void eat();
}
Even if you don’t add the @FunctionalInterface annotation, as long as the interface contains only one abstract method, it still counts as a functional interface in the eyes of Java.
public interface MyInterface {
void eat();
}
There’s only one exception to the “only one method” rule: a functional interface can still inherit methods from the Object class—like toString(), equals(), or hashCode()—and that’s totally allowed.
@FunctionalInterface
public interface MyInteface3 {
void eat();
@Override
String toString();
@Override
int hashCode();
}
3. Using Lambda Expressions
Usage inside regular methods
Student class:
@FunctionalInterface
public interface Student {
void eat();
}
Test class:
public class Test {
public static void main(String[] args) {
Student stu = new Student() {
// Regular method: override and use
@Override
public void eat() {
System.out.println("I am a student");
}
};
stu.eat();
// Lambda expression version:
// Part 1: overrides the single parameterless abstract method 'eat' in Student interface, providing implementation, so no need to write method name
// Part 2: -> operator, fixed syntax
// Part 3: {implementation body} provides the concrete implementation of the 'eat' method in Student interface
Student stu2 = () -> {
System.out.println("Student is eating");
};
stu2.eat();
}
}
Output:
I am a student
Student is eating
@FunctionalInterface
public interface Student {
void eat(String food);
}
public class Test {
public static void main(String[] args) {
// Using lambda to override the only method in the Student interface
Student stu2 = (foodName) -> {
System.out.println("The student is eating " + foodName);
};
stu2.eat("meat"); // Output: The student is eating meat
}
}
public class Test {
public static void main(String[] args) {
// Creating a thread using a lambda expression
Thread t = new Thread(() -> {
System.out.println("This thread is created using lambda");
});
t.start();
}
}
@FunctionalInterface
public interface Calculator<T> {
T operation(T v1, T v2);
}
Test Class:
public class Test {
// Calculation method
public static Integer operator(Integer v1, Integer v2, Calculator<Integer> calculator) {
return calculator.operation(v1, v2);
}
public static void main(String[] args) {
// Using a lambda expression:
// This means passing in two parameters and returning the result
int add = Test.operator(5, 10, (x, y) -> {
return x + y;
});
// Simplified version: much shorter and cleaner than above
int num1 = Test.operator(6, 12, (x, y) -> x + y);
int num2 = Test.operator(12, 6, (x, y) -> x - y);
System.out.println(add);
System.out.println(num1);
System.out.println(num2);
}
}
Output:
18 、18 、6
public interface ResultOneParam {
int method(int a);
}
public class Test {
// An instance method that adds 10 to the input
public int addTo(int a) {
return a + 10;
}
// A static method that also adds 10 to the input
public static int addTo2(int a) {
return a + 12;
}
public static void main(String[] args) {
// Lambda expression that overrides the method in the interface
ResultOneParam lambda1 = (a) -> a + 12;
// Method reference: uses the existing static method addTo2 in Test class
// as the implementation of the method in the interface
ResultOneParam lambda2 = Test::addTo2;
int result1 = lambda2.method(9);
System.out.println(result1);
// Method reference :: reuses an existing method instead of writing a new one
Test test = new Test();
ResultOneParam lambda3 = test::addTo;
int result2 = lambda3.method(9);
System.out.println(result2);
}
}
7. Using Lambda with Collections
Lambda expressions are also very convenient for operating on collections.
They allow you to write much less code when iterating or processing data in collections.
public class Test {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(6, 10, 1, 4, 5, 0, 7, 5, 0, 1, 5);
// Using a lambda expression to iterate over the list
// This overrides the accept method of the Consumer interface
list.forEach((element) -> {
System.out.println(element);
});
// Simplified version:
list.forEach(element -> System.out.println(element));
// Lambda expression with method reference to print elements in the list
list.forEach(System.out::print);
// Print only even numbers in the list:
list.forEach(element -> {
if (element % 2 == 0) {
System.out.println(element);
}
});
}
}
Comments
Post a Comment