ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

lambda,Optional,Stream最重要也是最常用

lambda,Optional,Stream最重要也是最常用

这三个是 Java 8 面试里最常被放在一起问的,可以按“Lambda 写行为、Stream 处理集合、Optional 处理空值”来记。

1. Lambda 表达式

作用:简化匿名内部类,让“一段行为”可以像参数一样传进去。

// 传统写法newThread(newRunnable(){@Overridepublicvoidrun(){System.out.println("hello");}}).start();// Lambda 写法newThread(()->System.out.println("hello")).start();

关键点:

  • 只能用于函数式接口,也就是只有一个抽象方法的接口。
  • 常用内置接口:
    • Predicate<T>:接收参数,返回boolean,比如x -> x > 10
    • Function<T,R>:接收 T,返回 R,比如s -> s.length()
    • Consumer<T>:接收参数,无返回值,比如s -> System.out.println(s)
    • Supplier<T>:无参数,返回 T,比如() -> new User()
  • Lambda 捕获的外部局部变量必须是final或“事实上不可变”。

面试可以答:Lambda 本质是函数式接口的实例,用来简化匿名内部类。


2. Stream 流

作用:对集合做过滤、转换、排序、统计、分组,替代繁琐的for循环。

List<String>names=users.stream().filter(u->u.getAge()>18).map(User::getName).sorted().collect(Collectors.toList());

三个阶段:

  1. 创建流:list.stream()、Stream.of()
  2. 中间操作:filter、map、flatMap、sorted、distinct、limit、skip
  3. 终止操作:forEach、collect、count、reduce、max、min、anyMatch

中间操作是“加工”,终端操作是“出锅”。
filter、map、flatMap、sorted 都在加工;collect、count、forEach、findFirst 就是出锅拿结果

特点:

  • Stream不存储数据,只是对数据源做计算。
  • 中间操作是惰性求值,只有遇到终止操作才会真正执行。
  • Stream不会修改原集合。
  • Stream只能消费一次,用完不能再次使用。

面试常问:map和flatMap区别?
map是一对一转换;flatMap是一对多再扁平化,比如List<List<String>>转成List<String>。


3. Optional

作用:优雅处理可能为null的值,减少if (obj != null)。

Optional<User>userOpt=Optional.ofNullable(user);Stringname=userOpt.map(User::getName).orElse("未知");// 通常写法如下,少一个变量命名Stringname=Optional.ofNullable(user).map(User::getName).orElse("未知名字");

常用方法:

  • Optional.of(value):值不能为null,否则抛异常
  • Optional.ofNullable(value):允许null
  • isPresent():判断是否有值
  • ifPresent():有值才执行
  • orElse():为空给默认值
  • orElseGet():为空时执行逻辑生成默认值
  • orElseThrow():为空抛异常

面试坑点:orElse()和orElseGet()区别?
orElse()无论是否为空都会执行;orElseGet()只有为空时才执行。所以orElseGet()更适合生成默认值。


面试一句话总结

Lambda 简化匿名内部类,Stream 做集合流式处理,Optional 用来避免空指针。这三个经常一起出现,最好各准备一个代码示例。


需要我详细讲讲Stream中map和flatMap的区别,并写个代码示例帮你理解吗?

你前面已经基本掌握了这三个东西,现在可以按“Lambda 写行为,Stream 处理集合,Optional 处理空值”来记。

速记版

概念作用常见写法
Lambda简化函数式接口实现(x) -> x > 10
Stream链式处理集合filter / map / collect
Optional避免空指针map / orElse / orElseThrow

组合示例

Optional<String>name=users.stream().filter(u->u.getAge()>18).map(User::getName).findFirst();Stringresult=name.orElse("未知用户");

这里三个都用上了:

  • u -> u.getAge() > 18是Lambda;
  • stream / filter / map / findFirst是Stream;
  • findFirst返回Optional,用orElse兜底是Optional。

面试高频坑点

  • filter是中间操作,不会立即执行;collect / count / forEach是终止操作,才会真正触发计算。
  • Stream 只能消费一次,不能重复使用。
  • map是一对一转换;flatMap是一对多再扁平化。
  • Optional.of()传 null 会抛异常;Optional.ofNullable()才允许 null。
  • orElse()不管有没有值都会执行;orElseGet()只有为空时才执行。
  • Lambda 只能用于函数式接口,也就是只有一个抽象方法的接口。

如果你是想练代码题,可以重点练这几类:集合过滤排序、去重统计、分组、转 Map、Optional 链式判空。需要的话我可以直接出几道带答案的练习题。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进