最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java?Optional優(yōu)雅處理空值與鏈?zhǔn)睫D(zhuǎn)換的實(shí)戰(zhàn)指南

 更新時(shí)間:2026年06月03日 08:28:57   作者:唐青楓  
Optional?是?Java?8?引入的一個(gè)容器類,這篇文章主要介紹了Java8中Optional類的使用場景和方法,包括創(chuàng)建Optional、處理null、鏈?zhǔn)秸{(diào)用以及與Stream的配合等,希望對大家有所幫助

簡介

OptionalJava 8 引入的一個(gè)容器類,包路徑是:

java.util.Optional

它用來表達(dá)一種很常見的情況:這個(gè)結(jié)果可能有值,也可能沒有值。

比如按 ID 查詢用戶:

User user = userRepository.findById(1L);

如果找到了,返回 User。

如果沒找到,傳統(tǒng)寫法通常返回 null。

Optional 的寫法是:

Optional<User> user = userRepository.findById(1L);

這段代碼的含義更明確:findById 可能查到用戶,也可能查不到用戶。

一句話概括:Optional 用來把“可能為空”這件事寫進(jìn)方法返回值里,讓空值處理變得更清楚。

為什么需要 Optional

先看一段普通判空代碼:

public String getUserCity(User user) {
    if (user != null) {
        Address address = user.getAddress();
        if (address != null) {
            String city = address.getCity();
            if (city != null) {
                return city;
            }
        }
    }

    return "未知城市";
}

代碼本身不復(fù)雜,但層級(jí)一多,判空會(huì)越來越長。

如果中間漏掉一次判空:

return user.getAddress().getCity();

只要 useraddressnull,就會(huì)出現(xiàn):

NullPointerException

使用 Optional 后,可以把“取值、轉(zhuǎn)換、兜底”連在一起:

public String getUserCity(User user) {
    return Optional.ofNullable(user)
            .map(User::getAddress)
            .map(Address::getCity)
            .orElse("未知城市");
}

這段代碼表達(dá)的是:

  • user 有值就取 address
  • address 有值就取 city
  • city 有值就返回 city
  • 中間任何一步為空,就返回“未知城市”

Optional 的基本結(jié)構(gòu)

Optional<T> 里的 T 表示實(shí)際包裝的數(shù)據(jù)類型。

Optional<String> name;
Optional<User> user;
Optional<Order> order;

Optional 只有兩種狀態(tài):

  • 有值:里面包裝了一個(gè)非 null 對象
  • 空:里面沒有值

創(chuàng)建一個(gè)有值的 Optional

Optional<String> name = Optional.of("Java");

創(chuàng)建一個(gè)空的 Optional

Optional<String> name = Optional.empty();

創(chuàng)建 Optional

常用創(chuàng)建方式有 3 個(gè):

  • Optional.of(value)
  • Optional.ofNullable(value)
  • Optional.empty()

Optional.of

Optional.of 用來包裝一個(gè)確定不為 null 的值。

Optional<String> name = Optional.of("Java");

System.out.println(name);

輸出:

Optional[Java]

如果傳入 null

Optional<String> name = Optional.of(null);

會(huì)直接拋出:

NullPointerException

所以 of 適合這種場景:值一定不為空,只是需要包裝成 Optional。

Optional.ofNullable

Optional.ofNullable 是最常見的創(chuàng)建方式。

它允許傳入 null。

String value = null;

Optional<String> name = Optional.ofNullable(value);

System.out.println(name);

輸出:

Optional.empty

如果傳入非空值:

String value = "Java";

Optional<String> name = Optional.ofNullable(value);

System.out.println(name);

輸出:

Optional[Java]

日常項(xiàng)目里,包裝一個(gè)來源不確定的對象時(shí),通常使用 ofNullable。

Optional.empty

Optional.empty 用來創(chuàng)建一個(gè)空的 Optional

Optional<User> user = Optional.empty();

它常用于方法返回空結(jié)果:

public Optional<User> findUserById(Long id) {
    if (id == null) {
        return Optional.empty();
    }

    User user = queryUser(id);
    return Optional.ofNullable(user);
}

判斷是否有值

Optional 提供了兩個(gè)常見判斷方法:

  • isPresent()
  • isEmpty()

isPresent() 表示是否有值:

Optional<String> name = Optional.of("Java");

System.out.println(name.isPresent());

輸出:

true

isEmpty() 表示是否為空,它是 Java 11 新增的方法:

Optional<String> name = Optional.empty();

System.out.println(name.isEmpty());

輸出:

true

判斷后再 get 的寫法可以用,但不算 Optional 最有價(jià)值的寫法:

Optional<String> name = Optional.of("Java");

if (name.isPresent()) {
    System.out.println(name.get());
}

更常見的寫法是直接使用 ifPresent、maporElse 等方法。

get 取值

get() 可以直接取出 Optional 里的值。

Optional<String> name = Optional.of("Java");

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

輸出:

Java

但空 Optional 調(diào)用 get() 會(huì)拋異常:

Optional<String> name = Optional.empty();

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

異常:

NoSuchElementException: No value present

所以實(shí)際項(xiàng)目里更常見的是先明確空值處理方式,而不是直接寫:

optional.get()

更合適的方式是:

optional.orElse(...)
optional.orElseGet(...)
optional.orElseThrow(...)
optional.ifPresent(...)

ifPresent:有值才執(zhí)行

ifPresent 適合處理“有值就做一件事,沒值就不處理”的場景。

Optional<String> name = Optional.ofNullable("Java");

name.ifPresent(value -> System.out.println("name = " + value));

輸出:

name = Java

如果是空值:

Optional<String> name = Optional.empty();

name.ifPresent(value -> System.out.println("name = " + value));

不會(huì)輸出任何內(nèi)容。

ifPresentOrElse

ifPresentOrElseJava 9 新增的方法。

它可以同時(shí)處理有值和無值兩種情況。

Optional<String> name = Optional.empty();

name.ifPresentOrElse(
        value -> System.out.println("name = " + value),
        () -> System.out.println("name 不存在")
);

輸出:

name 不存在

orElse:為空時(shí)返回默認(rèn)值

orElse 用來給空值設(shè)置默認(rèn)值。

String name = Optional.ofNullable(null)
        .orElse("默認(rèn)名稱");

System.out.println(name);

輸出:

默認(rèn)名稱

有值時(shí)返回原值:

String name = Optional.ofNullable("Java")
        .orElse("默認(rèn)名稱");

System.out.println(name);

輸出:

Java

orElseGet:為空時(shí)再生成默認(rèn)值

orElseGet 接收的是一個(gè) Supplier

只有 Optional 為空時(shí),才會(huì)執(zhí)行里面的邏輯。

String name = Optional.ofNullable(null)
        .orElseGet(() -> "默認(rèn)名稱");

System.out.println(name);

輸出:

默認(rèn)名稱

orElse 和 orElseGet 的區(qū)別

這兩個(gè)方法很像,但執(zhí)行時(shí)機(jī)不一樣。

準(zhǔn)備一個(gè)方法:

private static String createDefaultName() {
    System.out.println("生成默認(rèn)名稱");
    return "默認(rèn)名稱";
}

使用 orElse

String name = Optional.of("Java")
        .orElse(createDefaultName());

System.out.println(name);

輸出:

生成默認(rèn)名稱
Java

雖然 Optional 里已經(jīng)有 "Java",但 createDefaultName() 還是執(zhí)行了。

再看 orElseGet

String name = Optional.of("Java")
        .orElseGet(() -> createDefaultName());

System.out.println(name);

輸出:

Java

createDefaultName() 沒有執(zhí)行。

簡單理解:

orElse:默認(rèn)值先準(zhǔn)備好,不管最后用不用
orElseGet:真正為空時(shí),才去生成默認(rèn)值

如果默認(rèn)值只是一個(gè)普通字符串,用 orElse 很自然:

String name = optionalName.orElse("匿名用戶");

如果默認(rèn)值需要查詢數(shù)據(jù)庫、調(diào)用接口、創(chuàng)建復(fù)雜對象,用 orElseGet 更合適:

User user = optionalUser.orElseGet(() -> userRepository.createGuestUser());

orElseThrow:為空時(shí)拋異常

有些場景下,空值不是正常結(jié)果,而是業(yè)務(wù)異常。

比如訂單必須存在:

Order order = orderRepository.findById(orderId)
        .orElseThrow(() -> new IllegalArgumentException("訂單不存在"));

Java 10 開始,orElseThrow() 可以不傳參數(shù)。

String name = Optional.<String>empty()
        .orElseThrow();

空值時(shí)會(huì)拋出:

NoSuchElementException

業(yè)務(wù)代碼里通常更推薦帶上明確的異常類型和提示信息:

User user = userRepository.findById(userId)
        .orElseThrow(() -> new IllegalStateException("用戶不存在"));

map:轉(zhuǎn)換里面的值

map 用來把 Optional 里的值轉(zhuǎn)換成另一個(gè)值。

Optional<String> name = Optional.of("Java");

Optional<Integer> length = name.map(String::length);

System.out.println(length.orElse(0));

輸出:

4

如果原來的 Optional 是空的,map 不會(huì)執(zhí)行:

Optional<String> name = Optional.empty();

Optional<Integer> length = name.map(value -> {
    System.out.println("計(jì)算長度");
    return value.length();
});

System.out.println(length.orElse(0));

輸出:

0

不會(huì)輸出 計(jì)算長度。

map 處理對象屬性

map 很適合用來安全獲取對象屬性。

String city = Optional.ofNullable(user)
        .map(User::getAddress)
        .map(Address::getCity)
        .orElse("未知城市");

這段代碼里:

  • user 為空,直接返回默認(rèn)值
  • address 為空,直接返回默認(rèn)值
  • city 為空,直接返回默認(rèn)值
  • 三者都有值,返回真實(shí)城市

不用寫多層 if,也不用擔(dān)心中間某一步出現(xiàn)空指針。

flatMap:處理返回 Optional 的方法

如果轉(zhuǎn)換方法本身返回的就是 Optional,應(yīng)該使用 flatMap。

先看一個(gè)類:

class User {
    private final Address address;

    User(Address address) {
        this.address = address;
    }

    public Optional<Address> getAddress() {
        return Optional.ofNullable(address);
    }
}

此時(shí) getAddress() 返回的是:

Optional<Address>

如果使用 map

Optional<Optional<Address>> address = Optional.of(user)
        .map(User::getAddress);

結(jié)果會(huì)變成嵌套結(jié)構(gòu):

Optional<Optional<Address>>

使用 flatMap 可以把嵌套壓平:

Optional<Address> address = Optional.of(user)
        .flatMap(User::getAddress);

再配合城市字段:

String city = Optional.of(user)
        .flatMap(User::getAddress)
        .flatMap(Address::getCity)
        .orElse("未知城市");

簡單區(qū)分:

  • 方法返回普通值,用 map
  • 方法返回 Optional,用 flatMap

filter:按條件保留值

filter 用來給 Optional 里的值加條件。

條件滿足,值保留。

條件不滿足,變成空 Optional。

Optional<Integer> age = Optional.of(20);

Optional<Integer> adultAge = age.filter(value -> value >= 18);

System.out.println(adultAge.isPresent());

輸出:

true

如果條件不滿足:

Optional<Integer> age = Optional.of(16);

Optional<Integer> adultAge = age.filter(value -> value >= 18);

System.out.println(adultAge.isPresent());

輸出:

false

常見業(yè)務(wù)寫法:

Optional<User> activeUser = Optional.ofNullable(user)
        .filter(User::isActive);

表示:

user 不為空,并且是啟用狀態(tài),才繼續(xù)保留。

or:為空時(shí)切換到另一個(gè) Optional

orJava 9 新增的方法。

它適合處理多個(gè)來源的查找邏輯。

Optional<User> user = findByEmail(email)
        .or(() -> findByPhone(phone))
        .or(() -> findByUsername(username));

含義是:

  • 先按郵箱查
  • 查不到再按手機(jī)號(hào)查
  • 還查不到再按用戶名查

注意,or 返回的還是 Optional

User result = findByEmail(email)
        .or(() -> findByPhone(phone))
        .or(() -> findByUsername(username))
        .orElseThrow(() -> new IllegalArgumentException("用戶不存在"));

stream:把 Optional 轉(zhuǎn)成 Stream

streamJava 9 新增的方法。

它可以把一個(gè) Optional 轉(zhuǎn)成包含 0 個(gè)或 1 個(gè)元素的 Stream。

Optional<String> name = Optional.of("Java");

long count = name.stream().count();

System.out.println(count);

輸出:

1

Optional

Optional<String> name = Optional.empty();

long count = name.stream().count();

System.out.println(count);

輸出:

0

它常用于集合處理。

比如有一組用戶 ID,需要查詢用戶,但有些 ID 查不到:

List<User> users = userIds.stream()
        .map(userRepository::findById)
        .flatMap(Optional::stream)
        .collect(Collectors.toList());

這里的 findById 返回 Optional<User>。

flatMap(Optional::stream) 會(huì)自動(dòng)丟掉空結(jié)果,只留下查到的用戶。

實(shí)戰(zhàn) Demo:訂單查詢與金額展示

下面這組代碼可以直接復(fù)制運(yùn)行,演示 Optional 在業(yè)務(wù)代碼里的常見用法。

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

public class OptionalOrderDemo {

    public static void main(String[] args) {
        OrderService orderService = new OrderService();

        System.out.println(orderService.getBuyerName("A001"));
        System.out.println(orderService.getBuyerName("A002"));
        System.out.println(orderService.getBuyerName("A404"));

        System.out.println(orderService.getPaidAmountText("A001"));
        System.out.println(orderService.getPaidAmountText("A002"));
        System.out.println(orderService.getPaidAmountText("A003"));

        orderService.findOrder("A001")
                .filter(Order::isPaid)
                .ifPresent(order -> System.out.println("已支付訂單: " + order.getOrderNo()));

        try {
            Order order = orderService.findOrder("A404")
                    .orElseThrow(() -> new IllegalArgumentException("訂單不存在"));
        } catch (IllegalArgumentException e) {
            System.out.println("異常信息: " + e.getMessage());
        }
    }

    static class OrderService {
        private final List<Order> orders = Arrays.asList(
                new Order("A001", new Buyer("張三", new Address("上海")), new BigDecimal("99.00"), "PAID"),
                new Order("A002", new Buyer("李四", null), new BigDecimal("35.50"), "PAID"),
                new Order("A003", null, new BigDecimal("88.00"), "CANCELLED")
        );

        public Optional<Order> findOrder(String orderNo) {
            return orders.stream()
                    .filter(order -> order.getOrderNo().equals(orderNo))
                    .findFirst();
        }

        public String getBuyerName(String orderNo) {
            return findOrder(orderNo)
                    .map(Order::getBuyer)
                    .map(Buyer::getName)
                    .orElse("未知買家");
        }

        public String getPaidAmountText(String orderNo) {
            return findOrder(orderNo)
                    .filter(Order::isPaid)
                    .map(Order::getAmount)
                    .map(amount -> "支付金額: " + amount)
                    .orElse("未支付或訂單不存在");
        }

        public String getBuyerCity(String orderNo) {
            return findOrder(orderNo)
                    .map(Order::getBuyer)
                    .map(Buyer::getAddress)
                    .map(Address::getCity)
                    .orElse("未知城市");
        }
    }

    static class Order {
        private final String orderNo;
        private final Buyer buyer;
        private final BigDecimal amount;
        private final String status;

        Order(String orderNo, Buyer buyer, BigDecimal amount, String status) {
            this.orderNo = orderNo;
            this.buyer = buyer;
            this.amount = amount;
            this.status = status;
        }

        String getOrderNo() {
            return orderNo;
        }

        Buyer getBuyer() {
            return buyer;
        }

        BigDecimal getAmount() {
            return amount;
        }

        boolean isPaid() {
            return "PAID".equals(status);
        }
    }

    static class Buyer {
        private final String name;
        private final Address address;

        Buyer(String name, Address address) {
            this.name = name;
            this.address = address;
        }

        String getName() {
            return name;
        }

        Address getAddress() {
            return address;
        }
    }

    static class Address {
        private final String city;

        Address(String city) {
            this.city = city;
        }

        String getCity() {
            return city;
        }
    }
}

運(yùn)行結(jié)果:

張三
李四
未知買家
支付金額: 99.00
支付金額: 35.50
未支付或訂單不存在
已支付訂單: A001
異常信息: 訂單不存在

這個(gè) Demo 里包含了幾個(gè)典型場景:

  • findOrder:用 Optional<Order> 表達(dá)訂單可能不存在
  • getBuyerName:用 map 安全獲取買家姓名
  • getPaidAmountText:用 filter 判斷訂單狀態(tài)
  • orElse:為空或條件不滿足時(shí)給默認(rèn)文案
  • orElseThrow:訂單必須存在時(shí)拋出業(yè)務(wù)異常

實(shí)戰(zhàn) Demo:查詢不到時(shí)再走備用查詢

實(shí)際項(xiàng)目里,經(jīng)常會(huì)出現(xiàn)多個(gè)查詢?nèi)肟凇?/p>

