亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JDK8新出Optional類的方法探索與思考分析

 更新時間:2023年08月23日 14:18:54   作者:彼岸花開可奈何  
這篇文章主要為大家介紹了JDK8新出Optional類的發(fā)方法示例探索與思考分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

引言

所有的 Java 程序員基本都會遇到 NullPointerException 異常,一般處理這個問題可能不會是很難,但是有時去排查到底是哪引起的會耗費很長時間很是麻煩。最近了解到 JDK1.8 新增加了一個 Optional 類可以避免一些 NullPointerException 異常,下面讓我們一起去了解一下它吧。

基于值的類(Value-based Classes)

有些類,如 java.util.Optional 和 java.time.LocalDateTime,是基于值的。基于值的類的實例:

  • 是最終的和不可變的(盡管可能包含對可變對象的引用);
  • 具有 equals、hashCode 和 toString 的實現(xiàn),這些實現(xiàn)僅根據(jù)實例的狀態(tài)計算,而不是根據(jù)實例的標識或任何其他對象或變量的狀態(tài)計算;
  • 不使用對身份敏感的操作,例如實例之間的引用相等(==)、實例的身份哈希代碼或?qū)嵗膬?nèi)部鎖進行同步;
  • 僅基于 equals() 而不是基于引用相等 (==) 被視為相等;
  • 沒有可訪問的構(gòu)造函數(shù),而是通過工廠方法進行實例化,這些方法不提交返回實例的標識;
  • 當相等時是可自由替換的,這意味著在任何計算或方法調(diào)用中,根據(jù) equals() 交換任何兩個相等的實例 x 和 y 都不會產(chǎn)生明顯的行為變化。

如果程序試圖區(qū)分對基于值的類的相等值的兩個引用,無論是直接通過引用相等,還是間接通過調(diào)用同步、身份哈希、序列化或任何其他身份敏感機制,都可能產(chǎn)生不可預(yù)測的結(jié)果。在基于值的類的實例上使用這種對身份敏感的操作可能會產(chǎn)生不可預(yù)測的影響,應(yīng)該避免。

簡單地說,基于值的類的實例是最終的,不可變的,并且這些實例沒有適當?shù)臓顟B(tài)和標識,因此某些操作是特定于標識的,因此不應(yīng)使用。

一、Optional中的基本方法

Optional 類位于 java.util 包下,它是一個容器對象,可能包含也可能不包含非空值。

這是一個基于值的類;在Optional實例上使用身份敏感操作(包括引用相等(==)、身份哈希碼或同步)可能會產(chǎn)生不可預(yù)測的結(jié)果,應(yīng)該避免。

1、創(chuàng)建方法

empty()

返回一個空的 Optional 實例

public class Main {
    public static void main(String[] args) {
        System.out.println(Optional);
    }
}
// 輸出
Optional.empty

注意:不要通過與Option.empty()返回的實例進行==比較來避免測試對象是否為空,因為不能保證它是單例的。

of(T value)

返回一個帶值的 Optional,如果 value 是 null 會拋出 NullPointerException 異常

public static void main(String[] args) {
        Optional<String> emanjusaka = Optional.of("emanjusaka");
        System.out.println(emanjusaka);
    }
// 輸出
Optional[emanjusaka]

ofNullable(T value)

如果非空,返回描述指定值的 Optional,否則返回空 Optional。

public static void main(String[] args) {
        Optional<String> emanjusaka = Optional.ofNullable("emanjusaka");
        System.out.println(emanjusaka);

        Optional<String> empty = Optional.ofNullable(null);
        System.out.println(empty);
    }
// 輸出
Optional[emanjusaka]
Optional.empty

2、判斷方法

isPresent()

如果存在值則返回 true,否則返回 false。

