Java的Stream流和Option类

你好呀,欢迎来到 Dong雨 的技术小栈 🌱

在这里,我们一同探索代码的奥秘,感受技术的魅力 ✨。

👉 我的小世界Dong雨

📌 分享我的学习旅程
🛠️ 提供贴心的实用工具
💡 记录每一个灵感火花

🌟✨ Hello,探索技术的你,这里是本篇的地图指南! ✨🌟 

目录

🌟✨ Hello,探索技术的你,这里是本篇的地图指南! ✨🌟 

1. Stream 流

背景

1.1 创建 Stream

1.1.1 使用集合创建 Stream

1.1.2 使用 Arrays 创建 Stream

1.1.3 使用 Stream.of()

1.1.4 使用生成器

1.2 中间操作

1.2.1 filter()

1.2.2 map()

1.2.3 flatMap()

1.2.4 distinct()

1.2.5 sorted()

1.2.6 anyMatch(), allMatch(), noneMatch()

1.2.7 peek()

1.3 终止操作

1.3.1 collect()

1.3.2 forEach()

1.3.3 reduce()

1.3.4 count()

1.3.5 min() 和 max()

1.3.6 findFirst() 和 findAny()

总结

2. Optional 类

背景

2.1.1 Optional.of()

2.1.2 Optional.ofNullable()

2.1.3 Optional.empty()

2.2 常用方法

2.2.1 isPresent()

2.2.2 ifPresent()

2.2.3 get()

2.2.4 orElse()

2.2.5 orElseGet()

2.2.6 orElseThrow()

2.2.7 map()

2.2.8 flatMap()

2.2.9 filter()

2.2.10 ifPresentOrElse()

2.3 使用场景

2.3.1 使用 Optional 返回可能为 null 的值

2.3.2 使用 Optional 简化链式调用

总结

3.Stream 和 Optional关系

1. Stream 和 Optional 的基本区别

2. 如何结合使用 Stream 和 Optional

2.1. Stream 操作返回 Optional

2.2. Optional 的方法可以与 Stream 配合使用

3. Stream 与 Optional 的常见组合方式

3.1. findFirst() 与 map()

3.2. filter() 和 flatMap()

3.3. reduce() 和 Optional

4. 小结

🎉🌈 陪伴至此,感谢有你 🌈🎉


1. Stream 流

背景

Stream是Java 8引入的一个用于处理集合(或其他数据源)中的元素的API。它提供了一种声明式的方式来处理数据,并可以链式调用。Stream支持惰性求值,也支持并行流处理。

1.1 创建 Stream

创建一个Stream可以通过多种方式,不同的数据源(如集合、数组、生成器等)提供了不同的创建方法。

1.1.1 使用集合创建 Stream
  • 方法stream() 方法可以用于集合类,如 ListSet 等,返回一个顺序流。
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> stream = list.stream();
stream.forEach(System.out::println);  // 输出 1, 2, 3, 4, 5
1.1.2 使用 Arrays 创建 Stream
  • 方法Arrays.stream() 可以从数组创建 Stream。
int[] numbers = {1, 2, 3, 4, 5};
IntStream stream = Arrays.stream(numbers);
stream.forEach(System.out::println);  // 输出 1, 2, 3, 4, 5
1.1.3 使用 Stream.of()
  • 方法Stream.of() 创建包含指定元素的Stream。
Stream<String> stream = Stream.of("Apple", "Banana", "Cherry");
stream.forEach(System.out::println);  // 输出 Apple, Banana, Cherry
1.1.4 使用生成器
  • 方法Stream.generate()Stream.iterate() 用于生成无限流。
Stream<Double> randomNumbers = Stream.generate(Math::random);
randomNumbers.limit(5).forEach(System.out::println);  // 输出5个随机数

Stream<Integer> evenNumbers = Stream.iterate(0, n -> n + 2);
evenNumbers.limit(5).forEach(System.out::println);  // 输出 0, 2, 4, 6, 8

1.2 中间操作

中间操作是惰性求值的,它们返回一个新的Stream对象,允许链式调用。常见的中间操作包括 filter(), map(), flatMap(), distinct(), sorted() 等。