比如先按郵箱查用戶,查不到再按手機(jī)號(hào)查。

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

public class OptionalFallbackDemo {

    public static void main(String[] args) {
        UserService userService = new UserService();

        User user = userService.findByEmail("none@example.com")
                .or(() -> userService.findByPhone("13800000000"))
                .orElseThrow(() -> new IllegalArgumentException("用戶不存在"));

        System.out.println(user.getName());
    }

    static class UserService {
        private final List<User> users = Arrays.asList(
                new User("張三", "zhangsan@example.com", "13800000000"),
                new User("李四", "lisi@example.com", "13900000000")
        );

        public Optional<User> findByEmail(String email) {
            return users.stream()
                    .filter(user -> user.getEmail().equals(email))
                    .findFirst();
        }

        public Optional<User> findByPhone(String phone) {
            return users.stream()
                    .filter(user -> user.getPhone().equals(phone))
                    .findFirst();
        }
    }

    static class User {
        private final String name;
        private final String email;
        private final String phone;

        User(String name, String email, String phone) {
            this.name = name;
            this.email = email;
            this.phone = phone;
        }

        String getName() {
            return name;
        }

        String getEmail() {
            return email;
        }

        String getPhone() {
            return phone;
        }
    }
}

輸出:

張三

這類寫法比手動(dòng)判斷更緊湊:

