1. 程式人生 > >Java8函數式接口以及lambda表達式實踐

Java8函數式接口以及lambda表達式實踐

場景 value sta 提高 編寫 reduce 入庫 () 僅供參考

最近重新深入了解和學習了Java8的函數式接口以及lambda表達式,發現以前寫的代碼大多都是偽-函數表達式,因此重新精煉了一下的這部分代碼,僅供參考,如有更好的方式,歡迎在評論區留言。

  1.計算訂單總金額

  訂單總金額一般是在後臺循環疊加每個購買商品的金額已獲取到,通常的方式如下

     BigDecimal totalAmount = new BigDecimal(0);
     for (VenditionProduct venditionProduct : venditionVo.getVenditionProductList()) { totalAmount = totalAmount.add(venditionProduct.getPrice()); }

  用lambda的方式如下

        BigDecimal totalPrice = venditionVo.getVenditionProductList().stream().map(VenditionProduct::getPrice).reduce(BigDecimal::add).orElse(BigDecimal.ONE);

  2.循環集合組裝新的類

  面對的場景是更新字段,下面將出現一個更新方法updateNotNull,該方法是一個通用方法,僅更新不為字段null的屬性,由於venditionProduct中只允許Product的price和sellAmount屬性,因此不能直接將前端傳遞過來的集合直接進行更新,需要提取這兩個屬性重新組裝成新的類。

  比較Low的做法如下(偽-函數表達式)

技術分享圖片
        venditionProductList.forEach(venditionProduct -> {
            VenditionProduct newVenditionProduct = new VenditionProduct();
            newVenditionProduct.setId(venditionProduct.getId());
            newVenditionProduct.setSellAmount(venditionProduct.getSellAmount());
            newVenditionProduct.setPrice(venditionProduct.getPrice());
            updateNotNull(newVenditionProduct);
        });
技術分享圖片

  以下是真-函數表達式

 venditionProductList.stream().map(venditionProduct ->
                VenditionProduct.build(venditionProduct.getId(), venditionProduct.getSellAmount(), venditionProduct.getPrice()))
                .forEach(this::updateNotNull);

  3.在枚舉中的應用

  我們有如下的枚舉類

技術分享圖片
  public enum RecordTypeEnum {
        /**
         * 0為手工入庫  1生產入庫  2手工出庫   4 退貨入庫
         */
        MANUAL_STORE(0),
        PRODUCE_STORE(1),
        MANUAL_OUT(2),
        VENDITION_OUT(3),
        REFUND_IN(4),;
        private final int type;

        RecordTypeEnum(int type) {
            this.type = type;
        }
    }
技術分享圖片

  遇到的場景可能是希望通過type查找對應的枚舉值

  通常的方式是

技術分享圖片
 public static RecordTypeEnum getRecordTypeEnum(int type) {
        for (RecordTypeEnum typeEnum :
                RecordTypeEnum.values()) {
            if (typeEnum.getType() == type) {
                return typeEnum;
            }
        }
        return null; 
    }
技術分享圖片

  Java8中我們可以這樣子做  

 public static RecordTypeEnum getRecordTypeEnum1(int type) {
        return Arrays.stream(RecordTypeEnum.values()).filter(recordTypeEnum -> recordTypeEnum.getType() == type).findFirst().orElse(null);
    }

  還有我們可能需要獲取對應的數組

 public String[] getEnumStringArray() {
        return Arrays.stream(RecordTypeEnum.values()).map(Enum::name).toArray(String[]::new);
    }

  4.編寫一行的lambda語法有助於提高代碼的健壯性(這裏的重點不是lambda的使用技巧,但是覺得有必要記錄一下)

  面對的業務場景是增加生產產品的生產計劃表(plan),一張計劃表可以有多個產品,一個產品需要一或者多個原料組成,因此關系是一對多對多,下面看一下我最先的寫的代碼(偽-函數表達式)

技術分享圖片

  重點關註最後的一個方法,最初的實現是這樣子的

  技術分享圖片

  這裏的問題有兩個,一是簡短的 lambda 表達式能提高代碼可讀性,這是函數式編程的重要好處之一,這裏完全忽視了這一點,二是planProduct(產品)和planMaterial(原料)是關聯在一起的,也就是說增加原料這個操作,應該封裝在增加產品這個操作裏面,修改後的代碼如下

技術分享圖片

技術分享圖片

技術分享圖片

  這裏做記錄的原因是在將lambda表達式精簡成一行代碼的同時,需要不斷的調整代碼的結構,使之朝向更加的穩定健壯的方向發展,原本的代碼邏輯雖然過程也易懂,但是又醜又長,擔當了太多的任務。

  5.根據已知類型集合轉換成另一個類型的集合

  大致邏輯是獲取生產產品相關聯的原料(包括規格),實際是上就是需要根據List<ProductMaterail>轉換成List<PlanMaterial>

  技術分享圖片

  這裏的做法還是犯了跟上面一條同樣的錯誤,後面調整如下

  技術分享圖片

Java8函數式接口以及lambda表達式實踐