Java 8 + 中 Lambda 表达式与 Stream API 的应用解析

0 阅读8分钟

j以下是结合Java最新技术(Java 8+)的实操内容,涵盖核心概念与应用场景,并附代码说明:

1. Lambda表达式与Stream API(Java 8+)

说明
Lambda表达式简化匿名函数编写,Stream API提供高效的集合处理能力。
应用场景:集合过滤、映射、聚合操作。

实操案例:统计字符串列表中长度大于5的元素数量。

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

public class LambdaStreamDemo {
    public static void main(String[] args) {
        List<String> words = Arrays.asList("Java", "Stream", "Lambda", "Programming");
        
        // 使用Lambda和Stream统计长度>5的元素
        long count = words.stream()
                          .filter(word -> word.length() > 5)
                          .count();
        
        System.out.println("长度大于5的单词数量:" + count);
    }
}

代码解析

  • words.stream():将列表转换为流。
  • filter(word -> word.length() > 5):使用Lambda过滤长度>5的元素。
  • count():终止操作,统计元素数量。

2. 函数式接口(Java 8+)

说明
函数式接口是只包含一个抽象方法的接口,可被Lambda表达式实现。
应用场景:事件处理、回调函数、自定义工具类。

实操案例:自定义函数式接口实现字符串转换。

@FunctionalInterface
interface StringTransformer {
    String transform(String input);
}

public class FunctionalInterfaceDemo {
    public static void main(String[] args) {
        // 使用Lambda实现接口:将字符串转为大写
        StringTransformer toUpperCase = str -> str.toUpperCase();
        
        // 使用Lambda实现接口:截取前3个字符
        StringTransformer truncate = str -> str.substring(0, Math.min(3, str.length()));
        
        System.out.println(toUpperCase.transform("hello"));  // 输出: HELLO
        System.out.println(truncate.transform("world"));    // 输出: wor
    }
}

代码解析

  • @FunctionalInterface:声明函数式接口。
  • StringTransformer:自定义函数式接口,包含transform方法。
  • Lambda表达式直接实现接口方法。

3. Optional类(Java 8+)

说明
Optional用于处理可能为null的值,避免NullPointerException。
应用场景:方法返回值可能为空的场景。

实操案例:从Map中获取值并处理可能的空值。

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

public class OptionalDemo {
    public static void main(String[] args) {
        Map<String, Integer> scores = new HashMap<>();
        scores.put("Alice", 95);
        
        // 使用Optional避免空值异常
        Optional<Integer> aliceScore = Optional.ofNullable(scores.get("Alice"));
        Optional<Integer> bobScore = Optional.ofNullable(scores.get("Bob"));
        
        // 存在则打印,否则提供默认值
        System.out.println(aliceScore.orElse(0));  // 输出: 95
        System.out.println(bobScore.orElse(0));    // 输出: 0
        
        // 存在则执行操作
        aliceScore.ifPresent(score -> System.out.println("Alice的分数:" + score));
    }
}

代码解析

  • Optional.ofNullable():创建可能包含null的Optional对象。
  • orElse():提供默认值。
  • ifPresent():存在值时执行操作。

4. 接口默认方法与静态方法(Java 8+)

说明
接口可定义默认方法(default)和静态方法,增强接口扩展性。
应用场景:为现有接口添加新功能而不破坏实现类。

实操案例:定义一个包含默认方法的接口。

interface Shape {
    double area();  // 抽象方法
    
    // 默认方法:计算周长
    default double perimeter() {
        System.out.println("计算周长的默认实现");
        return 0;
    }
    
    // 静态方法:创建空形状
    static Shape createEmpty() {
        return () -> 0;  // Lambda实现抽象方法
    }
}

// 实现接口
class Circle implements Shape {
    private double radius;
    
    public Circle(double radius) {
        this.radius = radius;
    }
    
    @Override
    public double area() {
        return Math.PI * radius * radius;
    }
    
    @Override
    public double perimeter() {
        return 2 * Math.PI * radius;
    }
}

public class InterfaceDefaultMethodDemo {
    public static void main(String[] args) {
        Shape circle = new Circle(5);
        System.out.println("面积:" + circle.area());       // 输出: 78.539...
        System.out.println("周长:" + circle.perimeter());  // 输出: 31.415...
        
        Shape emptyShape = Shape.createEmpty();
        System.out.println("空形状面积:" + emptyShape.area());  // 输出: 0
    }
}

代码解析

  • default double perimeter():接口默认方法,提供通用实现。
  • static Shape createEmpty():接口静态方法,直接通过接口调用。

