成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

被人說 Lambda 代碼像...,那是沒用下面這三個方法

開發 前端
Lambda 函數式本身的寫法,尤其是對于從未接觸過函數式編程的開發來說,這種寫法本身就不太習慣,甚至不喜歡。負面情緒先入為主了,自然就覺得亂了。

說 Lambda 寫的代碼像屎山,其實就是代碼不夠干凈嘛。說到底并不是不會用 Lambda 本身的 API,而是用的方式不對。

Java Lambda 本身提供了非常豐富的方法庫,大多數時候我們常用的方法也就為數不多的那幾個。Lambda 的使用方法之前專門寫過文章,8000字,讓你徹底了解 Java 8 的 Lambda、函數式接口、Stream 用法和原理。在掘金社區已經獲得了將近600個贊,1200多個收藏。

之所以被diss,也大概并不是你用了其中某個不常用的方法(那樣別人可能覺得你見多識廣)。更多的時候可能是因為這幾個原因:

  1. 代碼寫太亂了。一個人說亂那可能是那個人的問題,如果大家都說亂,不好意思,那基本上就是你的問題了。
  2. Lambda 函數式本身的寫法,尤其是對于從未接觸過函數式編程的開發來說,這種寫法本身就不太習慣,甚至不喜歡。負面情緒先入為主了,自然就覺得亂了。
  3. 還有就是一直被詬病調試問題,Lambda 公認的不便于調試。

先來看一段代碼,也就是經常被人(除自己外的所有人)說的屎山代碼。

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 中的三個并列條件,恐怕你是沒見過與或非排列組合的寫法,加上不怎么換行,那是真的讓人抓狂。

如果你覺得這代碼還可以,那有可能你也這么寫過。

不瞞各位,這樣的代碼我曾經寫過,而且一天之內不知道寫了多少行。曾經有一個需求,一個很復雜的報表,100多個變量+圖表+表格,什么最大值、最小值、環比、同比、正序、倒序、top3、top5、top10等等,就是各種能想到的維度統統算一遍。有經驗的同學一看就知道,這妥妥的體力活兒啊,但是時間只有一天,沒辦法,越寫越煩躁,直接躺平了,比上面這種更屎的代碼一段接一段的寫啊。寫完別說改了,看都不敢看啊。

說回正題,上面那個代碼的邏輯是這樣的:

  1. 在一個 User列表中篩選男性,且年齡為18到45歲之間的;
  2. 然后將 User轉換為 SimpleUser類型,獲取姓名、年齡,以及地址列表(假設一個人有多個地址)中第一個的省份字段;
  3. 然后排序,按照年齡正序排序;
  4. 最后返回一個 SimpleUser 列表;

那怎么做才能讓代碼變得清晰易懂,告別屎山 Lambda 呢?

不管你用什么辦法,只要做到下面這3點,Lambda 代碼塊立馬變清晰,最后一點可以適度放寬。

不要超過 5 行

這其實沒什么好說的,本身代碼規約中就要求最好不寫超大方法,也就是行數過多的方法,更何況是在 Lambda 中。在函數式編程中,你寫的代碼其實是在小括號中,作為參數的形式出現的,一個多行的參數,不敢想啊。

不超過5行可不是說把換行符去掉,把之前的100行直接邊 1 行啊。而是下面這樣子,stream()就算一行了, 之后每個.function()都算一行,加起來不超過5行。

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

不要一個stream() 后面跟3個filter,4個map,再來個排序,再整個分組,有那么復雜的業務嗎,如果有,想想可能在上層設計的時候就出現問題了。

不要出現花括號

不要出現花括號,這其實就是縮短代碼行數的一個根本方法。用這個方法,強制你將邏輯抽離出來,這樣,你的代碼邏輯就會馬上變清晰,立竿見影。

拿前面的那端代碼舉個例子,其中map方法將 User轉換為SimpleUser,里面有賦值操作,還有一些判斷邏輯。

.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,直接抽取出方法,連名字都幫忙取號了。

圖片圖片

同樣的,filter()中的三個條件判斷也抽離出來。然后效果就是下面這樣,每一行的意圖都很清晰,誰還會說不能理解。

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;
    }

最好連 -> 都不要出現

再進一步,就是將 ->也干掉,雖然 ->后面沒有花括號已經很簡潔了,但是去掉->就不只是簡潔了,而是優雅了。

不用->,取而代之的是 ::,最終,去掉->后的代碼是下面這樣子。

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 用法。授人以魚不如授人以漁,聰明人早就這樣寫了,更聰明的人已經去改代碼了。

責任編輯:武曉燕 來源: 古時的風箏
相關推薦

2019-06-06 08:48:14

代碼函數編程語言

2021-04-16 09:17:39

機器學習人工智能AI

2017-01-06 10:07:39

Linuxwindowsatime

2017-11-02 13:15:18

Linux

2018-04-28 11:03:58

2022-06-28 08:03:06

緩存Redis

2022-03-30 14:19:36

云安全云計算風險

2023-10-26 07:29:06

mongodb十六進制ID

2015-09-23 09:48:04

2024-12-20 07:30:00

C++17代碼

2021-10-15 08:32:03

RocketMQ數據結構架構

2025-01-21 10:56:41

LLMs應用系統

2021-04-27 22:38:41

代碼開發前端

2020-10-09 11:30:07

Redis緩存數據庫

2021-02-06 12:28:53

低代碼開發者數字化

2021-05-13 09:27:13

JavaThreadLocal線程

2021-03-30 15:10:50

Java序列化

2020-04-16 14:53:39

JavaScript開發

2023-11-03 08:14:44

CSS生成器代碼

2021-12-23 10:05:43

機器學習人工智能黑盒模型
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 一区二区三区在线 | 亚洲一区二区三区四区五区午夜 | 亚洲精品一 | 亚洲精久| 天天插天天舔 | 中文字幕亚洲一区 | 99精品一区二区三区 | 国产成人99久久亚洲综合精品 | 午夜影院中文字幕 | 久久免费高清 | 国产精品视频免费看 | 亚洲高清在线观看 | 日日操夜夜操天天操 | 超碰av免费| 成人亚洲片 | 爱草在线 | 国产成人99久久亚洲综合精品 | 久久狠狠| 91精品国产综合久久婷婷香蕉 | 羞羞涩涩在线观看 | 在线成人av| 日韩在线资源 | 欧美亚州| 国产精品夜色一区二区三区 | 搞黄网站在线观看 | 国产特级毛片 | 黄色免费观看网站 | 亚洲高清视频一区 | 国产成人一区 | 日本一区二区在线视频 | 在线看亚洲 | 中文字幕在线电影观看 | 亚洲色图第一页 | 天天草天天爱 | 亚洲黄色一级 | 久草免费福利 | 99亚洲视频 | 精品视频在线播放 | 97人人澡人人爽91综合色 | 欧美精品91 | 一级黄色片在线免费观看 |