当前位置:首页 > 科技  > 软件

被人说 Lambda 代码像...,那是没用下面这三个方法

来源: 责编: 时间:2023-12-05 09:24:16 327观看
导读说 Lambda 写的代码像屎山,其实就是代码不够干净嘛。说到底并不是不会用 Lambda 本身的 API,而是用的方式不对。Java Lambda 本身提供了非常丰富的方法库,大多数时候我们常用的方法也就为数不多的那几个。Lambda 的使用

说 Lambda 写的代码像屎山,其实就是代码不够干净嘛。说到底并不是不会用 Lambda 本身的 API,而是用的方式不对。GpQ28资讯网——每日最新资讯28at.com

Java Lambda 本身提供了非常丰富的方法库,大多数时候我们常用的方法也就为数不多的那几个。Lambda 的使用方法之前专门写过文章,8000字,让你彻底了解 Java 8 的 Lambda、函数式接口、Stream 用法和原理。在掘金社区已经获得了将近600个赞,1200多个收藏。GpQ28资讯网——每日最新资讯28at.com

之所以被diss,也大概并不是你用了其中某个不常用的方法(那样别人可能觉得你见多识广)。更多的时候可能是因为这几个原因:GpQ28资讯网——每日最新资讯28at.com

  1. 代码写太乱了。一个人说乱那可能是那个人的问题,如果大家都说乱,不好意思,那基本上就是你的问题了。
  2. Lambda 函数式本身的写法,尤其是对于从未接触过函数式编程的开发来说,这种写法本身就不太习惯,甚至不喜欢。负面情绪先入为主了,自然就觉得乱了。
  3. 还有就是一直被诟病调试问题,Lambda 公认的不便于调试。

先来看一段代码,也就是经常被人(除自己外的所有人)说的屎山代码。GpQ28资讯网——每日最新资讯28at.com

private static List<SimpleUser> dirtyLambda(){ List<User> userList = User.buildUserList(30); List<SimpleUser> simpleUserList = userList.stream()   .filter(user -> {    return user.getGender().equals(1)      && user.getAge() >= 18 && user.getAge() <= 45;   })   .map(user -> {    SimpleUser su = new SimpleUser();    su.setName(user.getName());    su.setAge(user.getAge());    Optional<Address> addressOptional = user.getAddressList().stream()      .findFirst();    if (addressOptional.isPresent()) {     su.setProvince(addressOptional.get().getProvince());    }    return su;   })   .sorted(Comparator.comparingInt(SimpleUser::getAge))   .collect(Collectors.toList()); return simpleUserList;}

如果不做解释,是不是脏话马上就要出来了。这其实在屎山代码中也最多拍个中等,最起码该换行的换行了,比如那个filter 中的三个并列条件,恐怕你是没见过与或非排列组合的写法,加上不怎么换行,那是真的让人抓狂。GpQ28资讯网——每日最新资讯28at.com

如果你觉得这代码还可以,那有可能你也这么写过。GpQ28资讯网——每日最新资讯28at.com

不瞒各位,这样的代码我曾经写过,而且一天之内不知道写了多少行。曾经有一个需求,一个很复杂的报表,100多个变量+图表+表格,什么最大值、最小值、环比、同比、正序、倒序、top3、top5、top10等等,就是各种能想到的维度统统算一遍。有经验的同学一看就知道,这妥妥的体力活儿啊,但是时间只有一天,没办法,越写越烦躁,直接躺平了,比上面这种更屎的代码一段接一段的写啊。写完别说改了,看都不敢看啊。GpQ28资讯网——每日最新资讯28at.com

说回正题,上面那个代码的逻辑是这样的:GpQ28资讯网——每日最新资讯28at.com

  1. 在一个 User列表中筛选男性,且年龄为18到45岁之间的;
  2. 然后将 User转换为 SimpleUser类型,获取姓名、年龄,以及地址列表(假设一个人有多个地址)中第一个的省份字段;
  3. 然后排序,按照年龄正序排序;
  4. 最后返回一个 SimpleUser 列表;

