Java - Optional 類別:初學者指南

你好,未來的 Java 開發者!今天,我們將進入 Java 的 Optional 類別的精彩世界。如果你以前從未寫過一行代碼,也別擔心——我將成為你的友好指南,我們將一步步來。在這篇教程結束時,你將能像專業人士一樣處理空值!

Java - Optional Class

Optional 類別是什麼?

在我們深入探討之前,先來講個小故事。想象一下你正在等待一個包裹。有時它會到達,有時不會。在 Java 的世界裡,我們經常面臨與數據類似的情况——有時它在那裡,有時它不在。這就是 Optional 類別拯救我們的地方!

在 Java 8 中引入的 Optional 類別,就像一個特殊的容器,可能包含也可能不包含非空值。它是用來表示選擇性值,而不是空引用的一種方式。相信我,這個小類別將會為你避免代碼中的許多頭痛和潛在錯誤!

為什麼我們需要 Optional?

你可能在想,“為什麼我們不能只使用 null?” 呢?嗯,我的親愛的學生,null 可能會帶來很多麻煩。它可能導致可怕的 NullPointerException,這就像在黑暗中不小心踩到樂高積木一樣——痛苦而意外!

Optional 幫助我們更优雅地處理這些情況。它強迫我們思考可能不存在值的可能性並明確地處理它們。

創建一個 Optional

讓我們從創建我們的第一個 Optional 對象開始。有幾種方法可以做到這一點:

// 創建一個空的 Optional
Optional<String> empty = Optional.empty();

// 創建一個包含非空值的 Optional
String name = "Alice";
Optional<String> optionalName = Optional.of(name);

// 創建一個可能包含也可能不包含空值的 Optional
String nullableName = null;
Optional<String> optionalNullable = Optional.ofNullable(nullableName);

在這個例子中,我們創建了三個不同的 Optional 對象。第一個是空的,第二個包含一個確定的值,第三個可能包含也可能不包含一個值。

檢查值是否存在

現在我們有了我們的 Optional 對象,讓我們看看我們如何檢查它們是否真的包含一個值:

Optional<String> optionalName = Optional.of("Bob");

if (optionalName.isPresent()) {
System.out.println("Name is present: " + optionalName.get());
} else {
System.out.println("Name is not present");
}

在這裡,我們使用 isPresent() 方法來檢查 Optional 是否包含一個值,並使用 get() 方法來检索該值。但是要小心!在一個空的 Optional 上使用 get() 將會拋出異常。這就像試圖從空帽子中拉出一隻兔子——根本不會成功!

使用默認值

有時,如果我們的 Optional 是空的,我們希望使用默認值。Java 使這變得非常容易:

String name = Optional.ofNullable(nullableName).orElse("Unknown");
System.out.println("Name: " + name);

在這個例子中,如果 nullableName 是 null,我們的 name 變量將被設置為 "Unknown"。這就像有了一個後備計劃——永遠是一個好主意!

使用 map() 轉換值

Optional 類別還允許我們使用 map() 方法轉換值。讓我們看看它是如何工作的:

Optional<String> upperName = Optional.of("alice").map(String::toUpperCase);
System.out.println(upperName.orElse("No name found"));

這段代碼取的名稱 "alice",將其轉換為大寫,並將其包裝在一個新的 Optional 中。如果原始 Optional 是空的,則結果也將是空的 Optional。

鏈式 Optional 操作

Optional 最酷的事情之一是我們可以將操作鏈接在一起。這就像用樂高積木建造——每塊積木都連接在一起,創造出一些驚人的東西:

Optional<String> name = Optional.of("Alice")
.filter(s -> s.length() > 5)
.map(String::toUpperCase);

System.out.println(name.orElse("Name not long enough"));

在這個例子中,我們從 "Alice" 開始,檢查它是否長於 5 個字符(不是),所以結果是一個空的 Optional。如果名字夠長,它將被轉換為大寫。

使用 Optional 拋出異常

有時,當值不存在時,我們希望拋出異常。Optional 也使這變得容易:

String result = Optional.ofNullable(nullableValue)
.orElseThrow(() -> new IllegalArgumentException("Value cannot be null"));

如果 nullableValue 是 null,則這段代碼將拋出一個帶有我們自定義消息的 IllegalArgumentException。

Optional 類別方法

讓我們總結一些最有用的 Optional 方法:

方法 描述
empty() 返回一個空的 Optional 實例
of(T value) 返回一個包含指定非空值的 Optional
ofNullable(T value) 如果值非空,則返回描述該值的 Optional,否則返回一個空的 Optional
isPresent() 如果存在值,則返回 true,否則返回 false
ifPresent(Consumer<? super T> action) 如果存在值,則執行給定操作
get() 如果存在值,則返回值,否則拋出 NoSuchElementException
orElse(T other) 如果存在值,則返回值,否則返回另一個
orElseGet(Supplier<? extends T> supplier) 如果存在值,則返回值,否則調用供應商並返回結果
orElseThrow(Supplier<? extends X> exceptionSupplier) 如果存在值,則返回值,否則拋出異常供應商生成的異常
map(Function<? super T, ? extends U> mapper) 如果存在值,則返回一個 Optional,描述將給定映射函數應用於值的結果,否則返回一個空的 Optional
flatMap(Function<? super T, ? extends Optional<? extends U>> mapper) 與 map 相似,但映射函數返回 Optional
filter(Predicate<? super T> predicate) 如果存在值並且符合給定條件,則返回描述該值的 Optional,否則返回一個空的 Optional

結論

恭喜!你剛剛走出了 Java 的 Optional 類別的第一步。請記住,Optional 不僅是一個工具,它是一種思維方式。它鼓勵你考慮不存在值的可能性並优雅地處理它們。

在你繼續 Java 的旅程中,你會發現 Optional 在許多地方出現。擁抱它!它就像一個忠實的助手,始終在那裡幫助你處理那些棘手的空值情況。

繼續練習,繼續編碼,最重要的是,繼續享受!Java 是一個廣闊而精彩的世界,你剛剛觸及了皮毛。誰知道你會用新知識創造出什麼驚人的事情?

下次見,開心編碼!

Credits: Image by storyset