Java Lambda表达式tutorial

MasterJava Lambda表达式, writing更简洁, 更优雅 function式code

tutorialoverview

本tutorial将详细介绍Java Lambda表达式 core concepts and 实践techniques, includingLambda表达式 basic语法, function式interface, method引用, Lambda表达式 using场景etc. in 容. through本tutorial Learning, you willable towriting更加简洁, 优雅 Javacode, 充分利用function式programming 优势.

Lambda表达式overview

Lambda表达式 is Java 8引入 features, 它允许我们将functionserving asmethodparameter传递, or 者将code块serving asdataprocessing. Lambda表达式 本质 is a 匿名function, 它providing了一种更简洁 方式来表示匿名 in 部class.

Lambda表达式 优点

  • code简洁: Lambda表达式可以用更 few codeimplementation相同 functions.
  • readable 性强: Lambda表达式 语法更加清晰, able to更直观地表达code 意graph.
  • function式programming: Lambda表达式 is function式programming Basics, 使得Javaable to更 good 地supportfunction式programming范式.
  • parallelprocessing: Lambda表达式 and Stream API结合using, 可以更方便地forparallelprocessing.

Lambda表达式语法

Lambda表达式 basic语法such as under :

// Lambda表达式basic语法
(parameters) -> expression

//  or 者

(parameters) -> {
    statements;
}

语法说明

  • parameterlist: 可以 has 零个 or many 个parameter, parameterclass型可以显式声明, 也可以由编译器推断.
  • 箭头符号: -> 用于分隔parameterlist and Lambda体.
  • Lambda体: 可以 is a 表达式, 也可以 is a code块. such as果 is 表达式, 结果会自动返回; such as果 is code块, 需要usingreturn语句显式return value.

Lambda表达式example

// 无parameter, 返回常量值
() -> 42

// 单个parameter, parameterclass型由编译器推断
x -> x * 2

// 单个parameter, 显式声明parameterclass型
(int x) -> x * 2

//  many 个parameter
(x, y) -> x + y

//  many 个parameter, 显式声明parameterclass型
(int x, int y) -> x + y

// code块
(x, y) -> {
    int sum = x + y;
    return sum;
}

// 无parameter, code块
() -> {
    System.out.println("Hello");
    System.out.println("World");
}

function式interface

function式interface is 指只package含一个abstractionmethod interface. Lambda表达式只能用于function式interface. Java 8引入了@FunctionalInterface注解, 用于标记function式interface.

in 置function式interface

Java 8 in java.util.functionpackageinproviding了一些常用 function式interface:

  • Consumer<T>: 接受一个输入parameter, 没 has return value.
  • Supplier<T>: 不接受parameter, 返回一个结果.
  • Function<T, R>: 接受一个输入parameter, 返回一个结果.
  • Predicate<T>: 接受一个输入parameter, 返回一个boolean值.
  • UnaryOperator<T>: 接受一个parameter, 返回相同class型 结果.
  • BinaryOperator<T>: 接受两个相同class型 parameter, 返回相同class型 结果.

自定义function式interface

// 自定义function式interface
@FunctionalInterface
interface Calculator {
    int calculate(int a, int b);
}

// usingLambda表达式implementationfunction式interface
public class FunctionalInterfaceExample {
    public static void main(String[] args) {
        // implementation加法
        Calculator addition = (a, b) -> a + b;
        System.out.println("10 + 5 = " + addition.calculate(10, 5));
        
        // implementation减法
        Calculator subtraction = (a, b) -> a - b;
        System.out.println("10 - 5 = " + subtraction.calculate(10, 5));
        
        // implementation乘法
        Calculator multiplication = (a, b) -> a * b;
        System.out.println("10 * 5 = " + multiplication.calculate(10, 5));
        
        // implementation除法
        Calculator division = (a, b) -> a / b;
        System.out.println("10 / 5 = " + division.calculate(10, 5));
    }
}

using in 置function式interface

import java.util.function.*;

public class BuiltInFunctionalInterfacesExample {
    public static void main(String[] args) {
        // Consumer<T>: 接受一个parameter, 无return value
        Consumer<String> consumer = s -> System.out.println("Hello, " + s);
        consumer.accept("World");
        
        // Supplier<T>: 无parameter, 返回一个结果
        Supplier<Double> supplier = () -> Math.random();
        System.out.println("随机数: " + supplier.get());
        
        // Function<T, R>: 接受一个parameter, 返回一个结果
        Function<Integer, String> function = i -> "number: " + i;
        System.out.println(function.apply(42));
        
        // Predicate<T>: 接受一个parameter, 返回boolean值
        Predicate<Integer> predicate = i -> i > 0;
        System.out.println("10 > 0: " + predicate.test(10));
        System.out.println("-5 > 0: " + predicate.test(-5));
        
        // UnaryOperator<T>: 接受一个parameter, 返回相同class型 结果
        UnaryOperator<Integer> unaryOperator = i -> i * 2;
        System.out.println("10 * 2 = " + unaryOperator.apply(10));
        
        // BinaryOperator<T>: 接受两个相同class型 parameter, 返回相同class型 结果
        BinaryOperator<Integer> binaryOperator = (a, b) -> a + b;
        System.out.println("10 + 5 = " + binaryOperator.apply(10, 5));
    }
}