1.2.1 filter()
  • 作用:过滤出符合条件的元素。
  • 签名Stream<T> filter(Predicate<? super T> predicate)
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> evenNumbers = numbers.stream()
                                   .filter(n -> n % 2 == 0)
                                   .collect(Collectors.toList());
System.out.println(evenNumbers);  // 输出 [2, 4, 6, 8, 10]
1.2.2 map()
  • 作用:对流中的每个元素应用给定的函数,生成一个新的流。
  • 签名<R> Stream<R> map(Function<? super T, ? extends R> mapper)
List<String> words = Arrays.asList("hello", "world", "java");
List<String> upperCaseWords = words.stream()
                                   .map(String::toUpperCase)
                                   .collect(Collectors.toList());
System.out.println(upperCaseWords);  // 输出 [HELLO, WORLD, JAVA]
1.2.3 flatMap()
  • 作用:将流中的元素转换成另一个流,然后将多个流合并为一个流。通常用于处理包含集合或数组的流。
  • 签名<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper)
List<List<String>> listOfLists = Arrays.asList(
    Arrays.asList("A", "B", "C"),
    Arrays.asList("D", "E", "F")
);
List<String> flatList = listOfLists.stream()
                                   .flatMap(List::stream)
                                   .collect(Collectors.toList());
System.out.println(flatList);  // 输出 [A, B, C, D, E, F]
1.2.4 distinct()
  • 作用:去重,返回一个只包含不同元素的流。
  • 签名Stream<T> distinct()
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 4, 4, 5);
List<Integer> distinctNumbers = numbers.stream()
                                       .distinct()
                                       .collect(Collectors.toList());
System.out.println(distinctNumbers);  // 输出 [1, 2, 3, 4, 5]
1.2.5 sorted()
  • 作用:对流中的元素进行排序。
  • 签名Stream<T> sorted()
List<Integer> numbers = Arrays.asList(5, 2, 8, 1, 3);
List<Integer> sortedNumbers = numbers.stream()
                                     .sorted()
                                     .collect(Collectors.toList());
System.out.println(sortedNumbers);  // 输出 [1, 2, 3, 5, 8]

 比较器

1. comparing  
根据属性创建比较器。  
ListString sortedByLength = Arrays.asList("apple", "banana", "kiwi").stream().sorted(Comparator.comparing(String::length)).collect(Collectors.toList());



2. naturalOrder  
自然顺序比较器。  
ListInteger sortedNatural = Arrays.asList(3, 1, 4).stream().sorted(Comparator.naturalOrder()).collect(Collectors.toList());



3. reverseOrder  
逆序比较器。  
ListInteger sortedReverse = Arrays.asList(3, 1, 4).stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());



4. thenComparing  
添加次要比较规则。  
ListString sortedByLengthThenAlphabet = Arrays.asList("apple", "kiwi", "banana").stream().sorted(Comparator.comparing(String::length).thenComparing(Comparator.naturalOrder())).collect(Collectors.toList());



5. reversed  
逆序当前比较器。  
ListString sortedReverseByLength = Arrays.asList("apple", "kiwi", "banana").stream().sorted(Comparator.comparing(String::length).reversed()).collect(Collectors.toList());
// 使用 Lambda 表达式排序 (o1, o2) -> o1 - o2
List<Integer> sortedNumbers = numbers.stream()
    .sorted((o1, o2) -> o1 - o2)
    .collect(Collectors.toList());