那怎么做才能让代码变得清晰易懂,告别屎山 Lambda 呢?GpQ28资讯网——每日最新资讯28at.com

不管你用什么办法,只要做到下面这3点,Lambda 代码块立马变清晰,最后一点可以适度放宽。GpQ28资讯网——每日最新资讯28at.com

不要超过 5 行

这其实没什么好说的,本身代码规约中就要求最好不写超大方法,也就是行数过多的方法,更何况是在 Lambda 中。在函数式编程中,你写的代码其实是在小括号中,作为参数的形式出现的,一个多行的参数,不敢想啊。GpQ28资讯网——每日最新资讯28at.com

不超过5行可不是说把换行符去掉,把之前的100行直接边 1 行啊。而是下面这样子,stream()就算一行了, 之后每个.function()都算一行,加起来不超过5行。GpQ28资讯网——每日最新资讯28at.com

userList.stream()  .filter()  .filter()  .map()  .collect(Collectors.toList());

不要一个stream() 后面跟3个filter,4个map,再来个排序,再整个分组,有那么复杂的业务吗,如果有,想想可能在上层设计的时候就出现问题了。GpQ28资讯网——每日最新资讯28at.com

不要出现花括号

不要出现花括号,这其实就是缩短代码行数的一个根本方法。用这个方法,强制你将逻辑抽离出来,这样,你的代码逻辑就会马上变清晰,立竿见影。GpQ28资讯网——每日最新资讯28at.com

拿前面的那端代码举个例子,其中map方法将 User转换为SimpleUser,里面有赋值操作,还有一些判断逻辑。GpQ28资讯网——每日最新资讯28at.com

.map(user -> { SimpleUser su = new SimpleUser(); su.setName(user.getName()); su.setAge(user.getAge()); Optional<Address> addressOptional = user.getAddressList().stream()   .findFirst(); if (addressOptional.isPresent()) {  su.setProvince(addressOptional.get().getProvince()); } return su;})

直接将一段抽取成方法,在 IDEA 中操作也非常方便。选中花括号中的代码,然后右键->Refactor->Extract Method,直接抽取出方法,连名字都帮忙取号了。GpQ28资讯网——每日最新资讯28at.com

图片图片GpQ28资讯网——每日最新资讯28at.com

同样的,filter()中的三个条件判断也抽离出来。然后效果就是下面这样,每一行的意图都很清晰,谁还会说不能理解。GpQ28资讯网——每日最新资讯28at.com

private static List<SimpleUser> dirtyLambda(){        List<User> userList = User.buildUserList(30);        List<SimpleUser> simpleUserList = userList.stream()                .filter(user -> filterUser(user))                .map(user -> getSimpleUser(user))                .sorted(Comparator.comparingInt(SimpleUser::getAge))                .collect(Collectors.toList());        return simpleUserList;    }    private static boolean filterUser(User user) {        return user.getGender().equals(1)                && user.getAge() >= 18 && user.getAge() <= 45;    }    private static SimpleUser getSimpleUser(User user) {        SimpleUser su = new SimpleUser();        su.setName(user.getName());        su.setAge(user.getAge());        Optional<Address> addressOptional = user.getAddressList().stream()                .findFirst();        if (addressOptional.isPresent()) {            su.setProvince(addressOptional.get().getProvince());        }        return su;    }

最好连 -> 都不要出现

再进一步,就是将 ->也干掉,虽然 ->后面没有花括号已经很简洁了,但是去掉->就不只是简洁了,而是优雅了。GpQ28资讯网——每日最新资讯28at.com

不用->,取而代之的是 ::,最终,去掉->后的代码是下面这样子。GpQ28资讯网——每日最新资讯28at.com