5. 模块化系统(Java 9+)

说明
Java 9引入模块系统(Jigsaw),通过module-info.java声明模块依赖与导出。
应用场景:大型项目的组件化、减少依赖冲突。

实操案例:创建一个简单的模块化项目。
项目结构

myproject/
├── moduleA/
│   ├── src/
│   │   └── module-info.java
│   │   └── com/example/modulea/Hello.java
└── moduleB/
    ├── src/
    │   └── module-info.java
    │   └── com/example/moduleb/Main.java

module-info.java(moduleA)

module moduleA {
    exports com.example.modulea;  // 导出包
}

Hello.java(moduleA)

package com.example.modulea;

public class Hello {
    public static void sayHello() {
        System.out.println("Hello from ModuleA!");
    }
}

module-info.java(moduleB)

module moduleB {
    requires moduleA;  // 依赖moduleA
}

Main.java(moduleB)

package com.example.moduleb;

import com.example.modulea.Hello;

public class Main {
    public static void main(String[] args) {
        Hello.sayHello();  // 调用moduleA的类
    }
}

编译与运行

# 编译模块
javac -d out --module-source-path . $(find . -name "*.java")


# 运行模块
java --module-path out -m moduleB/com.example.moduleb.Main

代码解析

  • exports:声明模块导出的包。
  • requires:声明模块依赖。
  • 模块系统强制封装性,未导出的包无法被外部访问。

6. 集合工厂方法(Java 9+)

说明
Java 9+ 为List、Set、Map提供静态工厂方法(of())创建不可变集合。
应用场景:快速创建常量集合。

实操案例:创建不可变集合。

import java.util.List;
import java.util.Map;
import java.util.Set;

public class CollectionFactoryDemo {
    public static void main(String[] args) {
        // 创建不可变List
        List<String> fruits = List.of("Apple", "Banana", "Cherry");
        
        // 创建不可变Set
        Set<Integer> numbers = Set.of(1, 2, 3);
        
        // 创建不可变Map
        Map<String, Integer> scores = Map.of("Alice", 95, "Bob", 88);
        
        System.out.println(fruits);  // 输出: [Apple, Banana, Cherry]
        System.out.println(numbers); // 输出: [1, 2, 3]
        System.out.println(scores);  // 输出: {Alice=95, Bob=88}
        
        // 以下操作会抛出UnsupportedOperationException
        // fruits.add("Date");
    }
}

代码解析

  • List.of()Set.of()Map.of():创建不可变集合,元素不可添加/删除。

7. 本地变量类型推断(Java 10+)

说明
使用var关键字自动推断变量类型,简化代码。
应用场景:局部变量声明,避免冗长类型声明。

实操案例:使用var简化变量声明。

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

public class VarDemo {
    public static void main(String[] args) {
        // 推断为ArrayList<String>
        var names = new ArrayList<String>();
        names.add("Alice");
        names.add("Bob");
        
        // 推断为String
        var message = "Hello, Java 10+!";
        
        // 推断为Integer
        var sum = calculateSum(10, 20);
        
        System.out.println(names);    // 输出: [Alice, Bob]
        System.out.println(message);  // 输出: Hello, Java 10+!
        System.out.println(sum);      // 输出: 30
    }
    
    private static int calculateSum(int a, int b) {
        return a + b;
    }
}

代码解析

  • var根据右侧表达式自动推断类型,但不能用于方法参数、字段声明。

8. 文本块(Java 13+)

说明
使用"""创建多行字符串,避免转义和拼接。
应用场景:SQL语句、JSON、HTML模板。

实操案例:创建SQL查询文本块。

public class TextBlockDemo {
    public static void main(String[] args) {
        // 使用文本块创建SQL查询
        String sql = """
            SELECT * FROM users
            WHERE age > 18
            AND country = 'China'
            ORDER BY name DESC;
            """;
        
        // 使用文本块创建JSON
        String json = """
            {
                "name": "Alice",
                "age": 25,
                "city": "Beijing"
            }
            """;
        
        System.out.println(sql);
        System.out.println(json);
    }
}

代码解析

  • 文本块保留缩进和换行,无需手动添加\n和转义字符。

9. 模式匹配(Java 14+)

说明
instanceof可直接绑定变量,简化类型转换。
应用场景:类型检查与转换的场景。

实操案例:使用模式匹配简化类型转换。

public class PatternMatchingDemo {
    public static void main(String[] args) {
        Object obj = "Hello";
        
        // 传统写法
        if (obj instanceof String) {
            String str = (String) obj;  // 显式转换
            System.out.println("字符串长度:" + str.length());
        }
        
        // 模式匹配写法(Java 14+)
        if (obj instanceof String str) {  // 直接绑定变量
            System.out.println("字符串长度:" + str.length());
        }
    }
}

代码解析

  • obj instanceof String str:若obj是String类型,直接创建变量str并赋值。

10. 记录类(Java 16+)

说明
record关键字自动生成不可变数据类(getter、equals、hashCode、toString)。
应用场景:简单数据载体(DTO、POJO)。

实操案例:使用记录类定义数据结构。

// 定义记录类
record Person(String name, int age) {
    // 可添加自定义构造器
    public Person {
        if (age < 0) {
            throw new IllegalArgumentException("年龄不能为负数");
        }
    }
    
    // 可添加自定义方法
    public String greet() {
        return "Hello, I'm " + name + ", " + age + " years old.";
    }
}

public class RecordDemo {
    public static void main(String[] args) {
        // 创建实例
        Person person = new Person("Alice", 25);
        
        // 自动生成的访问器
        System.out.println(person.name());  // 输出: Alice
        System.out.println(person.age());   // 输出: 25
        
        // 自动生成的toString
        System.out.println(person);  // 输出: Person[name=Alice, age=25]
        
        // 自定义方法
        System.out.println(person.greet());  // 输出: Hello, I'm Alice, 25 years old.
    }
}

代码解析

  • record Person(String name, int age):自动生成私有final字段、构造器、getter等。

11. 密封类(Java 17+)

说明
sealed关键字限制类的继承,明确允许的子类。
应用场景:控制继承层次,如状态机、策略模式。

实操案例:使用密封类定义形状层次。

// 密封类:只允许Circle和Rectangle继承
public sealed interface Shape permits Circle, Rectangle {
    double area();
}

// 具体实现类
final class Circle implements Shape {
    private double radius;
    
    public Circle(double radius) {
        this.radius = radius;
    }
    
    @Override
    public double area() {
        return Math.PI * radius * radius;
    }
}

// 具体实现类
final class Rectangle implements Shape {
    private double width;
    private double height;
    
    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }
    
    @Override
    public double area() {
        return width * height;
    }
}

public class SealedClassDemo {
    public static void main(String[] args) {
        Shape circle = new Circle(5);
        Shape rectangle = new Rectangle(4, 6);
        
        System.out.println("圆面积:" + circle.area());      // 输出: 78.539...
        System.out.println("矩形面积:" + rectangle.area());  // 输出: 24.0
    }
}

代码解析

  • sealed interface Shape permits Circle, Rectangle:仅允许Circle和Rectangle实现Shape。
  • final类防止进一步继承,确保继承层次可控。

12. 虚拟线程(Java 19+)

说明
轻量级线程(JEP 425),由JVM调度,大幅提升并发性能。
应用场景:高并发I/O密集型应用(如Web服务器)。

实操案例:使用虚拟线程处理大量并发任务。

import java.time.Duration;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class VirtualThreadDemo {
    public static void main(String[] args) throws InterruptedException {
        // 创建虚拟线程池
        try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
            // 模拟10万个并发请求
            for (int i = 0; i < 100_000; i++) {
                final int taskId = i;
                executor.submit(() -> {
                    // 模拟耗时操作
                    Thread.sleep(Duration.ofMillis(100));
                    System.out.println("任务 " + taskId + " 由线程 " + Thread.currentThread().getName() + " 执行");
                    return taskId;
                });
            }
        }  // 自动关闭线程池
    }
}

代码解析

  • Executors.newVirtualThreadPerTaskExecutor():创建虚拟线程池。
  • 虚拟线程可创建百万级别,占用内存极少(约200KB/线程),适合高并发场景。

总结

通过以上实操案例,我们结合Java 8+的新特性展示了:

  1. 函数式编程(Lambda、Stream、函数式接口)
  2. 空值安全(Optional)
  3. 代码简化(var、文本块、记录类)
  4. 模块化与封装(模块系统、密封类)
  5. 高性能并发(虚拟线程)

这些技术使Java代码更简洁、安全且高效,建议在新项目中积极使用。


Java 8,Lambda 表达式,Stream API, 函数式编程,Java 开发,集合处理,并行流,Stream 操作,Predicate,Consumer,Java 函数接口,Stream 管道,Java 新特性,forEach,collect



代码获取方式 pan.quark.cn/s/14fcf913b…