Java8核心能力篇-Lambda-Stream-Optional与日期时间

张开发
2026/4/9 17:12:09 15 分钟阅读

分享文章

Java8核心能力篇-Lambda-Stream-Optional与日期时间
前言很多人说自己会 Java 8其实只是会写几个stream()。Java 8 真正带来的变化不只是多了几个 API而是把整个编码风格往函数式、声明式和不可变方向推了一大步。这一篇不追求大而全只讲最该掌握的 5 个核心能力Lambda、Stream、方法引用、Optional 和 DateTime API。把这几个点吃透你的 Java 代码风格会明显上一个台阶。一、Lambda 表达式函数式编程的起点Lambda 是 Java 8 最关键的起点也是后面 Stream、Optional 等特性的基础。Runnable r1 new Runnable() { Override public void run() { System.out.println(Hello); } }; Runnable r2 () - System.out.println(Hello);实战里最常见的价值不是“少写几行”而是把行为当参数传进去。new LambdaQueryWrapperSysUserEntity() .eq(StringUtils.hasText(status), SysUserEntity::getStatus, status) .eq(SysUserEntity::getDeleted, Boolean.FALSE) .and(StringUtils.hasText(keyword), wrapper - wrapper .like(SysUserEntity::getUsername, keyword) .or() .like(SysUserEntity::getDisplayName, keyword) .or() .like(SysUserEntity::getMobile, keyword)) .orderByDesc(SysUserEntity::getId); 注意点Lambda 捕获的局部变量必须是 effectively final参数类型通常可以省略由编译器推断单表达式 Lambda 可以省略大括号和return二、Stream API让集合操作更像“描述意图”Stream 最重要的价值不是炫技而是把“做什么”从“怎么做”里拆出来。常见操作操作类型方法说明中间操作filter()过滤元素中间操作map()元素转换中间操作flatMap()展平嵌套集合中间操作distinct()去重中间操作sorted()排序终止操作collect()收集结果终止操作findFirst()取第一个元素终止操作toList()收集为列表Java 161. 对象转换ListChatSessionResponse responses page.getRecords().stream() .map(this::toSessionResponse) .toList();如果还在 Java 8 环境可以写成ListChatSessionResponse responses page.getRecords().stream() .map(this::toSessionResponse) .collect(Collectors.toList());2. 转成 MapMapLong, ChunkEntity chunkMap chunkMapper.selectBatchIds(chunkIds) .stream() .collect(Collectors.toMap( ChunkEntity::getId, Function.identity() ));如果 key 可能重复要显式写合并逻辑.collect(Collectors.toMap( Entity::getId, Function.identity(), (existing, replacement) - existing ));3. 分组聚合MapLong, ListString capabilitiesByModel capabilities.stream() .collect(Collectors.groupingBy( AiModelCapabilityEntity::getModelId, Collectors.mapping( AiModelCapabilityEntity::getCapabilityType, Collectors.toList() ) ));4. flatMap 展平ListLong chunkIds refsByMessageId.values().stream() .flatMap(List::stream) .map(ChatAnswerReferenceEntity::getChunkId) .toList();5. 统计计算long totalPromptTokens messages.stream() .map(ChatMessageEntity::getPromptTokens) .filter(Objects::nonNull) .mapToLong(Integer::longValue) .sum(); Stream 使用建议不要把 Stream 当成“链式炫技工具”避免在 Lambda 中修改外部状态parallelStream()不是禁用项但不要默认觉得它更快必须按场景评估一个 Stream 只能消费一次三、方法引用能省则省但别写错方法引用是 Lambda 的语法糖本质没变只是更简洁。类型语法示例静态方法引用ClassName::staticMethodObjects::nonNull特定对象实例方法引用instance::methodthis::toSessionResponse任意对象实例方法引用ClassName::methodString::toUpperCase构造方法引用ClassName::newArrayList::new.filter(Objects::nonNull) .map(this::toSessionResponse) .map(ChatMessageEntity::getId)真正的构造方法引用应该长这样SupplierListString supplier ArrayList::new;Function.identity()不是构造方法引用它只是“返回参数本身”的函数。四、Optional少写空指针判断但别滥用Optional 是 Java 8 引入的容器类用于表达“这个值可能不存在”。OptionalString opt1 Optional.of(hello); OptionalString opt2 Optional.ofNullable(maybeNull); OptionalString opt3 Optional.empty();常见写法String value opt.orElse(默认值); String value2 opt.orElseGet(this::computeDefaultValue); String value3 opt.orElseThrow(() - new BusinessException(值不存在));ifPresentOrElse()也很好用但这里要注意版本opt.ifPresentOrElse( value - System.out.println(值: value), () - System.out.println(无值) );这个方法是 Java 9 才加的不是 Java 8。Stream 配合 Optional 的典型用法public EmbeddingModelClient getClient(String providerCode) { return clients.stream() .filter(client - client.supports(providerCode)) .findFirst() .orElseThrow(() - new BusinessException(当前未实现该模型提供方的客户端)); } Optional 注意点适合做返回值不适合做字段或方法参数尽量不要直接调用get()不要为了“显得高级”到处包一层 Optional五、DateTime API真正该淘汰的是旧时间 APIjava.time是 Java 8 最应该全面拥抱的一套 API。类用途LocalDate日期LocalTime时间LocalDateTime日期时间InstantUTC 时间点Duration时间段ZonedDateTime带时区时间实战里最常见的写法LocalDateTime now LocalDateTime.now(); Instant start Instant.now(); int latencyMs (int) Duration.between(start, Instant.now()).toMillis(); LocalDateTime staleBefore LocalDateTime.now().minus(Duration.ofMinutes(5)); String datePath LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE);配合 Spring 或 Redis 也很自然Duration ttl Duration.ofSeconds(refreshTokenTtlSeconds); stringRedisTemplate.opsForValue().set(key, value, ttl); DateTime API 注意点新项目尽量不要继续扩散Date/Calendar涉及时区时优先明确使用Instant或ZonedDateTime数据库存储和序列化时要确认时区策略一致总结Java 8 最核心的升级不是某个单独 API而是编码思维的变化Lambda 让行为可传递Stream 让集合操作更声明式方法引用让样板代码更少Optional 让空值表达更明确DateTime API 让时间处理终于变得可靠如果你想真正跨过“会写 Java”和“会写现代 Java”的分界线这 5 个点必须熟。

更多文章