java8中常用的工具函数
Java 8 引入了众多革命性特性(如 Lambda 表达式、Stream API、新日期时间 API 等),极大简化了代码编写。以下是基于 Java 8 的常用工具函数及特性,聚焦于新增或强化的功能:
一、Stream API(java.util.stream
)
Java 8 新增的 Stream API 是处理集合的强大工具,支持链式操作、惰性求值,可替代传统的 for 循环遍历,代码更简洁。
方法/操作 | 用途说明 | 示例 |
---|---|---|
stream() /parallelStream() | 从集合获取流(parallelStream() 为并行流,利用多线程) | List<Integer> list = List.of(1,2,3); Stream<Integer> stream = list.stream(); |
filter(Predicate<T> p) | 过滤元素(保留满足条件的元素) | list.stream().filter(n -> n > 1).collect(Collectors.toList()) → [2,3] |
map(Function<T,R> f) | 转换元素(将 T 类型转为 R 类型) | list.stream().map(n -> n * 2).collect(Collectors.toList()) → [2,4,6] |
flatMap(Function<T,Stream<R>> f) | 扁平化流(将嵌套集合转为单层流) | List<List<Integer>> nested = List.of(List.of(1,2), List.of(3)); nested.stream().flatMap(Collection::stream).collect(Collectors.toList()) → [1,2,3] |
sorted() /sorted(Comparator<T> c) | 排序(自然排序或自定义比较器) | list.stream().sorted((a,b) -> b - a).collect(Collectors.toList()) → [3,2,1] |
distinct() | 去重(基于 equals() ) | Stream.of(1,2,2,3).distinct().collect(Collectors.toList()) → [1,2,3] |
collect(Collector c) | 收集流结果(转集合、分组等,依赖 Collectors 工具类) | // 转Set:stream.collect(Collectors.toSet())<br>// 分组:List<String> strs = List.of("a","ab","b"); strs.stream().collect(Collectors.groupingBy(String::length)) → {1: ["a","b"], 2: ["ab"]} |
forEach(Consumer<T> c) | 遍历元素(终端操作,无返回值) | list.stream().forEach(System.out::println); // 打印1、2、3 |
reduce(BinaryOperator<T> op) | 归约(将元素合并为单个结果) | list.stream().reduce((a,b) -> a + b).orElse(0) → 6 (求和) |
anyMatch(Predicate<T> p) | 判断是否有元素满足条件(短路操作) | list.stream().anyMatch(n -> n > 2) → true (存在大于2的元素) |
二、Optional 类(java.util.Optional
)
Java 8 引入 Optional
解决 null
问题,避免空指针异常(NPE),强制显式处理“值可能不存在”的场景。
方法 | 用途说明 | 示例 |
---|---|---|
Optional.of(T t) | 创建非空 Optional(t 为 null 则抛 NPE,用于确定非空的值) | Optional<String> opt = Optional.of("hello"); |
Optional.ofNullable(T t) | 创建可空 Optional(t 为 null 则返回空 Optional) | Optional<String> opt = Optional.ofNullable(getNullableValue()); |
isPresent() | 判断是否有值(存在则返回 true) | opt.isPresent() → true (若 opt 包含"hello") |
ifPresent(Consumer<T> c) | 若有值则执行消费操作(替代 if (obj != null) { ... } ) | opt.ifPresent(s -> System.out.println(s.length())); // 打印5 |
orElse(T other) | 若为空则返回默认值(无论是否为空,other 都会被计算) | opt.orElse("default") → "hello" (若 opt 为空则返回"default") |
orElseGet(Supplier<T> s) | 若为空则通过 Supplier 获取默认值(惰性计算,仅为空时执行) | opt.orElseGet(() -> fetchDefault()) → "hello" (fetchDefault() 仅为空时调用) |
orElseThrow(Supplier<X> e) | 若为空则抛指定异常(常用于参数校验) | opt.orElseThrow(() -> new IllegalArgumentException("值不存在")) |
map(Function<T,R> f) | 转换 Optional 中的值(若为空则返回空 Optional) | opt.map(String::toUpperCase).orElse("") → "HELLO" |
三、新日期时间 API(java.time
包)
Java 8 彻底重构了日期时间 API,替代了旧的 Date
/Calendar
(线程不安全、设计混乱),新 API 线程安全且易用。
核心类及常用方法:
类 | 用途 | 常用方法示例 |
---|---|---|
LocalDate | 仅包含日期(年/月/日) | // 获取当前日期:LocalDate.now() → 2025-10-17<br>// 解析日期:LocalDate.parse("2025-10-17")<br>// 加减天数:localDate.plusDays(1) → 2025-10-18<br>// 比较:localDate.isAfter(LocalDate.of(2025,10,16)) → true |
LocalTime | 仅包含时间(时/分/秒/纳秒) | // 当前时间:LocalTime.now() → 16:30:45.123<br>// 解析时间:LocalTime.parse("10:15")<br>// 加减小时:localTime.minusHours(2) → 08:15 |
LocalDateTime | 包含日期+时间 | // 当前日期时间:LocalDateTime.now() → 2025-10-17T16:30:45<br>// 拼接:LocalDate.now().atTime(12,0) → 2025-10-17T12:00 |
ZonedDateTime | 带时区的日期时间(如 UTC+8) | // 时区转换:ZonedDateTime.now(ZoneId.of("America/New_York")) |
Duration | 表示时间间隔(时分秒) | Duration.between(LocalTime.of(10,0), LocalTime.of(12,30)).toMinutes() → 150 (间隔150分钟) |
Period | 表示日期间隔(年月日) | Period.between(LocalDate.of(2023,1,1), LocalDate.of(2025,1,1)).getYears() → 2 (间隔2年) |
DateTimeFormatter | 格式化/解析日期时间(线程安全) | // 格式化:LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) → "2025-10-17 16:30:45"<br>// 解析:LocalDateTime.parse("2025-10-17 16:30:45", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) |
四、集合框架增强(默认方法)
Java 8 为 List
、Map
等集合接口新增了默认方法(基于 Lambda),简化操作。
集合类型 | 方法 | 用途说明 | 示例 |
---|---|---|---|
List | forEach(Consumer<T> c) | 遍历元素(替代 for 循环) | List<String> list = List.of("a","b"); list.forEach(System.out::println); |
List | removeIf(Predicate<T> p) | 移除满足条件的元素 | List<Integer> list = new ArrayList<>(List.of(1,2,3)); list.removeIf(n -> n < 2); → [2,3] |
List | replaceAll(UnaryOperator<T> o) | 替换所有元素 | list.replaceAll(n -> n * 2); → [4,6] (基于上例结果) |
Map | forEach(BiConsumer<K,V> c) | 遍历键值对 | Map<String, Integer> map = Map.of("a",1,"b",2); map.forEach((k,v) -> System.out.println(k+":"+v)); |
Map | computeIfAbsent(K key, Function<K,V> f) | 若键不存在则计算并添加值(避免重复判断 null) | map.computeIfAbsent("c", k -> k.length()) → map 新增 "c":1 |
Map | computeIfPresent(K key, BiFunction<K,V,V> f) | 若键存在则更新值 | map.computeIfPresent("a", (k,v) -> v + 1) → "a"的值变为2 |
Map | merge(K key, V value, BiFunction<V,V,V> f) | 合并值(若键存在则用函数处理旧值和新值,否则直接添加) | map.merge("a", 3, (old, val) -> old + val) → "a"的值变为2+3=5 |
五、函数式接口(java.util.function
)
Java 8 定义了一系列函数式接口,作为 Lambda 表达式的类型,支撑 Stream、Optional 等特性的使用。
接口 | 抽象方法 | 用途说明 | 示例 |
---|---|---|---|
Predicate<T> | test(T t) | 断言(返回 boolean,用于过滤) | Predicate<Integer> isEven = n -> n % 2 == 0; isEven.test(4) → true |
Function<T,R> | apply(T t) | 函数(输入 T 输出 R,用于转换) | Function<String, Integer> strLen = s -> s.length(); strLen.apply("abc") → 3 |
Consumer<T> | accept(T t) | 消费者(输入 T 无返回,用于遍历) | Consumer<String> print = s -> System.out.println(s); print.accept("hello"); |
Supplier<T> | get() | 生产者(无输入返回 T,用于提供默认值) | Supplier<LocalDate> today = LocalDate::now; today.get() → 2025-10-17 |
UnaryOperator<T> | apply(T t) | 一元操作(输入输出同类型,继承 Function) | UnaryOperator<Integer> square = n -> n * n; square.apply(3) → 9 |
BiFunction<T,U,R> | apply(T t, U u) | 二元函数(输入 T 和 U,输出 R) | BiFunction<Integer, Integer, Integer> add = (a,b) -> a + b; add.apply(2,3) → 5 |
六、CompletableFuture(异步编程)
Java 8 引入 CompletableFuture
替代传统 Future
,支持链式异步操作、异常处理,更灵活地处理多线程任务。
方法 | 用途说明 | 示例 |
---|---|---|
supplyAsync(Supplier<T> s) | 异步执行有返回值的任务(默认用 ForkJoinPool) | CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> fetchData()); // fetchData() 异步执行 |
thenApply(Function<T,R> f) | 异步任务完成后执行转换(链式操作) | future.thenApply(data -> process(data)) // 处理 fetchData() 的结果 |
thenAccept(Consumer<T> c) | 异步任务完成后消费结果(无返回) | future.thenAccept(result -> saveToDB(result)); |
exceptionally(Function<Throwable,T> f) | 捕获异步任务中的异常并返回默认值 | future.exceptionally(e -> { e.printStackTrace(); return "default"; }); |
allOf(CompletableFuture<?>... cfs) | 等待所有异步任务完成(无返回,需配合 join() ) | CompletableFuture.allOf(future1, future2).join(); // 等待 future1 和 future2 完成 |
总结
Java 8 的工具函数核心围绕“简化代码、提升效率”,尤其是 Stream API 简化集合处理、Optional 消除 NPE、新日期时间 API 解决线程安全问题,以及 CompletableFuture 优化异步编程。这些特性已成为现代 Java 开发的基础,建议优先使用以替代旧有实现。