首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  Java

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

  •  1
     
  •   SuperHzw · 7 天前 · 1939 次点击

    现在项目升级用 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 表达式来简化代码吗?

    28 回复  |  直到 2019-02-13 09:10:25 +08:00
        1
    lqw3030   7 天前 via iPhone
    .forEach(()->{})套两层
        2
    arrow8899   7 天前
    familyList.forEach(fml -> fml.getPerson().forEach(person -> System.out.println(person.getAge())));
        3
    no1xsyzy   7 天前
    flatMap
        4
    reeco   7 天前   ♥ 4
    familyList.stream().map(Family::getPerson).flatMap(List::stream).map(Person::getAge).forEach(System.out::println);
        5
    thetydead   7 天前
    familyList.forEach(f -> f.getPerson().forEach(System.out::println));
        6
    xhinliang   7 天前
    flatMap 正解
        7
    zts1993   7 天前
    我觉得用 forEach 都不好意思说自己用的是 Lambda,这和 forr 有啥区别嘛 : )
        8
    LastingTime   7 天前
    过分追求 Lambda 去简化本不需要简化的代码, 不见得有什么好处.
    另外你这几层都得判空, 更没必要了..
        9
    DsuineGP   7 天前
    flightInfos.stream().map(Family::getPerson).flatMap(Collection::stream).map(Person::getAge).forEach(System.out::println);
        10
    qiyuey   7 天前
    楼上很多使用了 stream,但是 stream 比较消耗性能,单纯的 forEach 没必要使用 stream。
        11
    SuperHzw   7 天前 via iPhone
    @DsuineGP 之前研究了一下就是用你这样子的形式,但是这样子判断为空就没了,想加入 optional,但是这样就不知道要怎么写了😂
        12
    SuperHzw   7 天前 via iPhone
    @qiyuey 看书上的介绍 好像用 stream 是比较节省成本的?
        13
    SuperHzw   7 天前 via iPhone
    @xhinliang @reeco @no1xsyzy @arrow8899
    有使用 flatMap,但是还有两个非空判断,想加入 optionnal 解决,就不知道怎么写了,网上找了一下也没有结论
        14
    wxkvEX   7 天前 via iPhone
    @SuperHzw 为啥要 optional,非空判断可以加 family 的流里,用 filter 就可以
        15
    nl101531   7 天前
    @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));
        16
    SuperHzw   7 天前
    @wxkvEX 是的,用 filter 也可以,只是自己好奇在此背景下如何用 stream 和 optional 结合的方式写
        17
    daemonk   7 天前
    isEmpty() 还是有可能 NPE 啊
        18
    SuperHzw   7 天前
    @nl101531 感谢您的解答,厉害!
        19
    jorneyr   7 天前
    2 个 for 循环比啥都简洁的代码,强用其他写法后代码的可读性降低了很多。
        20
    qiyuey   7 天前
    @SuperHzw 那是指 stream 长链操作的 lazy 特性,对于单纯的 forEach 只会增加开销。
        21
    no1xsyzy   7 天前
    @qiyuey 真 · 只是为了好看
    流处理理解起来大多数更方便一点所以会觉得好看
        22
    SuperHzw   7 天前 via iPhone
    @qiyuey @no1xsyzy 不只是好看 刚刚写了个测试类试一下 单单两个循环 用 flatmap 速度是比较快的
        23
    qiyuey   6 天前
    @SuperHzw 你可以多测试几次,另外建议将 print 操作替换为空的方法调用,因为 print 带来的误差还是比较大的。其实这个问题很简单,你可以看一下 stream 的源码,就会发现,无论如何 stream 的性能不可能超过单纯的循环。
        24
    dengtongcai   6 天前
    写嵌套,然后 alt+enter 让 idea 帮你改成 lambda
        25
    cyspy   6 天前
    这两次判空完全是不需要的
        26
    SuperHzw   6 天前 via iPhone
    @cyspy 那应该如何处理呢?
        27
    SuperHzw   6 天前 via iPhone
    @qiyuey 好的 明天我会尝试一下
        28
    cyspy   6 天前
    @SuperHzw 无论是 for (:)还是 flatmap 都会自动忽略掉空集合
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3216 人在线   最高记录 4346   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 18ms · UTC 04:29 · PVG 12:29 · LAX 20:29 · JFK 23:29
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1