表达式排序顺序逻辑
(o1, o2) -> o1 - o2升序如果 o1 < o2,返回负数,o1 排在前面;如果 o1 > o2,返回正数,o1 排在后面。
(o1, o2) -> o2 - o1降序如果 o2 < o1,返回负数,o1 排在前面;如果 o2 > o1,返回正数,o1 排在后面。
1.2.6 anyMatch(), allMatch(), noneMatch()
  • 作用:这些方法用于匹配流中的元素:

    • anyMatch() 检查流中是否至少有一个元素满足条件。
    • allMatch() 检查流中的所有元素是否都满足条件。
    • noneMatch() 检查流中是否没有元素满足条件。
  • 签名

    • boolean anyMatch(Predicate<? super T> predicate)
    • boolean allMatch(Predicate<? super T> predicate)
    • boolean noneMatch(Predicate<? super T> predicate)
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
boolean anyGreaterThan3 = numbers.stream().anyMatch(n -> n > 3);  // true
boolean allGreaterThan0 = numbers.stream().allMatch(n -> n > 0);  // true
boolean noneNegative = numbers.stream().noneMatch(n -> n < 0);    // true
System.out.println(anyGreaterThan3);  // 输出 true
System.out.println(allGreaterThan0);  // 输出 true
System.out.println(noneNegative);     // 输出 true
1.2.7 peek()
  • 作用peek() 用于在中间操作中查看流中的每个元素。通常用于调试。
  • 签名Stream<T> peek(Consumer<? super T> action)
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> result = numbers.stream()
                              .peek(n -> System.out.println("Before filter: " + n))
                              .filter(n -> n % 2 == 0)
                              .collect(Collectors.toList());

1.3 终止操作

终止操作会触发流的处理,并生成一个最终的结果或副作用。常见的终止操作包括 collect(), forEach(), reduce(), count(), min() 等。

1.3.1 collect()
  • 作用:将流转换为集合或其他类型的结果。
  • 签名<R, A> R collect(Collector<? super T, A, R> collector)
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> evenNumbers = numbers.stream()
                                   .filter(n -> n % 2 == 0)
                                   .collect(Collectors.toList());
System.out.println(evenNumbers);  // 输出 [2, 4]
1.3.2 forEach()
  • 作用:对流中的每个元素执行给定的操作。
  • 签名void forEach(Consumer<? super T> action)
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.stream()
       .forEach(n -> System.out.println(n));  // 输出 1, 2, 3, 4, 5
1.3.3 reduce()
  • 作用:将流中的元素结合成一个单一的结果,常用于求和、求积等操作。
  • 签名T reduce(T identity, BinaryOperator<T> accumulator)
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
                 .reduce(0, (a, b) -> a + b);
System.out.println(sum);  // 输出 15
1.3.4 count()
  • 作用:计算流中的元素个数。
  • 签名long count()
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
long count = numbers.stream()
                    .filter(n -> n % 2 == 0)
                    .count();
System.out.println(count);  // 输出 2
1.3.5 min() 和 max()
  • 作用:找到流中的最小值或最大值。
  • 签名Optional<T> min(Comparator<? super T> comparator)
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> min = numbers.stream()
                               .min(Integer::compare);
System.out.println(min.get());  // 输出 1
1.3.6 findFirst() 和 findAny()
  • 作用:这两个方法用于获取流中的元素。
    • findFirst() 返回第一个元素。
    • findAny() 返回任意元素(并行流时表现不同)。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> first = numbers.stream().findFirst();
Optional<Integer> any = numbers.stream().findAny();
System.out.println(first.get());  // 输出 1
System.out.println(any.get());    // 输出 任意一个数

总结
  • Stream 提供了更简洁、声明式的方式处理数据流。
  • 中间操作如 filter(), map(), flatMap() 等支持链式操作,实现强大的数据处理能力。
  • 终止操作则触发最终的处理过程,如 collect(), forEach(), reduce() 等。

2. Optional 类

背景

Optional 是 Java 8 引入的一个容器类,用于解决传统 null 引用带来的 NullPointerException 问题。它表示一个可能为 null 的值,而不是直接使用 null,通过提供多种方法使得 Optional 的值可以更安全地处理。

Optional 主要用于以下几种场景:

  • 避免 null:避免直接返回或传递 null,提高代码的可读性和安全性。
  • 链式操作:允许对可能为 null 的值进行安全的链式调用,而不必担心 NullPointerException

2.1 创建 Optional

2.1.1 Optional.of()
  • 作用:创建一个非空的 Optional,如果值为 null,则抛出 NullPointerException
  • 签名static <T> Optional<T> of(T value)
Optional<String> optional = Optional.of("Hello");
System.out.println(optional.get());  // 输出 Hello
  • 注意:传入 null 会抛出异常。
Optional<String> optional = Optional.of(null);  // 会抛出 NullPointerException
2.1.2 Optional.ofNullable()
  • 作用:创建一个 Optional,如果值为 null,则返回一个空的 Optional
  • 签名static <T> Optional<T> ofNullable(T value)
