首頁  >  問答  >  主體

java-ee - java8的Collectors.reducing()

Map<Integer, OperationCountVO> collect = operationInfos.stream().collect(Collectors.groupingBy(OperationCountVO::getCityId,
            Collectors.reducing(new OperationCountVO(), (OperationCountVO v1, OperationCountVO v2) -> {
                v1.setSurgeryCount(v1.getSurgeryCount() + v2.getSurgeryCount());
                v1.setCityId(v2.getCityId());
                return v1;
            })));

大概就是我想將operationInfos集合按照裡面的cityId進行分組,然後cityId一樣的話,把對象的SurgeryCount加起來返回,但是現在第一次的v1是null,
執行v1.setSurgeryCount(v1. getSurgeryCount() v2.getSurgeryCount());的時候報了空指標,我哪裡寫的有問題嗎?

三叔三叔2686 天前1299

全部回覆(1)我來回復

  • 伊谢尔伦

    伊谢尔伦2017-07-03 11:45:35

    v1null的話,那就說明operationInfos集合裡面是有null的,因為是要根據OperationCountVOcitycity前面直接加filter過濾掉

    Map<Integer, OperationCountVO> collect = operationInfos.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(OperationCountVO::getCityId,
                Collectors.reducing(new OperationCountVO(), (OperationCountVO v1, OperationCountVO v2) -> {
                    v1.setSurgeryCount(v1.getSurgeryCount() + v2.getSurgeryCount());
                    v1.setCityId(v2.getCityId());
                    return v1;
                })));

    剛評論發現...可能報錯原因還有可能是,

    Collectors.reducing中的第一個參數是new OperationCountVO(),若new出來的OperationCountVO Integer類型,不是基本類型的話,所以沒有初始化,surgeryCount就為null,在做v1.getSurgeryCount() + v2.getSurgeryCount()操作的時候就可能報錯了 (ps:對於reducing中的第二個參數BinaryOperator

    ,最好還是封裝到

    OperationCountVO物件中,看起來程式碼更聲明式一點...這樣寫程式碼太醜了...哈哈. ..或寫出來,寫成一個靜態final變數比較好,到時候可以到處呼叫嘛) 例如直接在本類上新增一個SurgeryCount屬性合併的BinaryOperator

    ,名字就叫做

    surgeryCountMerge

    public static final BinaryOperator<OperationCountVO> surgeryCountMerge = (v1, v2) -> {
        v1.setSurgeryCount(v1.getSurgeryCount() + v2.getSurgeryCount());
        return v1;
    }
    這樣下面程式碼就可以改成
    Map<Integer, OperationCountVO> collect = operationInfos.stream()
            .filter(Objects::nonNull)
            .collect(Collectors.groupingBy(OperationCountVO::getCityId,
                                    Collectors.reducing(new OperationCountVO(), surgeryCountMerge));
    這樣寫了之後,其實發現題主可能做麻煩了點,最後不就是為了返回一個Map

    嘛,所以建議不使用

    groupingBy

    ,畢竟分組返回結果是一對多這樣的結構,不是一對一的結構,那直接使用

    toMap嘛,直接點

    Map<Integer, OperationCountVO> collect = operationInfos.stream()
            .filter(Objects::nonNull)
            .collect(Collectors.toMap(OperationCountVO::getCityId, Function.identity(), surgeryCountMerge));
    這樣快多了噻,還不會報錯,哈哈

    回覆
    0
  • 取消回覆