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 | 异步编程 |
| 类型注解 | 注解可用于任何类型 |
| 重复注解 | 同一位置可使用多个相同注解 |