Optional<String> optional = Optional.ofNullable("Hello");
System.out.println(optional.get());  // 输出 Hello

Optional<String> emptyOptional = Optional.ofNullable(null);
System.out.println(emptyOptional.isPresent());  // 输出 false
2.1.3 Optional.empty()
  • 作用:创建一个空的 Optional 对象。
  • 签名static <T> Optional<T> empty()
Optional<String> emptyOptional = Optional.empty();
System.out.println(emptyOptional.isPresent());  // 输出 false

2.2 常用方法

2.2.1 isPresent()
  • 作用:检查 Optional 是否包含一个非空的值。
  • 签名boolean isPresent()
Optional<String> optional = Optional.of("Hello");
System.out.println(optional.isPresent());  // 输出 true

Optional<String> emptyOptional = Optional.empty();
System.out.println(emptyOptional.isPresent());  // 输出 false
2.2.2 ifPresent()
  • 作用:如果 Optional 中有值,则执行给定的操作;如果没有值,则什么也不做。
  • 签名void ifPresent(Consumer<? super T> action)
Optional<String> optional = Optional.of("Hello");
optional.ifPresent(System.out::println);  // 输出 Hello

Optional<String> emptyOptional = Optional.empty();
emptyOptional.ifPresent(System.out::println);  // 不输出任何内容
2.2.3 get()
  • 作用:获取 Optional 中的值,如果值不存在,会抛出 NoSuchElementException
  • 签名T get()
Optional<String> optional = Optional.of("Hello");
System.out.println(optional.get());  // 输出 Hello

Optional<String> emptyOptional = Optional.empty();
// emptyOptional.get();  // 会抛出 NoSuchElementException
2.2.4 orElse()
  • 作用:如果 Optional 中有值,返回该值;如果没有值,返回提供的默认值。
  • 签名T orElse(T other)
Optional<String> optional = Optional.of("Hello");
System.out.println(optional.orElse("Default Value"));  // 输出 Hello

Optional<String> emptyOptional = Optional.empty();
System.out.println(emptyOptional.orElse("Default Value"));  // 输出 Default Value
2.2.5 orElseGet()
  • 作用:与 orElse() 类似,但 orElseGet() 使用 Supplier 提供默认值,这样可以延迟计算。
  • 签名T orElseGet(Supplier<? extends T> supplier)
Optional<String> optional = Optional.of("Hello");
System.out.println(optional.orElseGet(() -> "Default Value"));  // 输出 Hello

Optional<String> emptyOptional = Optional.empty();
System.out.println(emptyOptional.orElseGet(() -> "Default Value"));  // 输出 Default Value
2.2.6 orElseThrow()
  • 作用:如果 Optional 中有值,返回该值;如果没有值,抛出指定的异常。
  • 签名T orElseThrow(Supplier<? extends X> exceptionSupplier)
Optional<String> optional = Optional.of("Hello");
System.out.println(optional.orElseThrow(() -> new IllegalArgumentException("Value is missing")));  // 输出 Hello

Optional<String> emptyOptional = Optional.empty();
// emptyOptional.orElseThrow(() -> new IllegalArgumentException("Value is missing"));  // 会抛出 IllegalArgumentException
2.2.7 map()
  • 作用:如果 Optional 中有值,应用给定的映射函数返回一个新的 Optional,如果没有值,则返回一个空的 Optional
  • 签名<U> Optional<U> map(Function<? super T, ? extends U> mapper)
Optional<String> optional = Optional.of("Hello");
Optional<String> upperCaseOptional = optional.map(String::toUpperCase);
System.out.println(upperCaseOptional.get());  // 输出 HELLO

Optional<String> emptyOptional = Optional.empty();
System.out.println(emptyOptional.map(String::toUpperCase).isPresent());  // 输出 false
2.2.8 flatMap()
  • 作用:类似于 map(),但 flatMap() 返回的是一个 Optional。通常用于处理返回值本身可能为 Optional 的情况。
  • 签名<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper)
Optional<String> optional = Optional.of("Hello");
Optional<String> result = optional.flatMap(value -> Optional.of(value.toUpperCase()));
System.out.println(result.get());  // 输出 HELLO

