java打卡学习2:Stream高级与Optional

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或Set

    java 复制代码
    List<String> list = stream.collect(Collectors.toList());
  • toMap():转换为Map,需指定键和值的提取函数

    java 复制代码
    Map<Integer, String> map = stream.collect(Collectors.toMap(Person::getId, Person::getName));
  • groupingBy():按条件分组

    java 复制代码
    Map<String, List<Person>> group = stream.collect(Collectors.groupingBy(Person::getDepartment));
  • joining():拼接字符串

    java 复制代码
    String joined = stream.collect(Collectors.joining(", "));

方法引用

方法引用是Lambda表达式的简写形式,通过::符号引用已有方法。分为四种类型:

  1. 静态方法引用

    java 复制代码
    Function<String, Integer> parser = Integer::parseInt;
  2. 实例方法引用

    java 复制代码
    List<String> list = Arrays.asList("A", "B");
    list.forEach(System.out::println);
  3. 对象方法引用

    java 复制代码
    String str = "test";
    Supplier<Integer> lengthSupplier = str::length;
  4. 构造方法引用

    java 复制代码
    Supplier<List<String>> listSupplier = ArrayList::new;

Optional空值处理

Optional用于避免NullPointerException,提供链式空值检查。核心方法:

  • ofNullable():包装可能为null的值

    java 复制代码
    Optional<String> opt = Optional.ofNullable(getNullableString());
  • orElse():提供默认值

    java 复制代码
    String value = opt.orElse("default");
  • orElseGet():延迟计算默认值

    java 复制代码
    String value = opt.orElseGet(() -> computeFallback());
  • map()flatMap():链式转换

    java 复制代码
    Optional<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");
相关推荐
AI进化营-智能译站11 小时前
ROS2 C++开发系列17-多线程驱动多传感器|chrono高精度计时实现机器人同步控制
java·c++·ai·机器人
天若有情67314 小时前
程序员原创|借鉴JS事件冒泡,根治电脑文件混乱的“冒泡整理法”
开发语言·javascript·windows·ecmascript·电脑·办公·日常
qq_5895681015 小时前
springbootweb案例,出现访问 http://localhost:8080/list 一直处于浏览器运转阶段
java·网络协议·http·list·springboot
小e说说15 小时前
拯救孩子学习兴趣大作战!这些软件超神了
学习
九成宫15 小时前
Outlook使用
windows·笔记·outlook·办公
JAVA面经实录91715 小时前
计算机基础(完整版·超详细可背诵)
java·linux·数据结构·算法
AC赳赳老秦15 小时前
知识产权辅助:用 OpenClaw 批量生成专利交底书 / 软著申请材料,自动校验格式与内容合规性
java·人工智能·python·算法·elasticsearch·deepseek·openclaw
盘古工具16 小时前
【分享】打开PDF文件的几种方式
windows·pdf
FYKJ_201016 小时前
springboot校园兼职平台--附源码02041
java·javascript·spring boot·python·eclipse·django·php