Optional<User> user = findByEmail(email);

if (user.isEmpty()) {
    user = findByPhone(phone);
}

Optional 和 Stream 的配合

Stream 里的很多方法本身就會(huì)返回 Optional

比如 findFirst

Optional<String> first = Arrays.asList("Java", "Kotlin", "Go")
        .stream()
        .filter(name -> name.startsWith("K"))
        .findFirst();

System.out.println(first.orElse("沒有匹配結(jié)果"));

輸出:

Kotlin

再比如求最大值:

Optional<Integer> max = Arrays.asList(10, 20, 30)
        .stream()
        .max(Integer::compareTo);

System.out.println(max.orElse(0));

輸出:

30

為什么這些方法返回 Optional?

因?yàn)榻Y(jié)果可能不存在。

Optional<String> first = List.<String>of()
        .stream()
        .findFirst();

空集合里沒有第一個(gè)元素,所以返回空 Optional。

OptionalInt、OptionalLong、OptionalDouble

除了 Optional<T>,Java 還提供了 3 個(gè)基本類型版本:

  • OptionalInt
  • OptionalLong
  • OptionalDouble

它們用來避免基本類型裝箱。

import java.util.OptionalInt;

public class OptionalIntDemo {
    public static void main(String[] args) {
        OptionalInt maxAge = OptionalInt.of(30);

        System.out.println(maxAge.orElse(0));
    }
}

