小白请教一下 JDK8 Lambda 表达式问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
SuperHzw
V2EX    Java

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

  •  1
     
  •   SuperHzw 2019-02-11 15:11:31 +08:00 4593 次点击
    这是一个创建于 2435 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

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

    28 条回复    2019-02-13 09:10:25 +08:00
    xyooyx
        1
    xyooyx  
       2019-02-11 15:41:31 +08:00 via iPhone
    .forEach(()->{})套两层
    arrow8899
        2
    arrow8899  
       2019-02-11 15:44:55 +08:00
    familyList.forEach(fml -> fml.getPerson().forEach(person -> System.out.println(person.getAge())));
    no1xsyzy
        3
    no1xsyzy  
       2019-02-11 15:50:44 +08:00
    flatMap
    reeco
        4
    reeco  
       2019-02-11 16:01:54 +08:00   4
    familyList.stream().map(Family::getPerson).flatMap(List::stream).map(Person::getAge).forEach(System.out::println);
    thetydead
        5
    thetydead  
       2019-02-11 16:02:19 +08:00
    familyList.forEach(f -> f.getPerson().forEach(System.out::println));
    xhinliang
        6
    xhinliang  
       2019-02-11 16:02:26 +08:00
    flatMap 正解
    zts1993
        7
    zts1993  
       2019-02-11 16:15:35 +08:00
    我觉得用 forEach 都不好意思说自己用的是 Lambda,这和 forr 有啥区别嘛 : )
    LastingTime
        8
    LastingTime  
       2019-02-11 16:49:18 +08:00
    过分追求 Lambda 去简化本不需要简化的代码, 不见得有什么好处.
    另外你这几层都得判空, 更没必要了..
    DsuineGP
        9
    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
        10
    qiyuey  
       2019-02-11 19:00:19 +08:00
    楼上很多使用了 stream,但是 stream 比较消耗性能,单纯的 forEach 没必要使用 stream。
    SuperHzw
        11
    SuperHzw  
    OP
       2019-02-12 00:14:49 +08:00 via iPhone
    @DsuineGP 之前研究了一下就是用你这样子的形式,但是这样子判断为空就没了,想加入 optional,但是这样就不知道要怎么写了
    SuperHzw
        12
    SuperHzw  
    OP
       2019-02-12 00:15:56 +08:00 via iPhone
    @qiyuey 看书上的介绍 好像用 stream 是比较节省成本的?
    SuperHzw
        13
    SuperHzw  
    OP
       2019-02-12 00:19:08 +08:00 via iPhone
    @xhinliang @reeco @no1xsyzy @arrow8899
    有使用 flatMap,但是还有两个非空判断,想加入 optionnal 解决,就不知道怎么写了,网上找了一下也没有结论
    wxkvEX
        14
    wxkvEX  
       2019-02-12 00:56:07 +08:00 via iPhone
    @SuperHzw 为啥要 optional,非空判断可以加 family 的流里,用 filter 就可以
    nl101531
        15
    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
        16
    SuperHzw  
    OP
       2019-02-12 10:17:30 +08:00
    @wxkvEX 是的,用 filter 也可以,只是自己好奇在此背景下如何用 stream 和 optional 结合的方式写
    daemonk
        17
    daemonk  
       2019-02-12 10:20:11 +08:00
    isEmpty() 还是有可能 NPE 啊
    SuperHzw
        18
    SuperHzw  
    OP
       2019-02-12 10:24:11 +08:00
    @nl101531 感谢您的解答,厉害!
    jorneyr
        19
    jorneyr  
       2019-02-12 10:34:21 +08:00
    2 个 for 循环比啥都简洁的代码,强用其他写法后代码的可读性降低了很多。
    qiyuey
        20
    qiyuey  
       2019-02-12 10:54:33 +08:00
    @SuperHzw 那是指 stream 长链操作的 lazy 特性,对于单纯的 forEach 只会增加开销。
    no1xsyzy
        21
    no1xsyzy  
       2019-02-12 11:49:35 +08:00
    @qiyuey 真 只是为了好看
    流处理理解起来大多数更方便一点所以会觉得好看
    SuperHzw
        22
    SuperHzw  
    OP
       2019-02-12 11:59:27 +08:00 via iPhone
    @qiyuey @no1xsyzy 不只是好看 刚刚写了个测试类试一下 单单两个循环 用 flatmap 速度是比较快的
    qiyuey
        23
    qiyuey  
       2019-02-12 13:26:09 +08:00
    @SuperHzw 你可以多测试几次,另外建议将 print 操作替换为空的方法调用,因为 print 带来的误差还是比较大的。其实这个问题很简单,你可以看一下 stream 的源码,就会发现,无论如何 stream 的性能不可能超过单纯的循环。
    dengtongcai
        24
    dengtongcai  
       2019-02-12 14:03:50 +08:00
    写嵌套,然后 alt+enter 让 idea 帮你改成 lambda
    cyspy
        25
    cyspy  
       2019-02-12 16:07:14 +08:00
    这两次判空完全是不需要的
    SuperHzw
        26
    SuperHzw  
    OP
       2019-02-12 23:46:10 +08:00 via iPhone
    @cyspy 那应该如何处理呢?
    SuperHzw
        27
    SuperHzw  
    OP
       2019-02-12 23:46:36 +08:00 via iPhone
    @qiyuey 好的 明天我会尝试一下
    cyspy
        28
    cyspy  
       2019-02-13 09:10:25 +08:00
    @SuperHzw 无论是 for (:)还是 flatmap 都会自动忽略掉空集合
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2340 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 15:52 PVG 23:52 LAX 08:52 JFK 11:52
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86