public static void main(String[] args) {
        Optional<String> emanjusaka = Optional.ofNullable("emanjusaka");
        System.out.println(emanjusaka);
        System.out.println(emanjusaka.isPresent());
        Optional<String> empty = Optional.ofNullable(null);
        System.out.println(empty);
        System.out.println(empty.isPresent());
    }
//輸出
Optional[emanjusaka]
true
Optional.empty
false

?ifPresent(Consumer<? super T> consumer)??

如果存在值,則使用該值調(diào)用指定的消費者,否則什么都不做。

public static void main(String[] args) {
        Optional<String> emanjusaka = Optional.of("emanjusaka");
        Consumer<String> consumer = s -> {
            s = "hello " + s;
            System.out.println(s);
        };
        System.out.println(emanjusaka);
        emanjusaka.ifPresent(consumer);
    }
// 輸出
Optional[emanjusaka]
hello emanjusaka

一般用于判斷 Optional 是否為空,并在不為空的情況下執(zhí)行相應(yīng)的操作。

3、獲取方法

get()

如果這個 Optional 中存在一個值,則返回該值,否則拋出 NoSuchElementException。

public static void main(String[] args) {
        Optional<String> emanjusaka = Optional.ofNullable("emanjusaka");
        System.out.println(emanjusaka);
        System.out.println(emanjusaka.get());
        Optional<String> empty = Optional.ofNullable(null);
        System.out.println(empty);
        System.out.println(empty.get());
    }
// 輸出
Optional[emanjusaka]
emanjusaka
Optional.empty
Exception in thread "main" java.util.NoSuchElementException: No value present
    at java.util.Optional.get(Optional.java:135)
    at org.example.Main.main(Main.java:13)

filter(Predicate<? super T> predicate)

如果存在一個值,并且該值與給定的過濾條件匹配,則返回一個描述該值的 Optional,否則返回一個空的 Optional。

public static void main(String[] args) {
        Optional<String> emanjusaka = Optional.of("emanjusaka");
        System.out.println(emanjusaka);
        System.out.println(emanjusaka.filter(s -> {
            return "emanjusaka".equals(s);
        }));
        System.out.println(emanjusaka.filter(s -> false));
    }
// 輸出
Optional[emanjusaka]
Optional[emanjusaka]
Optional.empty

map(Function<? super T, ? extends U> mapper)

如果存在值,則將提供的映射函數(shù)應(yīng)用于該值,如果結(jié)果為非 null,則返回一個描述結(jié)果的 Optional。否則返回空的 Optional。

public static void main(String[] args) {
        User user = new User();
        user.setName("emanjusaka");
        Optional<User> optional = Optional.of(user);
        System.out.println(optional);
        System.out.println(optional.map(User::getName));
        User userEmpty = new User();
        Optional<User> optionalEmpty = Optional.of(userEmpty);
        System.out.println(optionalEmpty);
        System.out.println(optionalEmpty.map(User::getName));
    }
    private static class User {
        private String name;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }
// 輸出
Optional[org.example.Main$User@2503dbd3]
Optional[emanjusaka]
Optional[org.example.Main$User@6d03e736]
Optional.empty

flatMap(Function<? super T, Optionalu> mapper)

如果存在值,請將提供的 Optional 方位映射函數(shù)應(yīng)用于該值,返回該結(jié)果,否則返回空的 Optional。此方法類似于map(Function),但提供的 mapper 的結(jié)果已經(jīng)是 Optional,并且如果調(diào)用,flatMap 不會用額外的 Optional 包裝它。

public static void main(String[] args) {
        User user = new User();
        user.setName("emanjusaka");
        user.setAge(Optional.of(35));
        Optional<User> optional = Optional.of(user);
        System.out.println(optional);
        System.out.println(optional.map(User::getAge));
        System.out.println(optional.flatMap(User::getAge));
    }
    private static class User {
        private String name;
        private Optional<Integer> age;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Optional<Integer> getAge() {
            return age;
        }
        public void setAge(Optional<Integer> age) {
            this.age = age;
        }
    }