輸出:

30

IntStream 的一些操作也會(huì)返回 OptionalInt

OptionalInt max = Arrays.asList(10, 20, 30)
        .stream()
        .mapToInt(Integer::intValue)
        .max();

System.out.println(max.orElse(0));

輸出:

30

常見使用建議

適合作為方法返回值

Optional 最適合放在方法返回值上。

public Optional<User> findById(Long id) {
    User user = queryUser(id);
    return Optional.ofNullable(user);
}

調(diào)用方看到返回值類型,就知道這個(gè)方法可能查不到數(shù)據(jù)。

User user = userRepository.findById(id)
        .orElseThrow(() -> new IllegalArgumentException("用戶不存在"));

不適合作為實(shí)體字段

實(shí)體字段通常不建議寫成 Optional。

public class User {
    private Optional<String> nickname;
}

更常見的寫法是保持字段為普通類型:

public class User {
    private String nickname;

    public Optional<String> getNickname() {
        return Optional.ofNullable(nickname);
    }
}

原因很簡單:字段表示數(shù)據(jù)本身,Optional 更適合表達(dá)方法返回結(jié)果是否存在。

對于數(shù)據(jù)庫實(shí)體、JSON 序列化、ORM 映射,這種寫法也更自然。

不適合作為方法參數(shù)