Lambda表达式 using场景

1. threadcreation

// usingLambda表达式creationthread
Thread thread = new Thread(() -> {
    for (int i = 0; i < 5; i++) {
        System.out.println("thread执行: " + i);
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
});

thread.start();

2. collectionoperation

import java.util.ArrayList;
import java.util.List;
import java.util.Collections;

public class CollectionOperationsExample {
    public static void main(String[] args) {
        List names = new ArrayList<>();
        names.add("Alice");
        names.add("Bob");
        names.add("Charlie");
        names.add("David");
        names.add("Eve");
        
        // usingLambda表达式遍历collection
        System.out.println("=== 遍历collection ===");
        names.forEach(name -> System.out.println(name));
        
        // usingLambda表达式sort
        System.out.println("\n=== sortcollection ===");
        Collections.sort(names, (s1, s2) -> s1.compareTo(s2));
        names.forEach(name -> System.out.println(name));
        
        // usingLambda表达式sort (降序) 
        System.out.println("\n=== 降序sort ===");
        Collections.sort(names, (s1, s2) -> s2.compareTo(s1));
        names.forEach(name -> System.out.println(name));
    }
}

3. eventprocessing

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class EventHandlingExample {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Lambdaeventprocessingexample");
        JButton button = new JButton("点击我");
        
        // usingLambda表达式processingevent
        button.addActionListener((ActionEvent e) -> {
            System.out.println("按钮被点击了!");
        });
        
        frame.add(button);
        frame.setSize(300, 200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

4. function式interfaceimplementation

import java.util.function.Function;

public class FunctionalInterfaceImplementationExample {
    // 接受一个Functioninterfaceserving asparameter
    public static <T, R> R process(T input, Function<T, R> function) {
        return function.apply(input);
    }
    
    public static void main(String[] args) {
        // usingLambda表达式implementationFunctioninterface
        String result1 = process("Hello", s -> s.toUpperCase());
        System.out.println("转换 for  big 写: " + result1);
        
        Integer result2 = process("123", s -> Integer.parseInt(s));
        System.out.println("转换 for 整数: " + result2);
        
        String result3 = process(42, i -> "number: " + i);
        System.out.println("转换 for string: " + result3);
    }
}

method引用

method引用 is Lambda表达式 一种简化形式, 它允许我们直接引用已 has method, 而不需要writingLambda体. method引用using双冒号(::)operation符.

method引用 class型

  • 静态method引用: ClassName::staticMethodName
  • instancemethod引用: instance::instanceMethodName
  • objectmethod引用: ClassName::instanceMethodName
  • constructmethod引用: ClassName::new

method引用example

import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
import java.util.function.Function;
import java.util.function.BiFunction;

public class MethodReferenceExample {
    // 静态method
    public static String staticMethod(String s) {
        return s.toUpperCase();
    }
    
    // instancemethod
    public String instanceMethod(String s) {
        return s.toLowerCase();
    }
    
    public static void main(String[] args) {
        List names = new ArrayList<>();
        names.add("Alice");
        names.add("Bob");
        names.add("Charlie");
        
        System.out.println("=== 静态method引用 ===");
        // 静态method引用
        names.forEach(System.out::println);
        
        // using静态method引用serving asFunction
        Function staticFunction = MethodReferenceExample::staticMethod;
        System.out.println(staticFunction.apply("hello"));
        
        System.out.println("\n=== instancemethod引用 ===");
        // instancemethod引用
        MethodReferenceExample instance = new MethodReferenceExample();
        Function instanceFunction = instance::instanceMethod;
        System.out.println(instanceFunction.apply("HELLO"));
        
        System.out.println("\n=== objectmethod引用 ===");
        // objectmethod引用
        Function lengthFunction = String::length;
        System.out.println(""Hello".length() = " + lengthFunction.apply("Hello"));
        
        // objectmethod引用 (两个parameter) 
        BiFunction charAtFunction = String::charAt;
        System.out.println(""Hello".charAt(1) = " + charAtFunction.apply("Hello", 1));
        
        System.out.println("\n=== constructmethod引用 ===");
        // constructmethod引用
        Supplier> supplier = ArrayList::new;
        List newList = supplier.get();
        newList.add("Test");
        System.out.println(" new list: " + newList);
        
        // constructmethod引用 (带parameter) 
        Function> arrayListFunction = ArrayList::new;
        List sizedList = arrayListFunction.apply(10);
        System.out.println("指定容量 list: " + sizedList);
        System.out.println("list容量: " + sizedList.size());
    }
}

Lambda表达式 and Stream API

Lambda表达式 and Stream API结合using, 可以更方便地forcollectionoperation and parallelprocessing.

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class LambdaAndStreamExample {
    public static void main(String[] args) {
        List numbers = new ArrayList<>();
        for (int i = 1; i <= 10; i++) {
            numbers.add(i);
        }
        
        System.out.println("原始list: " + numbers);
        
        // usingStream API and Lambda表达式filter偶数
        List evenNumbers = numbers.stream()
                .filter(n -> n % 2 == 0)
                .collect(Collectors.toList());
        System.out.println("偶数list: " + evenNumbers);
        
        // usingStream API and Lambda表达式将每个元素乘以2
        List doubledNumbers = numbers.stream()
                .map(n -> n * 2)
                .collect(Collectors.toList());
        System.out.println("每个元素乘以2: " + doubledNumbers);
        
        // usingStream API and Lambda表达式计算总 and 
        int sum = numbers.stream()
                .reduce(0, (a, b) -> a + b);
        System.out.println("总 and : " + sum);
        
        // usingStream API and Lambda表达式计算平均值
        double average = numbers.stream()
                .mapToInt(Integer::intValue)
                .average()
                .orElse(0);
        System.out.println("平均值: " + average);
        
        // usingStream API and Lambda表达式sort
        List sortedNumbers = numbers.stream()
                .sorted((a, b) -> b - a) // 降序sort
                .collect(Collectors.toList());
        System.out.println("降序sort: " + sortedNumbers);
        
        // usingStream API and Lambda表达式去重
        List numbersWithDuplicates = new ArrayList<>();
        numbersWithDuplicates.add(1);
        numbersWithDuplicates.add(2);
        numbersWithDuplicates.add(2);
        numbersWithDuplicates.add(3);
        numbersWithDuplicates.add(3);
        numbersWithDuplicates.add(3);
        
        List distinctNumbers = numbersWithDuplicates.stream()
                .distinct()
                .collect(Collectors.toList());
        System.out.println("去重 before : " + numbersWithDuplicates);
        System.out.println("去重 after : " + distinctNumbers);
    }
}

实践case

Lambda表达式implementation计算器

本caseusingLambda表达式 and function式interfaceimplementation一个 simple 计算器, supportbasic 算术运算.

import java.util.HashMap;
import java.util.Map;
import java.util.function.BiFunction;

public class CalculatorExample {
    // 定义一个计算interface
    @FunctionalInterface
    interface Operation {
        double calculate(double a, double b);
    }
    
    public static void main(String[] args) {
        // creationoperationmap
        Map operations = new HashMap<>();
        
        // usingLambda表达式implementation加法
        operations.put("+", (a, b) -> a + b);
        
        // usingLambda表达式implementation减法
        operations.put("-", (a, b) -> a - b);
        
        // usingLambda表达式implementation乘法
        operations.put("*", (a, b) -> a * b);
        
        // usingLambda表达式implementation除法
        operations.put("/", (a, b) -> {
            if (b == 0) {
                throw new ArithmeticException("除数不能 for 零");
            }
            return a / b;
        });
        
        // test计算器
        double a = 10.0;
        double b = 5.0;
        
        for (Map.Entry entry : operations.entrySet()) {
            String operator = entry.getKey();
            Operation operation = entry.getValue();
            try {
                double result = operation.calculate(a, b);
                System.out.printf("%.2f %s %.2f = %.2f%n", a, operator, b, result);
            } catch (Exception e) {
                System.out.printf("%.2f %s %.2f = error: %s%n", a, operator, b, e.getMessage());
            }
        }
        
        // test除法errorcircumstances
        double c = 10.0;
        double d = 0.0;
        Operation division = operations.get("/");
        try {
            double result = division.calculate(c, d);
            System.out.printf("%.2f / %.2f = %.2f%n", c, d, result);
        } catch (Exception e) {
            System.out.printf("%.2f / %.2f = error: %s%n", c, d, e.getMessage());
        }
    }
}

互动练习

练习1: Lambda表达式Basics

usingLambda表达式implementation一个Runnableinterface, in run()methodin打印"Hello, Lambda!", 然 after creation一个Threadobject并启动它.

练习2: function式interface

creation一个function式interfaceConverter, package含一个convertmethod, 用于将一种class型转换 for 另一种class型. 然 after usingLambda表达式implementation这个interface, 将String转换 for Integer.

练习3: method引用

creation一个List, 然 after usingmethod引用遍历collection并打印每个元素. 再usingmethod引用 for collectionforsort.

练习4: Stream API and Lambda

creation一个List, package含1 to 10 整数. 然 after usingStream API and Lambda表达式:

  1. filter出 big 于5 number
  2. 将每个number平方
  3. 计算所 has 结果 总 and
  4. 打印最终结果