Optional<String> emptyOptional = Optional.empty();
System.out.println(emptyOptional.flatMap(value -> Optional.of(value.toUpperCase())).isPresent());  // 输出 false
2.2.9 filter()
  • 作用:如果 Optional 中有值并且满足给定的条件,则返回一个包含该值的 Optional,否则返回一个空的 Optional
  • 签名Optional<T> filter(Predicate<? super T> predicate)
Optional<Integer> optional = Optional.of(5);
Optional<Integer> result = optional.filter(n -> n > 3);
System.out.println(result.get());  // 输出 5

Optional<Integer> result2 = optional.filter(n -> n < 3);
System.out.println(result2.isPresent());  // 输出 false
2.2.10 ifPresentOrElse()
  • 作用:如果 Optional 中有值,执行给定的操作,否则执行提供的另一个操作。
  • 签名void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction)
Optional<String> optional = Optional.of("Hello");
optional.ifPresentOrElse(
    value -> System.out.println("Value: " + value),  // 输出 Value: Hello
    () -> System.out.println("Value is absent")
);

Optional<String> emptyOptional = Optional.empty();
emptyOptional.ifPresentOrElse(
    value -> System.out.println("Value: " + value),
    () -> System.out.println("Value is absent")  // 输出 Value is absent
);

2.3 使用场景

2.3.1 使用 Optional 返回可能为 null 的值

在方法中返回 Optional 而非直接返回 null,避免客户端代码中直接进行 null 值检查。

public Optional<String> findUserById(int userId) {
    User user = userRepository.findById(userId);
    return Optional.ofNullable(user != null ? user.getName() : null);
}

Optional<String> name = findUserById(1);
name.ifPresent(System.out::println);  // 如果值存在,打印用户名
2.3.2 使用 Optional 简化链式调用

Optional 可以避免 null 检查,并通过 map()flatMap()filter() 等方法方便地进行链式调用。

public Optional<Address> getUserAddress(User user) {
    return Optional.ofNullable(user)
                   .map(User::getAddress);
}

Optional<Address> address = getUserAddress(user);
address.ifPresent(addr -> System.out.println("Address: " + addr.getStreet()));

总结

  • Optional 提供了一种优雅的方式来处理可能为 null 的值,避免了 NullPointerException
  • 常用方法如 map()filter()ifPresent()orElse()orElseThrow() 等,使得对 Optional 的操作更加简洁且安全。
  • 使用 Optional 可以有效提高代码的可读性和可维护性,尤其是在返回可能为 null 的值时。

通过理解和使用 Optional,可以显著降低出现空指针异常的风险,优化代码的健壮性。

是的,StreamOptional 是两个不同的类,但它们在 Java 8 及之后的版本中被设计成可以很方便地结合使用。让我们更详细地探讨一下这两个类如何协同工作,以及它们如何互相配合以简化代码、提高可读性和健壮性。

3.StreamOptional关系

1. StreamOptional 的基本区别

  • Stream 是一个用于处理集合数据的接口。它代表了一系列的元素,支持函数式操作(如过滤、映射、排序等)。Stream 操作通常返回一个新的流对象,而不是修改原始数据源。

    示例:

    Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
    stream.filter(x -> x > 2).forEach(System.out::println);  // 输出: 3, 4, 5
    
  • Optional 是一个容器对象,表示值的存在与否。它用于避免 NullPointerException,并通过 Optional 中的函数方法,提供更优雅的 null 值处理方式。Optional 可以包含一个值,也可以是空的(即 Optional.empty())。

    示例:

    Optional<String> name = Optional.ofNullable("John");
    name.ifPresent(System.out::println);  // 输出: John
    

2. 如何结合使用 StreamOptional

虽然 StreamOptional 的作用不同,但它们在实际编程中有很多交集。主要的原因是 Stream 中的某些操作返回的是 Optional,而 Optional 也提供了一些函数式方法,使得它可以链式地进行操作,和 Stream 很好地结合。

2.1. Stream 操作返回 Optional

某些 Stream 方法在无法返回单一元素时会返回 Optional。例如,findFirst()findAny()reduce() 等方法:

// 返回一个包含第一个匹配元素的 Optional,如果流为空,则返回 Optional.empty()
Optional<String> firstMatch = Stream.of("apple", "banana", "cherry")
                                    .filter(fruit -> fruit.startsWith("b"))
                                    .findFirst();

// 输出:Optional[banana]
System.out.println(firstMatch);
2.2. Optional 的方法可以与 Stream 配合使用
  • Optional 提供了一些方法(如 map()flatMap()filter()ifPresent() 等)可以在值存在时进行链式操作。通过这些方法,你可以对流中的元素进行转换、过滤等操作,并优雅地处理 null 情况。

    例如,可以将 Stream 中的元素通过 findFirst() 查找后,进行 Optional 操作:

String result = Stream.of("apple", "banana", "cherry")
                      .filter(fruit -> fruit.startsWith("b"))
                      .findFirst()  // 返回 Optional<String>
                      .map(String::toUpperCase)  // Optional -> Optional<String>
                      .orElse("No match found");

System.out.println(result);  // 输出: BANANA

这里,我们使用 findFirst() 返回一个 Optional,然后使用 map() 方法将值转换为大写。如果 findFirst() 找不到任何匹配的元素,则使用 orElse() 给出一个默认值 "No match found"

3. StreamOptional 的常见组合方式

以下是 StreamOptional 常见的组合方式,展示了如何利用这两者的结合处理数据。

3.1. findFirst()map()

findFirst() 返回一个 Optional,如果有匹配的元素就返回该元素,否则返回 Optional.empty()。结合 map(),可以在找到了元素后进行转换:

Optional<String> firstMatch = Stream.of("apple", "banana", "cherry")
                                    .filter(fruit -> fruit.startsWith("b"))
                                    .findFirst();

String result = firstMatch
                    .map(String::toUpperCase)
                    .orElse("No match found");

System.out.println(result);  // 输出: BANANA
3.2. filter()flatMap()

Optional 提供了 filter()flatMap() 方法,这使得你可以更灵活地进行操作。例如,filter() 用于基于条件过滤,而 flatMap() 可以将 Optional 转换为另一个 Optional,从而支持链式操作。

Optional<String> firstMatch = Stream.of("apple", "banana", "cherry")
                                    .filter(fruit -> fruit.startsWith("b"))
                                    .findFirst();

String result = firstMatch
                    .filter(fruit -> fruit.length() > 5)  // 过滤掉长度小于等于5的水果
                    .map(String::toUpperCase)
                    .orElse("No match found");

System.out.println(result);  // 输出: BANANA
3.3. reduce()Optional

reduce()Stream 中常用的一个方法,它将流中的元素聚合为一个单一的结果。reduce() 返回的类型是 Optional,因为结果可能为空。

Optional<Integer> sum = Stream.of(1, 2, 3, 4, 5)
                              .reduce(Integer::sum);

sum.ifPresent(System.out::println);  // 输出: 15

4. 小结

  • Stream 用于处理数据流,可以对集合中的数据进行函数式操作,支持各种中间操作(如 filter()map()flatMap() 等)。
  • Optional 用于处理可能为 null 的值,避免显式的 null 检查,它提供了方便的函数式方法(如 map()orElse()filter() 等)。
  • Stream 中的某些方法(如 findFirst()reduce())返回 Optional,使得它可以与 Optional 紧密结合,利用 Optional 的函数式方法优雅地处理流中的元素。

通过这种方式,StreamOptional 可以非常自然地协作,避免了传统的 null 检查,使得代码更加简洁和易于维护。

🎉🌈 陪伴至此,感谢有你 🌈🎉

感谢你能坚持看到这里!如果这篇文章对你有一点点帮助,希望能收获你的:
👍 一个赞,⭐ 一个收藏,💬 一条评论 或 🔗 一键分享!
你的支持是我持续输出的最大动力!✨

有问题?有灵感?
别犹豫,直接留言和我交流~让我们一起成长、一起突破 💡。

最后,祝你:

🍯 生活美满如蜜香
🌞 心情灿烂似朝阳
🌱 成长如树渐成章
🚀 未来闪耀梦飞翔!

再次感谢你的阅读!🌟 下次再见~ 🎉

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值