Skip to content

Java 8新特性

Java 8是Java历史上最重要的版本之一,引入了函数式编程特性。

Lambda表达式

基本语法

java
// 传统方式
Runnable r1 = new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello");
    }
};

// Lambda表达式
Runnable r2 = () -> System.out.println("Hello");

// 带参数
Comparator<String> c1 = (s1, s2) -> s1.compareTo(s2);

// 带返回值
Callable<Integer> callable = () -> 42;

// 多行代码
Runnable r3 = () -> {
    System.out.println("第一行");
    System.out.println("第二行");
};

Lambda语法规则

java
// 无参数
() -> System.out.println("Hello")

// 单参数(可省略括号)
s -> System.out.println(s)
(String s) -> System.out.println(s)

// 多参数
(a, b) -> a + b
(int a, int b) -> a + b

// 单行表达式(自动返回)
(a, b) -> a + b

// 代码块(需要显式return)
(a, b) -> {
    int sum = a + b;
    return sum;
}

函数式接口

内置函数式接口

java
import java.util.function.*;

public class FunctionalInterfaceDemo {
    public static void main(String[] args) {
        // Predicate<T> - 接收T,返回boolean
        Predicate<String> isEmpty = s -> s.isEmpty();
        System.out.println(isEmpty.test(""));  // true
        
        // Consumer<T> - 接收T,无返回值
        Consumer<String> printer = s -> System.out.println(s);
        printer.accept("Hello");
        
        // Function<T, R> - 接收T,返回R
        Function<String, Integer> length = s -> s.length();
        System.out.println(length.apply("Hello"));  // 5
        
        // Supplier<T> - 无参数,返回T
        Supplier<String> supplier = () -> "Hello";
        System.out.println(supplier.get());
        
        // UnaryOperator<T> - 接收T,返回T
        UnaryOperator<Integer> square = x -> x * x;
        System.out.println(square.apply(5));  // 25
        
        // BinaryOperator<T> - 接收两个T,返回T
        BinaryOperator<Integer> add = (a, b) -> a + b;
        System.out.println(add.apply(1, 2));  // 3
        
        // 基本类型特化
        IntPredicate isPositive = n -> n > 0;
        IntToLongFunction intToLong = n -> (long) n;
        LongBinaryOperator longAdd = (a, b) -> a + b;
    }
}

自定义函数式接口

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

// 使用
Calculator add = (a, b) -> a + b;
Calculator multiply = (a, b) -> a * b;

System.out.println(add.calculate(1, 2));      // 3
System.out.println(multiply.calculate(2, 3)); // 6

方法引用

四种形式

java
import java.util.*;
import java.util.function.*;

public class MethodReferenceDemo {
    public static void main(String[] args) {
        // 1. 静态方法引用:ClassName::staticMethod
        Function<String, Integer> parser = Integer::parseInt;
        System.out.println(parser.apply("123"));  // 123
        
        // 2. 实例方法引用:instance::method
        String str = "Hello";
        Supplier<String> supplier = str::toUpperCase;
        System.out.println(supplier.get());  // HELLO
        
        // 3. 类的实例方法引用:ClassName::method
        Function<String, Integer> length = String::length;
        System.out.println(length.apply("Hello"));  // 5
        
        BiFunction<String, String, Boolean> equals = String::equals;
        System.out.println(equals.apply("Hello", "Hello"));  // true
        
        // 4. 构造方法引用:ClassName::new
        Supplier<List<String>> listSupplier = ArrayList::new;
        List<String> list = listSupplier.get();
        
        Function<Integer, String[]> arrayCreator = String[]::new;
        String[] array = arrayCreator.apply(5);
    }
}

Stream API

Stream API 简介

Stream API 是 Java 8 引入的函数式数据处理API,用于处理集合数据。

基本操作

java
import java.util.*;
import java.util.stream.*;

public class StreamDemo {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("apple", "banana", "orange", "grape");
        
        // 过滤
        list.stream()
            .filter(s -> s.length() > 5)
            .forEach(System.out::println);  // banana, orange
        
        // 映射
        list.stream()
            .map(String::toUpperCase)
            .forEach(System.out::println);  // APPLE, BANANA, ORANGE, GRAPE
        
        // 排序
        list.stream()
            .sorted()
            .forEach(System.out::println);  // apple, banana, grape, orange
        
        // 收集
        List<String> result = list.stream()
            .filter(s -> s.startsWith("a"))
            .collect(Collectors.toList());
        
        // 聚合
        int sum = IntStream.range(1, 10)
            .sum();
        System.out.println(sum);  // 45
    }
}

Optional类

Optional 简介

Optional 类是 Java 8 引入的用于处理空值的类,避免 NullPointerException。

基本使用

java
import java.util.Optional;

public class OptionalDemo {
    public static void main(String[] args) {
        // 创建 Optional
        Optional<String> empty = Optional.empty();
        Optional<String> nonEmpty = Optional.of("Hello");
        Optional<String> nullable = Optional.ofNullable(null);
        
        // 检查值是否存在
        if (nonEmpty.isPresent()) {
            System.out.println(nonEmpty.get());
        }
        
        // 消费值
        nonEmpty.ifPresent(System.out::println);
        
        // 映射
        nonEmpty.map(String::toUpperCase)
            .ifPresent(System.out::println);
        
        // 或 else
        String value = nullable.orElse("Default");
        String value2 = nullable.orElseGet(() -> "Generated Default");
        String value3 = nullable.orElseThrow(() -> new RuntimeException("Value not present"));
    }
}

