Java Interview Questions

30 Questions
Java

Java

Web DevelopmentBackend

Question 27

What are lambda expressions in Java?

Answer:

Lambda expressions in Java are a feature introduced in Java 8 that allow you to write more concise and readable code. They enable you to treat functionality as a method argument, or to treat a block of code as data. This helps in writing cleaner, more expressive code, especially when dealing with collections and other APIs that benefit from functional-style operations.

Key Concepts of Lambda Expressions

  1. Syntax: The basic syntax of a lambda expression is (parameters) -> expression or (parameters) -> { statements; }.
  2. Functional Interface: A lambda expression can be used only in the context of a functional interface. A functional interface is an interface that contains exactly one abstract method. Examples include Runnable, Callable, Comparator, and custom functional interfaces annotated with @FunctionalInterface.

Syntax of Lambda Expressions

Basic Syntax:

(parameters) -> expression

Block Syntax:

(parameters) -> { statements; }

Examples

Example 1: Lambda Expression with No Parameters

Runnable r = () -> System.out.println("Hello, Lambda!");
r.run();  // Output: Hello, Lambda!

Example 2: Lambda Expression with One Parameter

Consumer<String> consumer = (s) -> System.out.println(s);
consumer.accept("Hello, Lambda!");  // Output: Hello, Lambda!

Example 3: Lambda Expression with Multiple Parameters

BinaryOperator<Integer> add = (a, b) -> a + b;
System.out.println(add.apply(5, 3));  // Output: 8

Example 4: Lambda Expression with Block of Statements

Comparator<Integer> comparator = (a, b) -> {
    if (a > b) return 1;
    else if (a < b) return -1;
    else return 0;
};
System.out.println(comparator.compare(10, 20));  // Output: -1

Using Lambda Expressions with Collections

Lambda expressions are particularly powerful when used with the Java Collections Framework for operations like filtering, mapping, and reducing.

Example: Using forEach with a List

List<String> list = Arrays.asList("a", "b", "c", "d");
list.forEach(item -> System.out.println(item));  // Output: a b c d

Example: Using filter with Streams

List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl");
List<String> filtered = strings.stream()
                                .filter(str -> !str.isEmpty())
                                .collect(Collectors.toList());
System.out.println(filtered);  // Output: [abc, bc, efg, abcd, jkl]

Example: Using map with Streams

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> squares = numbers.stream()
                               .map(n -> n * n)
                               .collect(Collectors.toList());
System.out.println(squares);  // Output: [1, 4, 9, 16, 25]

Example: Using reduce with Streams

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
                 .reduce(0, (a, b) -> a + b);
System.out.println(sum);  // Output: 15

Functional Interfaces

Lambda expressions work with functional interfaces. Here are some common functional interfaces in the java.util.function package:

  • Predicate<T>: Represents a boolean-valued function of one argument.

    Predicate<String> isEmpty = s -> s.isEmpty();
    System.out.println(isEmpty.test(""));  // Output: true
  • Consumer<T>: Represents an operation that accepts a single input argument and returns no result.

    Consumer<String> print = s -> System.out.println(s);
    print.accept("Hello, World!");  // Output: Hello, World!
  • Function<T, R>: Represents a function that accepts one argument and produces a result.

    Function<Integer, String> intToString = i -> Integer.toString(i);
    System.out.println(intToString.apply(123));  // Output: 123
  • Supplier<T>: Represents a supplier of results.

    Supplier<String> stringSupplier = () -> "Hello, Supplier!";
    System.out.println(stringSupplier.get());  // Output: Hello, Supplier!

Benefits of Lambda Expressions

  1. Conciseness: Reduces the boilerplate code and makes the code more concise.
  2. Readability: Improves the readability of the code by expressing the intent more clearly.
  3. Functional Programming: Facilitates functional programming paradigms, enabling more expressive and flexible code.
  4. Parallel Operations: Makes it easier to perform parallel operations on collections.

Conclusion

Lambda expressions in Java provide a powerful way to write more concise and expressive code, especially when working with collections and functional interfaces. By understanding the syntax and usage of lambda expressions, you can leverage them to improve the readability and maintainability of your Java applications.

Recent job openings