【Optional】Java1.8新特性

Java 8 引入的一個很有趣的特性是 Optional 類。Optional 類主要解決的問題是臭名昭著的空指針異常(NullPointerException)。

合理使用Optional可以很好避免 NullPointerException

加入存在如下對象:

@Data
public class Competition {

    private String name;

    private String gender;

    private int score;

    private Result result;

    @Data
    public static class Result{
        private String last;
        private String space;
        private Champion champion;

        @Data
        public static class Champion{
            private String pion;
            private String str;
        }
    }
}

1、基礎用法

如果我們要獲取Champion對象中的str的值,爲避免空指針我們可能需要寫以下代碼:

Competition competition = new Competition();
        competition.setGender("男");
        competition.setName("Test");
        competition.setScore(92);

        Competition.Result result = new Competition.Result();
        result.setLast("last");
        result.setSpace("pace");

        Competition.Result.Champion champion = new Competition.Result.Champion();
        champion.setPion("pion");
        champion.setStr("buffer");

        competition.setResult(result);
        result.setChampion(champion);
        
        String str = "";
        if(competition != null){
            Competition.Result result1 = competition.getResult();
            if(result1 != null){
                Competition.Result.Champion champion1 = result1.getChampion();
                
                if(champion1 != null){
                    str = champion1.getStr();
                }
            }
        }
        System.out.println("結果:" + str);

如果對象中嵌套的對象太多,我們可能需要寫更多層的if判斷,就爲了一個字段的判斷,代碼寫很多行,代碼量多不說,也容易視覺疲勞。如果使用Optional類,我們可以將代碼優化爲如下:

    public static void main(String[] args) {
        Competition competition =new Competition();
        competition.setGender("男");
        competition.setName("Test");
        competition.setScore(92);

        Competition.Result result =new Competition.Result();
        result.setLast("last");
        result.setSpace("pace");

        Competition.Result.Champion champion = new Competition.Result.Champion();
        champion.setPion("pion");
        champion.setStr("buffer");

        competition.setResult(result);
        result.setChampion(champion);


//       以下代碼,只要存在空指針(result對象空指針或champion對象空指針)均會執行orElse代碼,輸出空字符串
        System.out.println(
                Optional.ofNullable(competition)
                .map(t -> t.getResult())
                .map(Competition.Result::getChampion)
                .map(s-> s.getStr())
                .orElse(""));
     }

//如果我們不想要默認值,可以拋出異常,使用orElseThrow方法
//可以將t理解爲對象,即對象實例competition

        System.out.println(
                Optional.ofNullable(competition)
                .map(t -> t.getResult())
                .map(Competition.Result::getChampion)
                .map(s -> s.getStr())
//                .orElse(""));
                .orElseThrow(() ->new IllegalArgumentException("Error")));

2、filter數據過濾

filter方法檢查給定的Option值是否滿足某些條件,如果滿足則返回同一個Option實例,否則返回空Optional

		Optional<String> name = Optional.of("michael");
        Optional<String> longName = name.filter((value) -> value.length() > 6);

		//我們可以通過以下代碼輸出filter方法的結果:
		System.out.println(longName.orElse("The name is less than 6 characters"));
		System.out.println(longName.get());

代碼:

package com.code.study.example.optional;

import lombok.Data;

/**
 * @author: Mwl
 * @date: 2020/4/5 5:12 下午
 **/
@Data
public class Competition {

    private String name;

    private String gender;

    private int score;

    private Result result;

    @Data
    public static class Result{
        private String last;
        private String space;
        private Champion champion;

        @Data
        public static class Champion{
            private String pion;
            private String str;
        }
    }
    
}



package com.code.study.example.optional;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum OperateContentEnum {

    /**
     * 操作類型
     */

    CREATE_BILL("生成對賬單",  "系統自動觸發", null),
    USE_OFFSET_AMOUNT("付款單已使用抵消金額", "系統自動觸發", "抵消金額:{0}");

    private String operateRecord;   //操作記錄
    private String operatorName;    //操作人
    private String remark;      //備註
}




package com.code.study.example.optional;

import java.text.MessageFormat;
import java.util.Optional;

/**
 * @author: Mwl
 * @date: 2020/4/5 5:16 下午
 **/
public class Main {

    //格式化
    public static String buildLogDo(OperateContentEnum contentEnum, String extraString){
        String str = Optional.ofNullable(extraString)
                .map(s -> MessageFormat.format(contentEnum.getRemark(), s))
                .orElse(contentEnum.getRemark());
        //這裏s 理解爲就是extraString,如果extraString爲對象,s就是對象的實例,字符串就是其本身

        return str;
    }


    public static void main(String[] args) {
        Competition competition =new Competition();
        competition.setGender("男");
        competition.setName("Test");
        competition.setScore(92);

        Competition.Result result =new Competition.Result();
        result.setLast("last");
        result.setSpace("pace");

        Competition.Result.Champion champion = new Competition.Result.Champion();
        champion.setPion("pion");
        champion.setStr("buffer");

        competition.setResult(result);
        result.setChampion(champion);


        System.out.println(
                Optional.ofNullable(competition)
                .map(t -> t.getResult())
                .map(Competition.Result::getChampion)
                .map(s -> s.getStr())
//                .orElse(""));
                .orElseThrow(() ->new IllegalArgumentException("Error")));


        System.out.println("=======================");
        System.out.println(buildLogDo(OperateContentEnum.USE_OFFSET_AMOUNT, "lalla"));

        System.out.println("=======================");

        Optional<String> name = Optional.of("michael");
        Optional<String> longName = name.filter((value) -> value.length() > 6);

        System.out.println(longName.orElse("The name is less than 6 characters"));

        System.out.println("=======================");

        System.out.println(longName.get());

        System.out.println("=======================");
        Optional<Competition> user = Optional.ofNullable(competition);
        System.out.println(user.get().getName());


    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章