private static List<SimpleUser> dirtyLambda(){ List<User> userList = User.buildUserList(30); return userList.stream()   .filter(CleanLambda::filterUser)   .map(CleanLambda::getSimpleUser)   .sorted(Comparator.comparingInt(SimpleUser::getAge))   .collect(Collectors.toList());}private static boolean filterUser(User user) { return user.getGender().equals(1)   && user.getAge() >= 18 && user.getAge() <= 45;}private static SimpleUser getSimpleUser(User user) { SimpleUser su = new SimpleUser(); su.setName(user.getName()); su.setAge(user.getAge()); Optional<Address> addressOptional = user.getAddressList().stream()   .findFirst(); addressOptional.ifPresent(address -> su.setProvince(address.getProvince())); return su;}

最后

本文只是抛砖引玉,并没有介绍太细节的 Lambda 用法。授人以鱼不如授人以渔,聪明人早就这样写了,更聪明的人已经去改代码了。GpQ28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-38109-0.html被人说 Lambda 代码像...,那是没用下面这三个方法

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 数据处理利器:Pandas带你游刃有余操控结构化数据

下一篇: 源码解密协程队列和线程队列的实现原理

标签:
  • 热门焦点
  • MIX Fold3包装盒泄露 新机本月登场

    小米的全新折叠屏旗舰MIX Fold3将于本月发布,近日该机的真机包装盒在网上泄露。从图上来看,新的MIX Fold3包装盒在外观设计方面延续了之前的方案,变化不大,这也是目前小米旗舰
  • 5月安卓手机好评榜:魅族20 Pro夺冠

    性能榜和性价比榜之后,我们来看最后的安卓手机好评榜,数据来源安兔兔评测,收集时间2023年5月1日至5月31日,仅限国内市场。第一名:魅族20 Pro好评率:97.50%不得不感慨魅族老品牌还
  • WebRTC.Net库开发进阶,教你实现屏幕共享和多路复用!

    WebRTC.Net库:让你的应用更亲民友好,实现视频通话无痛接入! 除了基本用法外,还有一些进阶用法可以更好地利用该库。自定义 STUN/TURN 服务器配置WebRTC.Net 默认使用 Google 的
  • 一条抖音4亿人围观 ! 这家MCN比无忧传媒还野

    作者:Hiu 来源:互联网品牌官01 擦边少女空降热搜,幕后推手曝光被网友誉为&ldquo;纯欲天花板&rdquo;的女网红井川里予,近期因为一组哥特风照片登上热搜,引发了一场互联网世界关于
  • 大厂卷向扁平化

    来源:新熵作者丨南枝 编辑丨月见大厂职级不香了。俗话说,兵无常势,水无常形,互联网企业调整职级体系并不稀奇。7月13日,淘宝天猫集团启动了近年来最大的人力制度改革,目前已形成一
  • 重估百度丨大模型,能撑起百度的“今天”吗?

    自象限原创 作者|程心 罗辑2023年之前,对于自己的&ldquo;今天&rdquo;,百度也很迷茫。&ldquo;新业务到 2022 年底还是 0,希望 2023 年出来一个 1。&rdquo;这是2022年底,李彦宏
  • 华为HarmonyOS 4.0将于8月4日发布 或搭载AI大模型技术

    华为宣布HarmonyOS4.0将于8月4日正式发布。此前,华为已经针对开发者公布了HarmonyOS4.0,以便于开发者提前进行适配,也因此被曝光出了一些新系统的特性
  • 到手价3099元起!iQOO Neo8 Pro今日首销:安卓性能最强旗舰

    5月23日,iQOO如期举行了新品发布会,全新的iQOO Neo8系列也正式与大家见面,包含iQOO Neo8和iQOO Neo8 Pro两个版本,其中标准版搭载高通骁龙8+,而Pro版更
  • 英特尔Xe HPG游戏显卡:拥有512EU,单风扇版本

    据10 月 30 日外媒 TheVerge 消息报道,英特尔 Xe HPG Arc Alchemist 的正面实被曝光,不仅拥有 512 EU 版显卡,还拥有 128EU 的单风扇版本。另外,这款显卡 PCB
Top