小白请教一下 JDK8 Lambda 表达式问题

2019-02-11 15:11:31 +08:00
 SuperHzw

现在项目升级用 jdk8,使用的时候遇到了一个问题,请教一下大家

实体类:
Family{
	private List<Person> person;
    ...
}
Person{
    private String age;
    ...
}

现在我要输出每个家庭中的每个人的年龄 jdk8 之前的写法:

if(!familyList.isEmpty()){
	for(Family f : familyList){
    	    if(!f.getPerson.isEmpty()){
        	for(Person p : f.getPerson){
            	    system.out.println(p.getAge());
            }
        }
    }
}

感觉很繁琐,可以用 Lambda 表达式来简化代码吗?

3936 次点击
所在节点    Java
28 条回复
lqw3030
2019-02-11 15:41:31 +08:00
.forEach(()->{})套两层
arrow8899
2019-02-11 15:44:55 +08:00
familyList.forEach(fml -> fml.getPerson().forEach(person -> System.out.println(person.getAge())));
no1xsyzy
2019-02-11 15:50:44 +08:00
flatMap
reeco
2019-02-11 16:01:54 +08:00
familyList.stream().map(Family::getPerson).flatMap(List::stream).map(Person::getAge).forEach(System.out::println);
thetydead
2019-02-11 16:02:19 +08:00
familyList.forEach(f -> f.getPerson().forEach(System.out::println));
xhinliang
2019-02-11 16:02:26 +08:00
flatMap 正解
zts1993
2019-02-11 16:15:35 +08:00
我觉得用 forEach 都不好意思说自己用的是 Lambda,这和 forr 有啥区别嘛 : )
LastingTime
2019-02-11 16:49:18 +08:00
过分追求 Lambda 去简化本不需要简化的代码, 不见得有什么好处.
另外你这几层都得判空, 更没必要了..
DsuineGP
2019-02-11 17:25:57 +08:00
flightInfos.stream().map(Family::getPerson).flatMap(Collection::stream).map(Person::getAge).forEach(System.out::println);
qiyuey
2019-02-11 19:00:19 +08:00
楼上很多使用了 stream,但是 stream 比较消耗性能,单纯的 forEach 没必要使用 stream。
SuperHzw
2019-02-12 00:14:49 +08:00
@DsuineGP 之前研究了一下就是用你这样子的形式,但是这样子判断为空就没了,想加入 optional,但是这样就不知道要怎么写了😂
SuperHzw
2019-02-12 00:15:56 +08:00
@qiyuey 看书上的介绍 好像用 stream 是比较节省成本的?
SuperHzw
2019-02-12 00:19:08 +08:00
@xhinliang @reeco @no1xsyzy @arrow8899
有使用 flatMap,但是还有两个非空判断,想加入 optionnal 解决,就不知道怎么写了,网上找了一下也没有结论
wxkvEX
2019-02-12 00:56:07 +08:00
@SuperHzw 为啥要 optional,非空判断可以加 family 的流里,用 filter 就可以
nl101531
2019-02-12 08:07:56 +08:00
@SuperHzw 你这里只是 isEmpty 判断,实际上集合中没有元素 Stream 这个链路只会构造起来,但是不会执行的,不用考虑。如果是 NPE 判断可以按照下面方式。

Optional.ofNullable(familyList)
.orElse(Collections.emptyList())
.stream()
.filter(x -> !CollectionUtils.isEmpty(x.person))
.flatMap(x -> x.person.stream())
.forEach(x -> System.out.println(x.age));
SuperHzw
2019-02-12 10:17:30 +08:00
@wxkvEX 是的,用 filter 也可以,只是自己好奇在此背景下如何用 stream 和 optional 结合的方式写
daemonk
2019-02-12 10:20:11 +08:00
isEmpty() 还是有可能 NPE 啊
SuperHzw
2019-02-12 10:24:11 +08:00
@nl101531 感谢您的解答,厉害!
jorneyr
2019-02-12 10:34:21 +08:00
2 个 for 循环比啥都简洁的代码,强用其他写法后代码的可读性降低了很多。
qiyuey
2019-02-12 10:54:33 +08:00
@SuperHzw 那是指 stream 长链操作的 lazy 特性,对于单纯的 forEach 只会增加开销。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/533940

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX