哪些Java案例展示了Optional类?

wen java案例 2

本文目录导读:

哪些Java案例展示了Optional类?

  1. 基础创建与取值
  2. 链式操作与转换
  3. 避免空指针异常 —— 传统 vs Optional
  4. 结合流(Stream)使用
  5. 在方法返回值中使用(推荐模式)
  6. 使用 ifPresentOrElse (Java 9+)

在Java中,Optional 类的主要目的是为了避免繁琐的 null 检查,并更优雅地处理可能为 null 的值,以下是一些典型的 Java 案例,展示了 Optional 类的常见用法。


基础创建与取值

场景:避免直接返回 null,而是返回一个 Optional

import java.util.Optional;
public class OptionalBasicExample {
    public static void main(String[] args) {
        // 1. 创建 Optional
        Optional<String> nonEmpty = Optional.of("Hello");
        Optional<String> empty = Optional.empty();
        // 2. 取值:如果为空,则用默认值
        String value1 = nonEmpty.orElse("Default");
        String value2 = empty.orElse("Default");
        System.out.println(value1); // Hello
        System.out.println(value2); // Default
        // 3. 取值:使用供应商函数提供默认值(懒加载)
        String value3 = empty.orElseGet(() -> "Generated Default");
        System.out.println(value3); // Generated Default
        // 4. 取值:如果为空则抛出异常
        // String value4 = empty.orElseThrow(() -> new RuntimeException("Value is absent"));
        // 5. 安全检查:如果存在则执行
        nonEmpty.ifPresent(val -> System.out.println("Found: " + val)); // Found: Hello
        empty.ifPresent(val -> System.out.println("不会执行")); // 不会输出
    }
}

链式操作与转换

场景:将 Optional 进行映射、过滤和扁平化处理。

import java.util.Optional;
public class OptionalChainingExample {
    public static void main(String[] args) {
        Optional<String> original = Optional.of("  Hello World  ");
        // 链式调用:过滤、映射、取值
        String result = original
                .map(String::trim)          // 去除首尾空格
                .filter(s -> s.length() > 5) // 长度大于5才保留
                .map(String::toUpperCase)    // 转大写
                .orElse("TOO_SHORT");
        System.out.println(result); // HELLO WORLD
        // 过滤条件不满足的情况
        Optional<String> shortStr = Optional.of("Hi");
        String result2 = shortStr
                .map(String::trim)
                .filter(s -> s.length() > 5) // 长度不大于5,过滤掉
                .map(String::toUpperCase)
                .orElse("TOO_SHORT");
        System.out.println(result2); // TOO_SHORT
    }
}

避免空指针异常 —— 传统 vs Optional

场景:从深层嵌套的对象中获取属性(如 user.getAddress().getCity()),传统方式需要大量判空,而 Optional 可以优雅地处理。

import java.util.Optional;
class Address {
    private String city;
    public Address(String city) { this.city = city; }
    public String getCity() { return city; }
}
class User {
    private Address address;
    public User(Address address) { this.address = address; }
    public Optional<Address> getAddress() { return Optional.ofNullable(address); }
}
public class OptionalNullSafeExample {
    public static void main(String[] args) {
        // 用户有地址
        User userWithAddress = new User(new Address("Beijing"));
        // 用户没有地址
        User userWithoutAddress = new User(null);
        // 1. 传统方式(易出错)
        String cityTraditional = "Unknown";
        if (userWithAddress.getAddress().isPresent()) {
            cityTraditional = userWithAddress.getAddress().get().getCity();
        }
        System.out.println(cityTraditional); // Beijing
        // 2. 使用 Optional 链式调用(推荐)
        String city = Optional.ofNullable(userWithAddress)
                .flatMap(User::getAddress)
                .map(Address::getCity)
                .orElse("Unknown");
        System.out.println(city); // Beijing
        // 3. 对于没有地址的用户
        String city2 = Optional.ofNullable(userWithoutAddress)
                .flatMap(User::getAddress)
                .map(Address::getCity)
                .orElse("Unknown");
        System.out.println(city2); // Unknown (不会报空指针)
    }
}

结合流(Stream)使用

场景:从集合中查找元素,结果可能为空,用 Optional 处理查找结果。

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
public class OptionalWithStreamExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
        // 查找名字长度大于5的第一个
        Optional<String> firstLongName = names.stream()
                .filter(name -> name.length() > 5)
                .findFirst();
        // 处理结果
        firstLongName.ifPresent(name -> System.out.println("Long name: " + name)); // Charlie
        // 查找名字长度大于10的(不存在)
        Optional<String> none = names.stream()
                .filter(name -> name.length() > 10)
                .findFirst();
        // 如果不存在,使用 orElse 提供默认值
        String result = none.orElse("No name longer than 10 chars");
        System.out.println(result); // No name longer than 10 chars
    }
}

在方法返回值中使用(推荐模式)

场景:在自定义方法中,用 Optional 表示可能没有返回值,让调用方明确知道需要处理空的情况。

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
public class OptionalReturnExample {
    private static Map<Integer, String> database = new HashMap<>();
    static {
        database.put(1, "Apple");
        database.put(2, "Banana");
    }
    // 查询用户,可能找不到
    public static Optional<String> findUserById(int id) {
        return Optional.ofNullable(database.get(id));
    }
    public static void main(String[] args) {
        // 调用方必须处理 Optional
        Optional<String> user1 = findUserById(1);
        user1.ifPresent(System.out::println); // Apple
        Optional<String> user3 = findUserById(3);
        String name = user3.orElse("Guest");
        System.out.println(name); // Guest
        // 建议调用方保持 Optional 链式风格:
        String uppercaseName = findUserById(1)
                .map(String::toUpperCase)
                .orElseThrow(() -> new RuntimeException("User not found"));
        System.out.println(uppercaseName); // APPLE
    }
}

使用 ifPresentOrElse (Java 9+)

场景:当值存在时执行一个操作,不存在时执行另一个操作。

import java.util.Optional;
public class IfPresentOrElseExample {
    public static void main(String[] args) {
        Optional<String> val = Optional.of("Hello");
        // Java 9+ 支持
        val.ifPresentOrElse(
                s -> System.out.println("Value: " + s),
                () -> System.out.println("No value")
        ); // 输出: Value: Hello
        Optional<String> empty = Optional.empty();
        empty.ifPresentOrElse(
                s -> System.out.println("Value: " + s),
                () -> System.out.println("No value")
        ); // 输出: No value
    }
}
场景 推荐方法
避免 null 返回值 返回 Optional<T> 代替 T
安全获取嵌套属性 flatMap + map + orElse
提供默认值 orElse(value) / orElseGet(Supplier)
存在时执行操作 ifPresent(Consumer)
不存在时抛出异常 orElseThrow(Supplier)
与流结合使用 findFirst() / findAny() 返回 Optional

⚠️ 注意:不要对 Optional 使用 .get() 而不先检查 isPresent(),这仍然可能抛出 NoSuchElementException,建议始终使用 orElseorElseGet 等安全方法。

抱歉,评论功能暂时关闭!