// 輸出
Optional[org.example.Main$User@2503dbd3]
Optional[Optional[35]]
Optional[35]

這個例子中體現(xiàn)出了 map 和 flatMap 方法的區(qū)別,map 方法會在返回時用 Optional 進行包裝而 flatMap 方法不會再進行額外的包裝。

orElse(T other)

如果存在這個值則返回這個值,否則返回傳入的值 other

public static void main(String[] args) {
        Optional<String> optional = Optional.of("emanjusaka");
        System.out.println(optional);
        System.out.println(optional.orElse(null));
        Optional<String> optionalEmpty = Optional.ofNullable(null);
        System.out.println(optionalEmpty);
        System.out.println(optionalEmpty.orElse("empty"));
    }
// 輸出
Optional[emanjusaka]
emanjusaka
Optional.empty
empty

orElseGet(Supplier<? extends T> other)

如果存在這個值則返回這個值,否則調(diào)用 other 并返回該調(diào)用的結(jié)果。

public static void main(String[] args) {
        Optional<String> optional = Optional.of("emanjusaka");
        System.out.println(optional);
        System.out.println(optional.orElseGet(() -> "hello emanjusaka"));
        Optional<String> optionalEmpty = Optional.ofNullable(null);
        System.out.println(optionalEmpty);
        System.out.println(optionalEmpty.orElseGet(() -> "hello emanjusaka"));
    }
// 輸出
Optional[emanjusaka]
emanjusaka
Optional.empty
hello emanjusaka

orElseThrow(Supplier? extends X exceptionSupplier)

返回包含的值(如果存在),否則拋出由所提供創(chuàng)建的異常。

public static void main(String[] args) {
        Optional<String> optionalEmpty = Optional.ofNullable(null);
        System.out.println(optionalEmpty);
        System.out.println(optionalEmpty.orElseThrow(ArithmeticException::new));
    }
// 輸出
Optional.empty
Exception in thread "main" java.lang.ArithmeticException
    at java.util.Optional.orElseThrow(Optional.java:290)
    at org.example.Main.main(Main.java:9)

二、Optional 中方法的區(qū)別

1、map 和 flatMap 方法的區(qū)別

  • map 方法會在返回時用 Optional 進行包裝而 flatMap 方法不會再進行額外的包裝。

2、orElse 和 orElseGet 方法的區(qū)別

  • orElse():如果有值則將其返回,否則返回指定的 other。
  • orElseGet():如果有值則將其返回,否則調(diào)用函數(shù) other 并將其返回調(diào)用結(jié)果。
  • orElse() 方法在 Optional 值為非空時,也會計算傳入的參數(shù),而 orElseGet() 方法只有在 Optional 值為空時才會執(zhí)行傳入的函數(shù)。

如果是傳值可以選用 orElse(),如果傳入的是方法選用orElseGet()??。

三、總結(jié)

在使用 Optional 時我覺得應(yīng)該盡量避免一些情況:

  • 永遠不要通過返回 Optional 的方法返回一個空值:它破壞 Optional 設(shè)計的初衷。
  • 并不是所有的返回類型都能從 Optional 的處理中獲益。容器類型,包括集合、映射、Stream、數(shù)組和 Optional,不應(yīng)該封裝在 Optional 中。與其返回一個空的 Optional<List<T>> ,不還如返回一個 空的 List<T> 。
  • 除了「次要基本類型(minor primitive types)」Boolean,Byte,Character,Short 和 Float 之外,永遠不應(yīng)該返回裝箱的基本類型 的 Optional。

總之,如果發(fā)現(xiàn)自己編寫的方法不能總是返回值,并且認為該方法的用戶在每次調(diào)用時考慮這種可能性很重要,那么或許應(yīng)該返回一個 Optional 的方法。但是,應(yīng)該意識到,返回 Optional 會帶來實際的性能后果;對于性能關(guān)鍵的方法,最好返回 null 或拋出異常。最后,除了作為返回值之外,不應(yīng)該在任何其他地方中使用 Optional。

