Advanced Interfaces and Lambda

This lesson covers advanced interface features and Lambda expressions to make your code more concise.

Interface Default Methods

Java 8 introduced default methods, allowing interfaces to have method bodies.

Syntax

JAVA
public interface MyInterface {
    // Abstract method
    void abstractMethod();
    
    // Default method
    default void defaultMethod() {
        System.out.println("Default implementation");
    }
}

Example: Default Methods

JAVA
public interface Vehicle {
    void start();
    
    default void horn() {
        System.out.println("Beep beep!");
    }
    
    default void stop() {
        System.out.println("Vehicle stopped");
    }
}

public class Car implements Vehicle {
    @Override
    public void start() {
        System.out.println("Car started");
    }
    
    // Can optionally override default methods
    @Override
    public void horn() {
        System.out.println("Honk honk!");
    }
}

public class DefaultMethodDemo {
    public static void main(String[] args) {
        Car car = new Car();
        car.start();  // Car started
        car.horn();   // Honk honk! (overridden method)
        car.stop();   // Vehicle stopped (interface default)
    }
}
▶ Try it Yourself

Interface Static Methods

Java 8 introduced static methods that are called directly through the interface name.

JAVA
public interface MathUtils {
    static int add(int a, int b) {
        return a + b;
    }
    
    static int multiply(int a, int b) {
        return a * b;
    }
}

public class StaticMethodDemo {
    public static void main(String[] args) {
        System.out.println(MathUtils.add(3, 5));      // 8
        System.out.println(MathUtils.multiply(3, 5));  // 15
    }
}

Functional Interfaces

An interface with only one abstract method can be implemented with a Lambda expression.

@FunctionalInterface Annotation

JAVA
@FunctionalInterface
public interface Calculator {
    int calculate(int a, int b);
}

Common Functional Interfaces

Interface Method Description
Predicate<T> boolean test(T t) Tests a condition
Function<T,R> R apply(T t) Transforms input to output
Consumer<T> void accept(T t) Consumes input
Supplier<T> T get() Provides output

Lambda Expressions

Lambda is a shorthand for anonymous functions, introduced in Java 8.

Syntax

JAVA
(parameters) -> { body }

Example: Lambda

JAVA
// Traditional approach
Calculator add = new Calculator() {
    @Override
    public int calculate(int a, int b) {
        return a + b;
    }
};

// Lambda expression
Calculator add = (a, b) -> a + b;

// Call
int result = add.calculate(3, 5);  // 8
▶ Try it Yourself

Various Lambda Forms

JAVA
// No parameters
Runnable r = () -> System.out.println("Hello");

// One parameter
Consumer<String> print = s -> System.out.println(s);

// Multiple parameters
Comparator<String> comp = (a, b) -> a.length() - b.length();

// Multi-line body
Function<String, String> upper = s -> {
    String result = s.trim();
    return result.toUpperCase();
};

Example: Using Lambda

JAVA
import java.util.Arrays;
import java.util.List;
import java.util.function.*;

public class LambdaDemo {
    public static void main(String[] args) {
        // Predicate: test condition
        Predicate<Integer> isEven = n -> n % 2 == 0;
        System.out.println(isEven.test(4));  // true
        System.out.println(isEven.test(7));  // false
        
        // Function: transform
        Function<String, Integer> length = s -> s.length();
        System.out.println(length.apply("Hello"));  // 5
        
        // Consumer: consume
        Consumer<String> print = s -> System.out.println("Output: " + s);
        print.accept("Java");  // Output: Java
        
        // Supplier: provide
        Supplier<Double> random = () -> Math.random();
        System.out.println(random.get());
    }
}
▶ Try it Yourself

Lambda with Collections

Lambda makes collection operations more concise.

Example: Iteration

JAVA
import java.util.Arrays;
import java.util.List;

public class LambdaCollection {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
        
        // Traditional approach
        for (String name : names) {
            System.out.println(name);
        }
        
        // Lambda approach
        names.forEach(name -> System.out.println(name));
        
        // Method reference (more concise)
        names.forEach(System.out::println);
    }
}
▶ Try it Yourself

Example: Sorting

JAVA
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class LambdaSort {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Charlie", "Alice", "Bob");
        
        // Traditional approach
        Collections.sort(names, new Comparator<String>() {
            @Override
            public int compare(String a, String b) {
                return a.compareTo(b);
            }
        });
        
        // Lambda approach
        names.sort((a, b) -> a.compareTo(b));
        
        // Method reference
        names.sort(String::compareTo);
        
        System.out.println(names);  // [Alice, Bob, Charlie]
    }
}
▶ Try it Yourself

Method References

Method references are a shorthand for Lambda expressions.

Four Types of Method References

Type Syntax Example
Static method ClassName::staticMethod Math::abs
Instance method object::instanceMethod System.out::println
Specific class ClassName::instanceMethod String::length
Constructor ClassName::new ArrayList::new

Example: Method References

JAVA
import java.util.Arrays;
import java.util.List;
import java.util.function.*;

public class MethodRefDemo {
    public static void main(String[] args) {
        // Static method reference
        Function<Integer, Integer> abs = Math::abs;
        System.out.println(abs.apply(-5));  // 5
        
        // Instance method reference
        Consumer<String> print = System.out::println;
        print.accept("Hello");  // Hello
        
        // Specific class instance method reference
        Function<String, Integer> length = String::length;
        System.out.println(length.apply("Hello"));  // 5
        
        // Constructor reference
        Supplier<List<String>> listFactory = ArrayList::new;
        List<String> list = listFactory.get();
    }
}
▶ Try it Yourself

Comprehensive Example

JAVA
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class LambdaPractice {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        
        // Filter even numbers
        List<Integer> evens = numbers.stream()
            .filter(n -> n % 2 == 0)
            .collect(Collectors.toList());
        System.out.println("Evens: " + evens);  // [2, 4, 6, 8, 10]
        
        // Square
        List<Integer> squares = numbers.stream()
            .map(n -> n * n)
            .collect(Collectors.toList());
        System.out.println("Squares: " + squares);  // [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
        
        // Sum
        int sum = numbers.stream()
            .reduce(0, (a, b) -> a + b);
        System.out.println("Sum: " + sum);  // 55
        
        // Maximum
        int max = numbers.stream()
            .reduce(Integer::max)
            .orElse(0);
        System.out.println("Max: " + max);  // 10
    }
}

❓ Frequently Asked Questions

Q What's the difference between Lambda and anonymous inner classes?
A Lambda is more concise but only works with functional interfaces. Anonymous inner classes can work with any interface or class.
Q When should I use Lambda?
A When implementing functional interfaces, especially for collection operations and event handling.
Q How do I choose between method references and Lambda?
A If Lambda just calls an existing method, use method reference for conciseness.

📖 Summary

📝 Exercises

  1. Lambda practice: Use Lambda to convert strings to uppercase, get length, check if empty
  2. Collection operations: Use Lambda to filter, transform, and sort collections
  3. Custom functional interface: Define a math operation interface, implement add/subtract/multiply/divide with Lambda

Next Lesson

In the next lesson, we'll learn about Enums and Inner Classes — special classes in Java.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