方法參數(shù)也通常不建議寫成 Optional

public void updateNickname(Long userId, Optional<String> nickname) {
}

調(diào)用這個(gè)方法時(shí),反而多了一層包裝:

updateNickname(1L, Optional.of("小張"));
updateNickname(1L, Optional.empty());

更常見的寫法是傳普通參數(shù):

public void updateNickname(Long userId, String nickname) {
}

如果參數(shù)有明確的業(yè)務(wù)含義,可以拆成更清楚的方法:

public void updateNickname(Long userId, String nickname) {
}

public void clearNickname(Long userId) {
}

不適合放進(jìn)集合

集合里通常不建議放 Optional。

List<Optional<User>> users;

更常見的是:

List<User> users;

如果沒有數(shù)據(jù),用空集合表示:

List<User> users = Collections.emptyList();

如果集合中某些元素可能不存在,一般在收集前處理掉空值:

List<User> users = userIds.stream()
        .map(userRepository::findById)
        .flatMap(Optional::stream)
        .collect(Collectors.toList());

get 的使用邊界

get() 只有在已經(jīng)確定有值時(shí)才安全。

if (optional.isPresent()) {
    User user = optional.get();
}

但大多數(shù)場景可以改成更直接的寫法。

有默認(rèn)值:

User user = optional.orElse(defaultUser);

