<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    告別丑陋判空,一個Optional類就能搞定!

    VSole2023-02-27 13:52:09

    認識Optional

    Opitonal類就是Java提供的為了解決大家平時判斷對象是否為空用,通常會用 null!=obj 這樣的方式存在的判斷,從而令人頭疼導致空指針異常,同Optional的存在可以讓代碼更加簡單,可讀性跟高,代碼寫起來更高效

    Student student = new Student();
    if (null == student){
        return student為null;
    }
    return student;
    Student student = new Student();
    return Optional.ofNullable(student).orElse(student為null);
    

    測試展示類Student 代碼(如果有朋友不明白可以看一下這個):

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Student {
        private String name;
        private Integer age;
    }
    

    Optional對象創建

    首先我們先打開Optional的內部,去一探究竟 先把幾個創建Optional對象的方法提取出來

    public final class Optional<T> {
       private static final Optional EMPTY = new Optional<>();
       private final T value;
       // 我們可以看到兩個構造方格都是private 私有的
       // 說明 我們沒辦法在外面去new出來Optional對象
       private Optional() {
            this.value = null;
        }
       private Optional(T value) {
            this.value = Objects.requireNonNull(value);
        }
        // 這個靜態方法大致 是創建出一個包裝值為空的一個對象因為沒有任何參數賦值
       public static Optional empty() {
            @SuppressWarnings(unchecked)
            Optional t = (Optional) EMPTY;
            return t;
        }
        // 這個靜態方法大致 是創建出一個包裝值非空的一個對象 因為做了賦值
       public static  Optional of(T value) {
            return new Optional<>(value);
        }
        // 這個靜態方法大致是 如果參數value為空,則創建空對象,如果不為空,則創建有參對象
       public static  Optional ofNullable(T value) {
            return value == null ? empty() : of(value);
        }
     }
    

    再做一個簡單的實例展示 與上面對應

    // 1、創建一個包裝對象值為空的Optional對象
    Optional optEmpty = Optional.empty();
    // 2、創建包裝對象值非空的Optional對象
    Optional optOf = Optional.of(optional);
    // 3、創建包裝對象值允許為空也可以不為空的Optional對象
    Optional optOfNullable1 = Optional.ofNullable(null);
    Optional optOfNullable2 = Optional.ofNullable(optional);
    

    Optional.get()方法(返回對象的值)

    get()方法是返回一個option的實例值

    源碼:

    public T get() {
        if (value == null) {
            throw new NoSuchElementException(No value present);
        }
        return value;
    }
    

    也就是如果value不為空則做返回,如果為空則拋出異常 “No value present” 簡單實例展示

    Student student = new Student();
    student.setAge(18);
    System.out.println(Optional.ofNullable(student).get());
    

    Optional.isPresent()方法(判讀是否為空)

    isPresent()方法就是會返回一個boolean類型值,如果對象不為空則為真,如果為空則false

    源碼:

    public boolean isPresent() {
        return value != null;
    }
    

    簡單的實例展示:

    Student student = new Student();
    student.setAge(18);
    if (Optional.ofNullable(student).isPresent()){
        System.out.println(不為空);
    }else {
        System.out.println(為空);
    }
    

    Optional.ifPresent()方法(判讀是否為空并返回函數)

    這個意思是如果對象非空,則運行函數體

    源碼:

    public void ifPresent(Consumersuper T> consumer) {
        //如果value不為空,則運行accept方法體
        if (value != null)
            consumer.accept(value);
    }
    

    看實例:

    Student student = new Student();
    student.setAge(18);
    Optional.ofNullable(student).ifPresent(s -> System.out.println(年齡: + s.getAge()));
    

    如果對象不為空,則會打印這個年齡,因為內部已經做了NPE(非空判斷),所以就不用擔心空指針異常了

    Optional.filter()方法(過濾對象)

    filter()方法大致意思是,接受一個對象,然后對他進行條件過濾,如果條件符合則返回Optional對象本身,如果不符合則返回空Optional

    源碼:

    public Optional filter(Predicatesuper T> predicate) {
        Objects.requireNonNull(predicate);
        //如果為空直接返回this
        if (!isPresent())
            return this;
        else
            //判斷返回本身還是空Optional
            return predicate.test(value) ? this : empty();
    }
    

    簡單實例:

    Student student = new Student();
    student.setAge(18);
    Optional.ofNullable(student).filter(s -> s.getAge()>10);
    

    Optional.flatMap()方法(Optional對象進行二次包裝)

    map()方法將對應Optional< Funcation >函數式接口中的對象,進行二次運算,封裝成新的對象然后返回在Optional中

    源碼:

    public Optional flatMap(Functionsuper T, Optional> mapper) {
        Objects.requireNonNull(mapper);
        if (!isPresent())
            return empty();
        else {
            return Objects.requireNonNull(mapper.apply(value));
        }
    }
    

    實例:

    Student student = new Student();
    student.setAge(18);
    Optional optName = Optional.ofNullable(student).map(s -> Optional.ofNullable(s.getName()).orElse(name為空));
    Optional.orElse()方法(為空返回對象)
    常用方法之一,這個方法意思是如果包裝對象為空的話,就執行orElse方法里的value,如果非空,則返回寫入對象
    源碼:
    public T orElse(T other) {
        //如果非空,返回value,如果為空,返回other
        return value != null ? value : other;
    }
    實例:
    Student student = new Student();
    student.setAge(18);
    Optional.ofNullable(student).orElse(new Student(小明, 12));
    Optional.orElseGet()方法(為空返回Supplier對象)
    這個與orElse很相似,入參不一樣,入參為Supplier對象,為空返回傳入對象的.get()方法,如果非空則返回當前對象。
    源碼:
    public T orElseGet(Supplier other) {
        return value != null ? value : other.get();
    }
    實例:
    Optional> sup=Optional.ofNullable(Student::new);
    //調用get()方法,此時才會調用對象的構造方法,即獲得到真正對象
    Optional.ofNullable(student).orElseGet(sup.get());
    Suppiler是一個接口,是類似Spring的懶加載,聲明之后并不會占用內存,只有執行了get()方法之后,才會調用構造方法創建出對象 創建對象的語法的話就是Supplier supStudent= Student::new; 需要使用時supStudent.get()即可
    Optional.orElseThrow()方法(為空返回異常)
    方法作用的話就是如果為空,就拋出你定義的異常,如果不為空返回當前對象,在實戰中所有異常肯定是要處理好的,為了代碼的可讀性
    源碼:
    public  T orElseThrow(Supplier exceptionSupplier) throws X {
        if (value != null) {
            return value;
        } else {
            throw exceptionSupplier.get();
        }
    }
    實例:
    //簡單的一個查詢
    Member member = memberService.selectByPhone(request.getPhone());
    Optional.ofNullable(member).orElseThrow(() -> new ServiceException(沒有查詢的相關數據));
    相似方法進行對比分析
    可能看到這,沒用用過的話會覺得orElse()和orElseGet()還有orElseThrow()很相似,map()和flatMap()好相似,不用著急,都是從這一步過來的,我再給大家總結一下不同方法的異同點 orElse()和orElseGet()和orElseThrow()的異同點
    方法效果類似,如果對象不為空,則返回對象,如果為空,則返回方法體中的對應參數,所以可以看出這三個方法體中參數是不一樣的 orElse(T 對象) orElseGet(Supplier < T >對象) orElseThrow(異常)
    map()和orElseGet的異同點
    方法效果類似,對方法參數進行二次包裝,并返回,入參不同 map(function函數) flatmap(Optional< function >函數)
    具體要怎么用,要根據業務場景以及代碼規范來定義,下面可以簡單看一下我在實戰中怎用使用神奇的Optional。
    實戰場景
    場景1:在service層中 查詢一個對象,返回之后判斷是否為空并做處理
    //查詢一個對象
    Member member = memberService.selectByIdNo(request.getCertificateNo());
    //使用ofNullable加orElseThrow做判斷和操作
    Optional.ofNullable(member).orElseThrow(() -> new ServiceException(沒有查詢的相關數據));
    場景2:我們可以在dao接口層中定義返回值時就加上Optional
    public interface LocationRepository extends JpaRepository<Location, String> {
    Optional findLocationById(String id);
    }
    然在是Service中
    public TerminalVO findById(String id) {
        //這個方法在dao層也是用了Optional包裝了
        Optional terminalOptional = terminalRepository.findById(id);
        //直接使用isPresent()判斷是否為空
        if (terminalOptional.isPresent()) {
        //使用get()方法獲取對象值
            Terminal terminal = terminalOptional.get();
            //在實戰中,我們已經免去了用set去賦值的繁瑣,直接用BeanCopy去賦值
            TerminalVO terminalVO = BeanCopyUtils.copyBean(terminal, TerminalVO.class);
            //調用dao層方法返回包裝后的對象
            Optional location = locationRepository.findLocationById(terminal.getLocationId());
            if (location.isPresent()) {
                terminalVO.setFullName(location.get().getFullName());
            }
            return terminalVO;
        }
        //不要忘記拋出異常
        throw new ServiceException(該終端不存在);
    }
    實戰場景還有很多,包括return時可以判斷是否返回當前值還是跳轉到另一個方法體中,其它的還有很多。
    Optional使用注意事項
    Optional真么好用,真的可以完全替代if判斷嗎?我想這肯定是大家使用完之后Optional之后可能會產生的想法,答案是否定的 舉一個最簡單的栗子:
    例子:如果我只想判斷對象的某一個變量是否為空并且做出判斷呢?
    Person person=new Person();
    person.setName();
    persion.setAge(2);
    //普通判斷
    if(StringUtils.isNotBlank(person.getName())){
       //名稱不為空執行代碼塊
    }
    //使用Optional做判斷
    Optional.ofNullable(person).map(p -> p.getName()).orElse(name為空);
    我覺得這個例子就能很好的說明這個問題,只是一個很簡單判斷,如果用了Optional我們還需要考慮包裝值,考慮代碼書寫,考慮方法調用,雖然只有一行,但是可讀性并不好,如果別的程序員去讀,我覺得肯定沒有if看的明顯。
    Jdk 9對Optional優化
    首先增加了三個方法: or()、ifPresentOrElse() 和 stream()。or() 與orElse等方法相似,如果對象不為空返回對象,如果為空則返回or()方法中預設的值。
    ifPresentOrElse() 方法有兩個參數:一個 Consumer 和一個 Runnable。如果對象不為空,會執行 Consumer 的動作,否則運行 Runnable。相比ifPresent()多了OrElse判斷。stream()將Optional轉換成stream,如果有值就返回包含值的stream,如果沒值,就返回空的stream。
    感謝閱讀,希望對你有所幫助 :) 
    來源:blog.csdn.net/weixin_45581915/article/
    details/124493863
    -End-
    
    最近有一些小伙伴,讓我幫忙找一些 面試題 資料,于是我翻遍了收藏的 5T 資料后,匯總整理出來,可以說是程序員面試必備!所有資料都整理到網盤了,歡迎下載!
    
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    Optional對象創建首先我們先打開Optional的內部,去一探究竟 先把幾個創建Optional對象的方法提取出來public?我們可以看到兩個構造方格都是private?我們沒辦法在外面去new出來Optional對象。這個靜態方法大致?是創建出一個包裝值為一個對象因為沒有任何參數賦值。再做一個簡單的實例展示 與上面對應//?//如果為直接返回this
    2024年,是國產芯片的分水嶺,強者愈強,弱者愈弱。從今以后,請不要再講國產芯片替代,要講芯片性能和競爭力,國產芯片替代的篇章就此翻過。
    起因前段時間參加了一場政務hw,各種waf基本上告別目錄掃描,sql注入,暴力破解這些行為,主要采取的快速打點方式有弱口令,文件上傳,反序列化及各種邏輯漏洞。最后點了一下burp的顯示發現json多了一個回車,修改成原始請求,也看到結果最后刪除換行,請求成功,成功修改了管理員的密碼,進入系統,然后就是很簡單是樸實無華的文件上傳getshell,這里不做截圖了。
    美國伊利諾斯州的林肯學院宣布將于本周五 5 月 13 日永久關閉,成為第一所因勒索軟件攻擊而倒閉的美國高等院校。刊登在學校官網上的告別信稱,它經歷了兩次世界大戰、西班牙流感和大蕭條,但無法應付新冠疫情和去年 12 月發生的勒索軟件攻擊。林肯學院以亞伯拉罕林肯總統的名字命名,1865 年動工,至今有 157 年歷史,是少數幾所以黑人為主體的鄉村學院之一。2021 年 12月林肯學院遭到了勒索軟件攻擊
     這是反思和感恩的季節。當我們翻開新的篇章時,我們會繼續吸取今年的經驗教訓,對未來的可能性感到興奮。 現在是時候以寶貴的見解來結束這一年了。這是我們 2023 年時事通訊的最終版本。讓我們以美好的心情結束這一年!嘿, 本著節日的精神,我們致以最熱烈的祝愿,祝愿您與親人共度歡樂而寧靜的時光。在我們告別一個非凡的一年之際,我們預計您和我們都會迎來更美好的一年。 是時候用寶貴的見解
     ManageEngine OpManager MSP 現在集成了 IP 地址管理 (IPAM) 和交換機端口映射器 (SPM) 插件。但這對 MSP 意味著什么?它如何解決 MSP 日常面臨的挑戰?MSP 遇到的挑戰:快速回顧MSP 應對復雜的環境,努力確保高可用性并從網絡停機中快速恢復。在管理 IP 地址、交換機端口以及日益關注的惡意設備滲透網絡方面,傳統工具往往存在不足。 OpMa
    4月15日,由奇安信集團提供技術支持的第二屆廣東大學生網絡安全攻防大賽成功落下帷幕。
    在安服仔的日子里,發現下面的人輸出的滲透測試報告結果不規范,主要在報告質量、內容、字體、及修復方案中存在諸多問題,而且大部分安服仔需要對每次的項目結果進行統計整理,方便后續跟蹤復測。因此研發了Savior-滲透測試報告輔助生成系統,起這個名字也是為了拯救大多數逗逼滲透測試工程師,告別繁瑣的滲透測試報告編寫過程及漏洞統計過程。這是一個菜狗?通宵一年寫的菜雞?項目。。。
    8月4日下午,在2022新京報貝殼財經夏季峰會“下一代互聯網離我們有多遠” 數字技術主題論壇上,中國工程院院士、中國互聯網協會咨詢委員會主任鄔賀銓發表了主旨演講。他指出,中國互聯網行業進入轉型期,互聯網企業告別了野蠻生長階段,希望互聯網企業正確理解治理,也相信國家在監管上將以一種長期的、穩定的方式來進行,讓中國的互聯網行業發展更加規范有序。web3.0更多只是web2.0的演進版本,還承擔不了作為
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类