本文目录导读:

在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,建议始终使用 orElse、orElseGet 等安全方法。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播