空值時(shí)報(bào)錯(cuò):

User user = optional.orElseThrow(() -> new IllegalArgumentException("用戶不存在"));

有值時(shí)執(zhí)行邏輯:

optional.ifPresent(user -> sendMessage(user));

轉(zhuǎn)換字段:

String name = optional.map(User::getName).orElse("匿名用戶");

鏈?zhǔn)秸{(diào)用不宜過長

Optional 支持鏈?zhǔn)秸{(diào)用,但業(yè)務(wù)邏輯很復(fù)雜時(shí),拆成普通變量會(huì)更清楚。

比如這類代碼:

String result = Optional.ofNullable(order)
        .map(Order::buyer)
        .filter(Buyer::isVip)
        .map(Buyer::address)
        .map(Address::city)
        .filter(city -> city.startsWith("上"))
        .map(city -> city + " VIP")
        .orElse("普通訂單");

如果中間夾雜很多業(yè)務(wù)規(guī)則,拆開后通常更容易維護(hù):

Optional<Order> orderOptional = Optional.ofNullable(order);

Optional<Buyer> vipBuyer = orderOptional
        .map(Order::buyer)
        .filter(Buyer::isVip);

String result = vipBuyer
        .map(Buyer::address)
        .map(Address::city)
        .filter(city -> city.startsWith("上"))
        .map(city -> city + " VIP")
        .orElse("普通訂單");

鏈?zhǔn)秸{(diào)用適合表達(dá)清晰的數(shù)據(jù)流。

邏輯復(fù)雜時(shí),適當(dāng)拆開,變量名本身就是說明。

常用方法匯總

方法作用常見場景
Optional.of(value)創(chuàng)建有值的 Optional,值不能為 null明確值不為空
Optional.ofNullable(value)創(chuàng)建可能為空的 Optional包裝外部返回值
Optional.empty()創(chuàng)建空 Optional返回空結(jié)果
isPresent()判斷是否有值簡單分支判斷
isEmpty()判斷是否為空Java 11+
ifPresent(...)有值時(shí)執(zhí)行邏輯打印、通知、補(bǔ)充操作
ifPresentOrElse(...)有值和無值分別處理Java 9+
orElse(...)為空時(shí)返回默認(rèn)值默認(rèn)字符串、默認(rèn)數(shù)字
orElseGet(...)為空時(shí)執(zhí)行 Supplier 獲取默認(rèn)值默認(rèn)值創(chuàng)建成本較高
orElseThrow(...)為空時(shí)拋異常必須存在的數(shù)據(jù)
map(...)轉(zhuǎn)換內(nèi)部值取字段、格式化
flatMap(...)轉(zhuǎn)換返回 Optional 的值避免 Optional<Optional<T>>
filter(...)條件過濾狀態(tài)判斷、權(quán)限判斷
or(...)為空時(shí)切換到另一個(gè) OptionalJava 9+,備用查詢
stream()轉(zhuǎn)成 0 或 1 個(gè)元素的 StreamJava 9+,集合流水線

總結(jié)

Optional 的重點(diǎn)不是把所有 null 都消滅掉,而是把“結(jié)果可能不存在”這件事表達(dá)清楚。

最常見的使用流程是:

Optional.ofNullable(value)
        .map(...)
        .filter(...)
        .orElse(...);

或者:

repository.findById(id)
        .orElseThrow(() -> new IllegalArgumentException("數(shù)據(jù)不存在"));

實(shí)際項(xiàng)目里,Optional 最適合放在方法返回值上,用來表示查詢結(jié)果、匹配結(jié)果、計(jì)算結(jié)果可能為空。

只要控制好邊界,不把它塞進(jìn)實(shí)體字段、方法參數(shù)和集合元素里,代碼會(huì)更容易看出空值處理邏輯。

以上就是Java Optional優(yōu)雅處理空值與鏈?zhǔn)睫D(zhuǎn)換的實(shí)戰(zhàn)指南的詳細(xì)內(nèi)容,更多關(guān)于Java Optional處理空值的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • MyBatis查詢數(shù)據(jù),賦值給List集合時(shí),數(shù)據(jù)缺少的問題及解決

    MyBatis查詢數(shù)據(jù),賦值給List集合時(shí),數(shù)據(jù)缺少的問題及解決

    這篇文章主要介紹了MyBatis查詢數(shù)據(jù),賦值給List集合時(shí),數(shù)據(jù)缺少的問題及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • java 操作gis geometry類型數(shù)據(jù)方式

    java 操作gis geometry類型數(shù)據(jù)方式

    這篇文章主要介紹了java 操作gis geometry類型數(shù)據(jù)方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • IDEA “Cannot resolve symbol”爆紅問題解決

    IDEA “Cannot resolve symbol”爆紅問題解決

    最近發(fā)現(xiàn)個(gè)問題,IDEA 無法識(shí)別同一個(gè) package 里的其他類,將其顯示為紅色,本文就來介紹一下IDEA “Cannot resolve symbol”爆紅問題解決,感興趣的可以了解一下
    2023-10-10
  • Java和C的隨機(jī)數(shù)(Random)詳解

    Java和C的隨機(jī)數(shù)(Random)詳解

    本篇文章主要介紹了Java和C隨機(jī)數(shù)(Random),現(xiàn)在分享給大家,也給大家做個(gè)參考,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-09-09
  • Java設(shè)計(jì)模式之單例模式簡介

    Java設(shè)計(jì)模式之單例模式簡介

    這篇文章主要介紹了Java設(shè)計(jì)模式之單例模式簡介,文中有非常詳細(xì)的代碼示例,對正在學(xué)習(xí)Java的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • RestTemplate集成Ribbbon的示例代碼

    RestTemplate集成Ribbbon的示例代碼

    這篇文章主要介紹了RestTemplate集成Ribbbon的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-08-08
  • JAVA實(shí)現(xiàn)感知器算法

    JAVA實(shí)現(xiàn)感知器算法

    這篇文章主要為大家詳細(xì)介紹了JAVA實(shí)現(xiàn)感知器算法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Java 和 JavaScript 真正通用的Base64編碼詳解

    Java 和 JavaScript 真正通用的Base64編碼詳解

    這篇文章主要介紹了Java 和 JavaScript 真正通用的Base64編碼詳解的相關(guān)資料,附有Java和Javascript 的Base64編碼,需要的朋友可以參考下
    2016-11-11
  • SpringBoot整合RocketMQ批量發(fā)送消息的實(shí)現(xiàn)代碼

    SpringBoot整合RocketMQ批量發(fā)送消息的實(shí)現(xiàn)代碼

    這篇文章主要介紹了SpringBoot整合RocketMQ批量發(fā)送消息的實(shí)現(xiàn),文中通過代碼示例講解的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-04-04
  • Java中的移位運(yùn)算符使用及原理詳解

    Java中的移位運(yùn)算符使用及原理詳解

    在 Java 中,移位運(yùn)算符用于對二進(jìn)制數(shù)進(jìn)行位移操作,它們可以將一個(gè)數(shù)的所有位向左或向右移動(dòng)指定的位數(shù),本文小編將給大家詳細(xì)的介紹一下Java移位運(yùn)算符,需要的朋友可以參考下
    2023-09-09

最新評論

柯坪县| 高台县| 河池市| 河曲县| 崇仁县| 中方县| 铜川市| 连州市| 昌平区| 蒲江县| 千阳县| 奎屯市| 黔东| 攀枝花市| 阿拉善左旗| 满城县| 福建省| 金湖县| 鄂托克前旗| 梓潼县| 蓬莱市| 毕节市| 扶沟县| 济南市| 沾益县| 泸西县| 巴南区| 荥阳市| 平和县| 双辽市| 格尔木市| 伊金霍洛旗| 密山市| 安阳市| 平定县| 鄂托克前旗| 乌鲁木齐县| 彰化市| 南川市| 游戏| 白河县|