默认方法

接口默认方法

java
public interface MyInterface {
    // 抽象方法
    void abstractMethod();
    
    // 默认方法
    default void defaultMethod() {
        System.out.println("默认方法实现");
    }
    
    // 静态方法
    static void staticMethod() {
        System.out.println("静态方法");
    }
}

class MyClass implements MyInterface {
    @Override
    public void abstractMethod() {
        System.out.println("实现抽象方法");
    }
    
    // 可以重写默认方法
    @Override
    public void defaultMethod() {
        System.out.println("重写默认方法");
    }
}

多继承冲突解决

java
interface A {
    default void method() {
        System.out.println("A");
    }
}

interface B {
    default void method() {
        System.out.println("B");
    }
}

class C implements A, B {
    @Override
    public void method() {
        // 必须重写解决冲突
        A.super.method();  // 调用A的默认方法
        // 或者 B.super.method();
    }
}

新日期时间API

日期时间API 简介

Java 8 引入了新的日期时间API,位于 java.time 包中,解决了旧API的线程安全问题。

基本使用

java
import java.time.*;
import java.time.format.*;

public class DateTimeDemo {
    public static void main(String[] args) {
        // 本地日期
        LocalDate date = LocalDate.now();
        System.out.println(date);  // 2023-12-25
        
        // 本地时间
        LocalTime time = LocalTime.now();
        System.out.println(time);  // 14:30:45
        
        // 本地日期时间
        LocalDateTime dateTime = LocalDateTime.now();
        System.out.println(dateTime);  // 2023-12-25T14:30:45
        
        // 格式化
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String formatted = dateTime.format(formatter);
        System.out.println(formatted);  // 2023-12-25 14:30:45
        
        // 解析
        LocalDateTime parsed = LocalDateTime.parse("2023-12-25 14:30:45", formatter);
        
        // 时区
        ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
        
        // 期间
        Period period = Period.between(LocalDate.of(2023, 1, 1), LocalDate.of(2023, 12, 31));
        System.out.println(period.getMonths());  // 11
        
        // 持续时间
        Duration duration = Duration.between(LocalTime.of(10, 0), LocalTime.of(12, 0));
        System.out.println(duration.toHours());  // 2
    }
}

CompletableFuture

基本使用

java
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class CompletableFutureDemo {
    public static void main(String[] args) throws Exception {
        // 异步执行
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            return "Hello";
        });
        
        // 获取结果
        String result = future.get();
        System.out.println(result);
        
        // 链式调用
        CompletableFuture<String> chain = CompletableFuture
            .supplyAsync(() -> "Hello")
            .thenApply(s -> s + " World")
            .thenApply(String::toUpperCase);
        
        System.out.println(chain.get());  // HELLO WORLD
    }
}

组合多个Future

java
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "World");

// 组合
CompletableFuture<String> combined = future1
    .thenCombine(future2, (s1, s2) -> s1 + " " + s2);

System.out.println(combined.get());  // Hello World

// 任一完成
CompletableFuture<Object> anyOf = CompletableFuture.anyOf(future1, future2);

// 全部完成
CompletableFuture<Void> allOf = CompletableFuture.allOf(future1, future2);

异常处理

java
CompletableFuture<String> future = CompletableFuture
    .supplyAsync(() -> {
        if (true) throw new RuntimeException("Error");
        return "Success";
    })
    .exceptionally(ex -> "Default Value")
    .handle((result, ex) -> {
        if (ex != null) return "Error: " + ex.getMessage();
        return result;
    });

类型注解

Java 8扩展了注解的使用范围:

java
import java.lang.annotation.*;

// 类型注解
@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
public @interface NonNull {}

public class TypeAnnotationDemo {
    // 字段类型注解
    private @NonNull String name;
    
    // 参数类型注解
    public void method(@NonNull String param) {}
    
    // 泛型类型注解
    List<@NonNull String> list;
    
    // 类型转换注解
    String s = (@NonNull String) obj;
    
    // 继承类型注解
    class MyList implements List<@NonNull String> {}
}

重复注解

java
import java.lang.annotation.*;

@Repeatable(Authors.class)
@Retention(RetentionPolicy.RUNTIME)
public @interface Author {
    String name();
}

@Retention(RetentionPolicy.RUNTIME)
public @interface Authors {
    Author[] value();
}

// 使用
@Author(name = "张三")
@Author(name = "李四")
public class Book {}

Java 8特性总结

特性说明
Lambda表达式简洁的函数式编程语法
函数式接口单一抽象方法的接口
方法引用更简洁的Lambda写法
Stream API函数式数据处理
Optional空值处理
默认方法接口可以有默认实现
新日期时间API线程安全的日期时间处理
CompletableFuture异步编程
类型注解注解可用于任何类型
重复注解同一位置可使用多个相同注解