Stream 高级操作
Stream API 提供了丰富的中间操作和终端操作,用于处理集合数据。以下是一些高级用法:
过滤与映射
java
list.stream()
.filter(e -> e.getAge() > 18) // 过滤年龄大于18的元素
.map(Person::getName) // 转换为姓名列表
.collect(Collectors.toList());
扁平化处理
java
List<List<String>> nestedList = ...;
nestedList.stream()
.flatMap(Collection::stream) // 扁平化为单一流
.distinct() // 去重
.forEach(System.out::println);
分组与分区
java
Map<String, List<Person>> byCity =
people.stream()
.collect(Collectors.groupingBy(Person::getCity));
Map<Boolean, List<Person>> partitioned =
people.stream()
.collect(Collectors.partitioningBy(p -> p.getAge() > 30));
Optional 深度用法
Optional 用于避免空指针异常,提供更优雅的null处理方式。
创建Optional
java
Optional<String> emptyOpt = Optional.empty();
Optional<String> ofOpt = Optional.of("value"); // 值不能为null
Optional<String> nullableOpt = Optional.ofNullable(nullableValue);
链式操作
java
String result = Optional.ofNullable(user)
.map(User::getAddress)
.map(Address::getStreet)
.orElse("default street");
条件处理
java
optionalValue.ifPresent(v -> System.out.println("Found: " + v));
optionalValue.orElseThrow(() -> new RuntimeException("Value not present"));
结合Stream使用
java
List<String> names = users.stream()
.map(User::getName)
.flatMap(Optional::stream) // Java9+ 自动解包
.collect(Collectors.toList());
性能注意事项
- 避免在循环中创建Stream
- 优先使用基本类型特化流(IntStream等)
- 并行流仅在数据量大且无状态操作时使用
collect收集器
Collectors是Java 8中StreamAPI的核心工具类,用于将流中的元素聚合为集合或其他形式的结果。常用方法包括:
-
toList()/toSet():转换为List或SetjavaList<String> list = stream.collect(Collectors.toList()); -
toMap():转换为Map,需指定键和值的提取函数javaMap<Integer, String> map = stream.collect(Collectors.toMap(Person::getId, Person::getName)); -
groupingBy():按条件分组javaMap<String, List<Person>> group = stream.collect(Collectors.groupingBy(Person::getDepartment)); -
joining():拼接字符串javaString joined = stream.collect(Collectors.joining(", "));
方法引用
方法引用是Lambda表达式的简写形式,通过::符号引用已有方法。分为四种类型:
-
静态方法引用
javaFunction<String, Integer> parser = Integer::parseInt; -
实例方法引用
javaList<String> list = Arrays.asList("A", "B"); list.forEach(System.out::println); -
对象方法引用
javaString str = "test"; Supplier<Integer> lengthSupplier = str::length; -
构造方法引用
javaSupplier<List<String>> listSupplier = ArrayList::new;
Optional空值处理
Optional用于避免NullPointerException,提供链式空值检查。核心方法:
-
ofNullable():包装可能为null的值javaOptional<String> opt = Optional.ofNullable(getNullableString()); -
orElse():提供默认值javaString value = opt.orElse("default"); -
orElseGet():延迟计算默认值javaString value = opt.orElseGet(() -> computeFallback()); -
map()与flatMap():链式转换javaOptional<Integer> length = opt.map(String::length);
今日练习
分组统计的实现方法
使用SQL进行分组统计时,GROUP BY子句是关键。例如统计每个部门的员工数量:
sql
SELECT department, COUNT(*) as employee_count
FROM employees
GROUP BY department;
在Java中利用Stream API进行分组统计:
java
Map<String, Long> countByDepartment = employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment, Collectors.counting()));
空指针优化的处理策略
Java中Optional类可以优雅处理空指针:
java
Optional.ofNullable(obj)
.map(Object::toString)
.orElse("default");
使用Objects工具类进行空校验:
java
String value = Objects.requireNonNullElse(input, "default");
数据库查询的空值处理
SQL中使用COALESCE函数处理空值:
sql
SELECT COALESCE(column_name, 'N/A') FROM table;
MySQL的IFNULL函数:
sql
SELECT IFNULL(column_name, 0) FROM table;
前端空值展示优化
JavaScript可选链操作符:
javascript
const name = user?.profile?.name ?? 'Anonymous';
Vue/React中使用条件渲染:
jsx
{user && <Profile data={user.profile} />}
日志记录中的空指针防护
日志输出前进行空校验:
java
log.debug("User info: {}", Optional.ofNullable(user).map(User::toString).orElse("[null]"));
使用String.format时添加防护:
java
String.format("Value: %s", obj != null ? obj : "null");
