亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Industrial programming >> java

掌握 Java Lambda 表达式:从基础到 Stream API 实战

掌握 Java Lambda 表达式

探索 Java Lambda 表达式、函数式接口、泛型与 Stream API,配清晰示例。

Java 8 引入 Lambda 表达式增强语言表达力,让开发者编写更简洁可读的代码。

深入前需理解函数式接口——Lambda 实现的基石。


什么是函数式接口?

函数式接口是仅包含一个抽象方法的 Java 接口。该单一方法定义接口用途。

java.lang 的 Runnable 是经典例子,仅暴露 run() 方法。

示例 1:定义函数式接口

import java.lang.FunctionalInterface;
@FunctionalInterface
public interface MyInterface {
    // 单一抽象方法
    double getValue();
}

@FunctionalInterface 注解强制编译器遵守函数式接口契约,防止意外添加多个抽象方法。注解可选但强烈推荐以提高清晰度和安全性。

Java 7 中函数式接口称为单一抽象方法(SAM),通常用匿名类实现。

示例 2:用匿名类实现 SAM

public class FunctionInterfaceTest {
    public static void main(String[] args) {
        // 匿名类实现 Runnable
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("I just implemented the Runnable Functional Interface.");
            }
        }).start();
    }
}

输出:

I just implemented the Runnable Functional Interface.

匿名类虽比传统实现减少样板代码,但语法仍冗长。Lambda 表达式消除传递函数式接口为参数时的显式方法名。


Lambda 表达式简介

Lambda 表达式本质是匿名方法,为函数式接口的抽象方法提供简洁实现。不独立执行,而是为接口方法提供行为。

如何在 Java 中定义 Lambda 表达式

通用语法:

(parameter list) -> lambda body

箭头操作符(->)分隔参数列表与主体。具体示例如下。

假设有返回 Pi 的方法:

double getPiValue() { return 3.1415; }

用 Lambda:

() -> 3.1415

无参数时箭头左侧为空,右侧为返回值的表达式主体。


Lambda 主体类型

Java Lambda 主体有两种形式:

1. 表达式主体 – 含单一表达式。

() -> System.out.println("Lambdas are great");

2. 代码块主体 – 用大括号包裹,允许多语句和可选 return。

() -> { double pi = 3.1415; return pi; };

注意:表达式主体不需显式 return,代码块主体若返回值则需 return。


示例 3:Lambda 表达式实战

编写程序用 Lambda 返回 Pi:

import java.lang.FunctionalInterface;
@FunctionalInterface
interface MyInterface {
    double getPiValue();
}
public class Main {
    public static void main(String[] args) {
        MyInterface ref = () -> 3.1415;
        System.out.println("Value of Pi = " + ref.getPiValue());
    }
}

输出:

Value of Pi = 3.1415

要点:


带参数的 Lambda 表达式

Lambda 可接受参数,如方法。示例:

(n) -> (n % 2) == 0

此 Lambda 判断输入整数是否为偶数。

示例 4:用参数化 Lambda 反转字符串

@FunctionalInterface
interface MyInterface {
    String reverse(String s);
}
public class Main {
    public static void main(String[] args) {
        MyInterface ref = (str) -> {
            String result = "";
            for (int i = str.length() - 1; i >= 0; i--) {
                result += str.charAt(i);
            }
            return result;
        };
        System.out.println("Lambda reversed = " + ref.reverse("Lambda"));
    }
}

输出:

Lambda reversed = adbmaL

泛型函数式接口

函数式接口可为泛型,操作任意数据类型。例如:

@FunctionalInterface
interface MyInterface {
    T func(T t);
}

示例 5:字符串与整数的泛型 Lambda

public class Main {
    public static void main(String[] args) {
        // 字符串反转
        MyInterface reverse = (str) -> {
            String result = "";
            for (int i = str.length() - 1; i >= 0; i--) {
                result += str.charAt(i);
            }
            return result;
        };
        System.out.println("Lambda reversed = " + reverse.func("Lambda"));
        // 整数阶乘
        MyInterface factorial = (n) -> {
            int result = 1;
            for (int i = 1; i <= n; i++) {
                result *= i;
            }
            return result;
        };
        System.out.println("factorial of 5 = " + factorial.func(5));
    }
}

输出:

Lambda reversed = adbmaL
factorial of 5 = 120

Lambda 表达式与 Stream API

java.util.stream 包(JDK 8 引入)赋能开发者对集合执行函数式操作:过滤、映射、归约、排序等。

考虑地名列表,每个以国家为前缀。用流和 Lambda 高效提取操作数据。

示例 6:带 Lambda 的流处理

import java.util.ArrayList;
import java.util.List;
public class StreamMain {
    static List places = new ArrayList<>();
    public static List getPlaces() {
        places.add("Nepa, Kathmandu");
        places.add("Nepa, Pokhara");
        places.add("India, Delhi");
        places.add("USA, New York");
        places.add("Africa, Nigeria");
        return places;
    }
    public static void main(String[] args) {
        List myPlaces = getPlaces();
        System.out.println("Places from Nepal:");
        myPlaces.stream()
            .filter(p -> p.startsWith("Nepa"))
            .map(p -> p.toUpperCase())
            .sorted()
            .forEach(p -> System.out.println(p));
    }
}

输出:

Places from Nepal:
NEPA, KATHMANDU
NEPA, POKHARA

流操作链——filter、map、sorted、forEach——各接受 Lambda,相比 Java 8 前大幅减少样板代码。

java

  1. 掌握 C# 接口:定义、实现与实战场景全解析
  2. 精通 Java 运算符:类型、语法与实战示例
  3. 理解 Java 表达式、语句与代码块
  4. 精通 Java 接口:概念、实现与最佳实践
  5. 精通 Java Try-With-Resources:自动资源管理详解
  6. Java 注解详解:类型、放置位置与实战示例
  7. 掌握 Java NavigableSet 接口:导航、排序与实战示例
  8. Java 接口 vs 抽象类:如何选择合适的抽象方式
  9. Java 正则表达式完全指南:掌握 java.util.regex 模式匹配
  10. Java 接口全解析:定义契约、默认方法、多实现与标记接口
  11. Java 9 接口私有方法:增强封装与代码复用
  12. 精通 Java 8 Lambda 表达式:函数式编程入门指南