使用 Optional 時要注意,我認為它并不能完全避免空指針。如果這個值是 null ,不做額外的判斷,直接使用還是會有空指針的問題。使用 Optional 的好處是它可以幫助我們簡化判空的操作,簡潔我們的代碼。用了 Optional 最后拿結(jié)果的時候還是要小心的,盲目 get 一樣會拋錯。

參考文獻

《Effective Java》jdk11的文檔

以上就是JDK8新出Optional類的方法探索與思考分析的詳細內(nèi)容,更多關(guān)于JDK8 Optional類的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java實現(xiàn)桌面右下角彈窗效果

    java實現(xiàn)桌面右下角彈窗效果

    這篇文章主要為大家詳細介紹了java實現(xiàn)桌面右下角彈窗效果,模仿類似于qq消息彈窗,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • springboot返回html和jsp的方法示例

    springboot返回html和jsp的方法示例

    這篇文章主要介紹了springboot返回html和jsp的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • mybatis-plus自帶QueryWrapper自定義sql實現(xiàn)復雜查詢實例詳解

    mybatis-plus自帶QueryWrapper自定義sql實現(xiàn)復雜查詢實例詳解

    MyBatis-Plus是一個MyBatis(opens new window)的增強工具,在 MyBatis的基礎(chǔ)上只做增強不做改變,MyBatis可以無損升級為MyBatis-Plus,這篇文章主要給大家介紹了關(guān)于mybatis-plus自帶QueryWrapper自定義sql實現(xiàn)復雜查詢的相關(guān)資料,需要的朋友可以參考下
    2022-10-10
  • java開發(fā)flyway的方法

    java開發(fā)flyway的方法

    這篇文章主要介紹了java開發(fā)flyway的方法,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • IDEA新建javaWeb以及Servlet簡單實現(xiàn)小結(jié)

    IDEA新建javaWeb以及Servlet簡單實現(xiàn)小結(jié)

    這篇文章主要介紹了IDEA新建javaWeb以及Servlet簡單實現(xiàn)小結(jié),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11
  • java鏈表的頭插法和尾插法詳解

    java鏈表的頭插法和尾插法詳解

    本文介紹了鏈表的基本概念,包括節(jié)點類Listnode和鏈表類Linklist,頭插法和尾插法是兩種常見的插入節(jié)點的方法,分別通過頭指針和游標來實現(xiàn),通過示例代碼和測試,展示了鏈表的創(chuàng)建和操作過程
    2024-12-12
  • 淺談Java中的橋接方法與泛型的逆變和協(xié)變

    淺談Java中的橋接方法與泛型的逆變和協(xié)變

    對應(yīng)于Java當中,協(xié)變對應(yīng)的就是<? extends XXX>,而逆變對應(yīng)的就是<? super XXX>,本文詳細的介紹了Java中的橋接方法與泛型的逆變和協(xié)變,感興趣的可以了解一下
    2022-04-04
  • Java中Date和Calendar常用方法

    Java中Date和Calendar常用方法

    這篇文章主要為大家詳細介紹了Java中Date和Calendar常用用法,感興趣的小伙伴們可以參考一下
    2016-09-09
  • Java在Excel中創(chuàng)建多級分組、折疊或展開分組的實現(xiàn)

    Java在Excel中創(chuàng)建多級分組、折疊或展開分組的實現(xiàn)

    這篇文章主要介紹了Java在Excel中創(chuàng)建多級分組、折疊或展開分組的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-05-05
  • 淺談解決Hibernate懶加載的4種方式

    淺談解決Hibernate懶加載的4種方式

    這篇文章主要介紹了淺談解決Hibernate懶加載的4種方式,具有一定借鑒價值,需要的朋友可以參考下。
    2017-12-12

最新評論