Optional类是java8中引入的一个非常有用的类,它可以用来解决空指针异常带来的不便。这个类可以将对象包装为一个Optional对象,如果该对象为空,则可以使用一些默认值或者执行一些默认操作。Optional 是 Java 实现函数式编程的强劲一步,并且帮助在范式中实现。

Java8的Optional类提供了丰富的 API 方法,这里按照其功能分类介绍。

一、创建 Optional 对象的方法

empty()

  empty()方法用于创建一个空的Optional对象。该方法返回的Optional对象中没有包含任何值,因此它永远不会抛出 NullPointerException 异常。

下面是使用empty()方法创建一个空的 Optional 对象的示例:

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

        上述代码中,我们使用了Optional.empty()方法来创建一个空的 Optional 对象,并将该对象赋值给了一个名为 emptyOptional 的变量。

        当需要使用 Optional 类型的变量,但还不知道它的值应该是什么时,可以使用Optional.empty()方法来初始化该变量,以表示该变量当前还没有被赋值。

        在对 Optional 对象进行操作时,必须先判断 Optional 对象中是否实际包含值,否则可能会抛出 NoSuchElementException 异常。使用isPresent()方法可以判断 Optional 对象中是否包含值,如果返回 true,则说明 Optional 对象中包含值,否则说明 Optional 对象为空。

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

if (emptyOptional.isPresent()) {
    String value = emptyOptional.get();
} else {
    System.out.println("Optional对象为空");
}

         上述代码中,我们对创建的空的 Optional 对象进行了判断,由于 Optional 对象中并没有包含任何值,因此输出的结果是"Optional对象为空"。

of(T value)

  of(T value)方法用于创建一个包含指定值的 Optional 对象。该方法接收一个非 null 值作为参数,如果传入的参数为 null,则会抛出 NullPointerException 异常。

        下面是使用of()方法创建一个包含指定值的 Optional 对象的示例:

String str = "Hello World";
Optional<String> optionalStr = Optional.of(str);

         上述代码中,我们使用Optional.of()方法将一个非 null 的字符串类型变量 str 包装到 Optional 对象中,并将其赋值给了一个名为 optionalStr 的变量。

创建包含指定值的 Optional 对象后,可以使用get()方法获取 Optional 对象中的实际值。

String str = "Hello World";
Optional<String> optionalStr = Optional.of(str);

String value = optionalStr.get();
System.out.println(value); // 输出"Hello World"

        上述代码中,我们首先使用Optional.of()方法创建一个包含字符串类型的值的 Optional 对象,然后使用get()方法获取 Optional 对象中的实际值,并将其输出到控制台上。

需要注意的是,传入of()方法的参数必须是非 null 的值,否则会抛出 NullPointerException 异常。

String str = null;
Optional<String> optionalStr = Optional.of(str); // 抛出 NullPointerException 异常

         上述代码中,我们将一个 null 值传入Optional.of()方法,由于传入的参数为 null,因此会抛出 NullPointerException 异常。

ofNullable(T value)

   ofNullable(T value)方法用于创建一个包含指定值的 Optional 对象。该方法接收一个可能为 null 的值作为参数,如果传入的参数为 null,则返回一个空的 Optional 对象。

下面是使用ofNullable()方法创建一个包含指定值的 Optional 对象的示例:

String str = "Hello World";
Optional<String> optionalStr1 = Optional.ofNullable(str);

String str2 = null;
Optional<String> optionalStr2 = Optional.ofNullable(str2);

        上述代码中,我们使用Optional.ofNullable()方法将一个可能为 null 的字符串类型变量 str 包装到 Optional 对象中,并将其赋值给了一个名为 optionalStr1 的变量。同时,我们也将一个为 null 的字符串类型变量 str2 包装到 Optional 对象中,并将其赋值给了一个名为 optionalStr2 的变量。

需要注意的是,使用ofNullable()方法创建 Optional 对象时,传入的参数可以为 null,此时会自动返回一个空的 Optional 对象。

String str = null;
Optional<String> optionalStr = Optional.ofNullable(str);

         上述代码中,我们将一个为 null 的字符串类型变量 str 传入了Optional.ofNullable()方法。由于传入的参数为 null,因此该方法会返回一个空的 Optional 对象,不会抛出 NullPointerException 异常。

在对 Optional 对象进行操作时,必须先判断 Optional 对象是否实际包含值,否则可能会抛出 NoSuchElementException 异常。使用isPresent()方法可以判断 Optional 对象中是否包含值,如果返回 true,则说明 Optional 对象中包含值,否则说明 Optional 对象为空。

String str = "Hello World";
Optional<String> optionalStr = Optional.ofNullable(str);

if (optionalStr.isPresent()) {
    String value = optionalStr.get();
} else {
    System.out.println("Optional对象为空");
}

         上述代码中,我们对创建的 Optional 对象进行了判断,由于 Optional 对象中包含非 null 的值,因此使用get()方法获取 Optional 对象中的实际值,并将其赋值给一个名为 value 的变量。

二、判断 Optional 对象是否包含值的方法

isPresent()

 isPresent()方法用于判断 Optional 对象中是否存在非 null 值。如果 Optional 对象中存在非 null 值,该方法会返回 true;否则返回 false。

下面是使用isPresent()方法判断 Optional 对象是否存在非 null 值的示例:

String str = "Hello World";
Optional<String> optionalStr = Optional.ofNullable(str);

if (optionalStr.isPresent()) {
    String value = optionalStr.get();
} else {
    System.out.println("Optional对象为空");
}

 上述代码中,我们首先使用Optional.ofNullable()方法将一个可能为 null 的字符串类型变量 str 包装到 Optional 对象中,并将其赋值给了一个名为 optionalStr 的变量。接着,我们使用isPresent()方法判断 Optional 对象中是否存在非 null 值,如果存在,则使用get()方法获取 Optional 对象中的实际值,并将其赋值给一个名为 value 的变量;否则输出“Optional对象为空”。

需要注意的是,在对 Optional 对象进行操作时,必须先判断 Optional 对象中是否存在值,否则可能会抛出 NoSuchElementException 异常。

String str = null;
Optional<String> optionalStr = Optional.ofNullable(str);

String value = optionalStr.get(); // 抛出 NoSuchElementException 异常

 上述代码中,我们使用Optional.ofNullable()方法将一个为 null 的字符串类型变量 str 包装到 Optional 对象中,并将其赋值给了一个名为 optionalStr 的变量。由于 Optional 对象中并不包含实际值(因为 str 为 null),因此在使用get()方法获取 Optional 对象中的实际值时会抛出 NoSuchElementException 异常。因此,在对 Optional 对象进行操作时,一定要先判断 Optional 对象中是否存在值。

isEmpty()

isEmpty()方法用于判断 Optional 对象是否为空,如果 Optional 对象中包含非 null 值,则返回 false;否则返回 true。

下面是使用isEmpty()方法判断 Optional 对象是否为空的示例:

String str = "Hello World";
Optional<String> optionalStr = Optional.ofNullable(str);

if (optionalStr.isEmpty()) {
    System.out.println("Optional对象为空");
} else {
    String value = optionalStr.get();
    System.out.println("Optional对象的值为:" + value);
}

在上面的示例中,我们首先使用Optional.ofNullable()方法将一个可能为 null 的字符串类型变量 str 包装到 Optional 对象中,并将其赋值给了一个名为 optionalStr 的变量。接着,我们使用isEmpty()方法判断 Optional 对象是否为空,如果为空,则输出“Optional对象为空”,否则使用get()方法获取 Optional 对象中的实际值,并将其赋值给一个名为 value 的变量,并输出“Optional对象的值为:Hello World”。

需要注意的是,在 JDK 11 中新增的isEmpty()方法与isPresent()方法的作用相反,这里我们演示的是 JDK 11 中的新版本,如果您使用的是旧版本的 JDK,则无法使用isEmpty()方法。

String str = "Hello World";
Optional<String> optionalStr = Optional.ofNullable(str);

if (optionalStr.isPresent()) {
    String value = optionalStr.get();
    System.out.println("Optional对象的值为:" + value);
} else {
    System.out.println("Optional对象为空");
}

 上述代码中,我们使用isPresent()方法判断 Optional 对象中是否存在非 null 值。如果存在,则使用get()方法获取 Optional 对象中的实际值,并将其赋值给一个名为 value 的变量,并输出“Optional对象的值为:Hello World”;否则输出“Optional对象为空”。

三、获取 Optional 对象中的值的方法

get()

get()方法来获取包装在其中的实际值,但是它需要在 Optional 对象中存储一个非 null 的值,否则会抛出 NoSuchElementException 异常。

下面是使用get()方法获取 Optional 对象中的实际值的示例:

String str = "Hello World";
Optional<String> optionalStr = Optional.ofNullable(str);

if (optionalStr.isPresent()) {
    String value = optionalStr.get();
    System.out.println("Optional对象的值为:" + value);
} else {
    System.out.println("Optional对象为空");
}

在上述代码中,我们首先使用Optional.ofNullable()方法将一个可能为 null 的字符串类型变量 str 包装到 Optional 对象中,并将其赋值给了一个名为 optionalStr 的变量。接着,我们使用isPresent()方法判断 Optional 对象中是否包含非 null 值,如果存在,则使用get()方法获取 Optional 对象中的实际值,并将其赋值给一个名为 value 的变量,并输出“Optional对象的值为:Hello World”;否则输出“Optional对象为空”。

需要注意的是,在 Optional 对象没有值的情况下调用get()方法会抛出 NoSuchElementException 异常,因此在使用get()方法之前必须先判断 Optional 对象中是否存在值。可以使用isPresent()方法来判断 Optional 对象中是否存在值,或者使用orElse()方法设置默认值以避免抛出异常。

String str = null;
Optional<String> optionalStr = Optional.ofNullable(str);

String value = optionalStr.get(); // 抛出 NoSuchElementException 异常

在上述代码中,我们使用Optional.ofNullable()方法将一个为 null 的字符串类型变量 str 包装到 Optional 对象中,并将其赋值给了一个名为 optionalStr 的变量。由于 Optional 对象中并不包含实际值(因为 str 为 null),因此在调用get()方法时会抛出 NoSuchElementException 异常。 

orElse(T other)

  orElse(T other)方法用于在 Optional 对象不包含非 null 值的情况下提供默认值。

下面是使用orElse(T other)方法设置默认值的示例:

String str = null;
Optional<String> optionalStr = Optional.ofNullable(str);

String value = optionalStr.orElse("默认值");
System.out.println("Optional对象的值为:" + value);

        在上述代码中,我们首先使用Optional.ofNullable()方法将一个为 null 的字符串类型变量 str 包装到 Optional 对象中,并将其赋值给了一个名为 optionalStr 的变量。接着,我们调用orElse("默认值")方法来设置默认值。由于 optionalStr 中并没有实际值,因此orElse()方法会返回提供的默认值,并将其赋值给 name 变量。最后,输出“Optional对象的值为:默认值”。

        需要注意的是,调用orElse(T other)方法时必须指定一个非 null 的值作为参数,用于在 Optional 对象中不存在实际值时返回。

String str = null;
Optional<String> optionalStr = Optional.ofNullable(str);

String value = optionalStr.orElse(null); // 抛出 NullPointerException 异常

        在上述代码中,我们同样使用Optional.ofNullable()方法将一个为 null 的字符串类型变量 str 包装到 Optional 对象中,并将其赋值给了一个名为 optionalStr 的变量。接着,我们调用orElse(null)方法来设置默认值。由于传递给orElse()方法的参数为 null,因此在Optional对象中不存在实际值时,调用orElse(null)方法会抛出NullPointerException异常。因此,在调用orElse(T other)方法时必须指定一个非 null 的默认值。

orElseGet(Supplier<? extends T> other)

   orElseGet(Supplier<? extends T> other) 方法与 orElse(T other) 方法类似,都是在 Optional 对象不包含非 null 值的情况下提供默认值。不同的是,orElseGet(Supplier<? extends T> other) 方法需要传递一个 Supplier 对象作为参数,在 Optional 对象不包含非 null 值时,会调用该 Supplier 对象提供的方法来生成默认值。

下面是使用 orElseGet(Supplier<? extends T> other) 方法设置默认值的示例:

String str = null;
Optional<String> optionalStr = Optional.ofNullable(str);

String value = optionalStr.orElseGet(() -> "默认值");
System.out.println("Optional对象的值为:" + value);

        在上述代码中,我们首先使用 Optional.ofNullable() 方法将一个为 null 的字符串类型变量 str 包装到 Optional 对象中,并将其赋值给了一个名为 optionalStr 的变量。接着,我们调用 orElseGet(() -> "默认值") 方法来设置默认值。由于 optionalStr 中并没有实际值,因此 orElseGet() 方法会调用传递的 Supplier 对象来生成默认值,并将其赋值给 value 变量。因为我们传递的 Supplier 对象返回的是字符串 "默认值",所以 value 变量最终的值为 "默认值"。最后,输出“Optional对象的值为:默认值”。

需要注意的是,使用 orElseGet(Supplier<? extends T> other) 方法时,传递的 Supplier 对象不能为 null,否则会抛出 NullPointerException 异常。

String str = null;
Optional<String> optionalStr = Optional.ofNullable(str);

String value = optionalStr.orElseGet(null); // 抛出 NullPointerException 异常

         在上述代码中,我们同样使用 Optional.ofNullable() 方法将一个为 null 的字符串类型变量 str 包装到 Optional 对象中,并将其赋值给了一个名为 optionalStr 的变量。接着,我们调用 orElseGet(null) 方法来设置默认值。由于传递给 orElseGet() 方法的参数为 null,因此会抛出 NullPointerException 异常。因此,在调用 orElseGet(Supplier<? extends T> other) 方法时必须指定一个非 null 的 Supplier 对象。

orElseThrow(Supplier<? extends X> exceptionSupplier)

  orElseThrow(Supplier<? extends X> exceptionSupplier) 方法是 Optional 类中的一个方法,用于在 Optional 对象为空时抛出指定的异常。具体来说,如果 Optional 对象的值为 null,那么将会调用传入的 Supplier 函数生成一个异常对象,然后将其抛出。

下面是一个使用 orElseThrow() 方法的示例:

Optional<String> optionalStr = Optional.ofNullable(null);

String result = optionalStr.orElseThrow(() -> new RuntimeException("字符串为空"));

        在上述代码中,我们使用 Optional.ofNullable() 方法将一个 null 值包装成 Optional 类型的对象并赋值给 optionalStr 变量。接着,我们调用 orElseThrow() 方法设置了一个默认值,如果 Optional 对象当前的值为空,就会抛出由匿名Supplier 对象生成的RuntimeException 异常,并将异常信息设置为"字符串为空"。因为这个 Optional 为空,所以会抛出异常。

需要注意的是,使用 orElseThrow() 方法时,必须指定一个 Supplier 对象来生成异常。这个Supplier 对象返回的是需要抛出的异常对象。

Optional<String> optionalStr = Optional.ofNullable(null);

String result = optionalStr.orElseThrow(null); // 抛出 NullPointerException 异常

        如果在调用orElseThrow() 方法时传递的 Supplier 参数为 null,则会抛出NullPointerException 异常。因此,在调用 orElseThrow(Supplier<? extends X> throwableSupplier) 方法时必须指定一个非null的Supplier函数。 

四、对 Optional 对象中的值进行操作的方法

ifPresent(Consumer<? super T> consumer)

   ifPresent(Consumer<? super T> consumer) 方法是 Optional 类中的一个方法,用于判断 Optional 对象是否有值(即不为 null)。如果该对象有值,则调用传入的 Consumer 函数处理该值。否则,什么也不做。

下面是一个使用 ifPresent() 方法的示例:

import java.util.Optional;

public class Example {
    public static void main(String[] args) {
        Optional<String> optionalStr = Optional.of("Hello World!");

        optionalStr.ifPresent(str -> System.out.println("Optional 中包含非空字符串:" + str));
    }
}

        在这个示例中,我们首先创建了一个值为 "Hello World!"Optional 对象。接着,我们使用 ifPresent(Consumer<? super T> consumer) 方法判断 Optional 对象是否有值,如果有则输出 "Optional 中包含非空字符串:" 连接上该字符串的值。

在运行这个程序后,输出结果应该为:

Optional 中包含非空字符串:Hello World!

         使用 ifPresent() 方法时,必须设置一个非空的 Consumer 函数。该函数用于处理 Optional 对象中包含的值。如果该对象为空,ifPresent() 方法不会做任何事情。

filter(Predicate<? super T> predicate)

   filter(Predicate<? super T> predicate)Optional 类中的一个方法,它用于过滤 Optional 对象中的值,只有当值满足特定条件时才保留。

该方法接受一个 Predicate 参数,这个参数是一个函数式接口,需要自己实现其中的 test(T t) 方法。test(T t) 方法用于测试指定对象是否符合特定条件。

        如果 Optional 对象中的值满足 Predicate 参数中的条件,则返回该值所在的 Optional 对象,否则返回一个空的 Optional 对象。

示例代码:

import java.util.Optional;

public class Example {
    public static void main(String[] args) {
        Optional<String> optionalStr = Optional.of("Hello World!");

        Optional<String> filtered = optionalStr.filter(str -> str.contains("World"));
        System.out.println("过滤后的 Optional 对象:" + filtered);
    }
}

        在上面的示例中,我们首先创建了一个值为 "Hello World!"Optional 对象。接着,我们使用 filter 方法并传入一个 Predicate 参数,这个 Predicate 参数判断字符串是否包含 "World" 子串,如果包含则返回此 Optional 对象,否则返回一个空 Optional 对象。

输出结果如下:

过滤后的 Optional 对象:Optional[Hello World!]

         需要注意的是,如果 Optional 对象中的值为 null,则直接返回一个空的 Optional 对象,并不会执行传进去的 Predicate 参数的计算。如果需要对 null 值进行判断,可以使用 Optional.ofNullable(T value) 方法来创建一个包含可空值的 Optional 对象。

map(Function<? super T, ? extends U> mapper)

        map(Function<? super T, ? extends U> mapper) 是 Optional 类中的一个方法,用于对 Optional 对象中的值进行转换,并返回一个新的 Optional 对象。该方法接受一个 Function 参数,这个参数也是一个函数式接口,需要自己实现其中的 apply(T t) 方法。apply(T t) 方法用于将指定类型的对象转换为另一种类型的对象。
        如果 Optional 对象中的值不为空,则将该值作为参数传递给 Function 对象中的 apply(T t) 方法,得到一个新的对象作为转换后的结果;否则直接返回一个空的 Optional 对象。

示例代码:

import java.util.Optional;

public class Example {
    public static void main(String[] args) {
        Optional<String> optionalStr = Optional.of("Hello World!");

        Optional<Integer> lengthOptional = optionalStr.map(String::length);
        lengthOptional.ifPresent(len -> System.out.println("字符串长度为:" + len));
    }
}

在上面的示例中,我们首先创建了一个值为 "Hello World!"Optional 对象。接着,我们使用 map 方法并传入一个 Function 参数,这个 Function 参数将字符串转换成了整型,即字符串的长度。在这里,我们使用方法引用 String::length,而不是使用 lambda 表达式来实现。

接着,我们使用 ifPresent 方法判断新的 Optional 对象是否为空,如果不为空则输出其中的值。

输出结果如下:

字符串长度为:11

        需要注意的是,在调用 map 方法时,返回值是一个新的 Optional 对象,因此我们可以在该对象上连续调用其他方法来进行操作,比如 orElse(T other)orElseGet(Supplier<? extends T> other) 等。同时如果 Function 对象中的转换过程中抛出了异常,则该方法也会将该异常包装进一个 RuntimeException 中重新抛出。

flatMap(Function<? super T, Optional<U>> mapper)

  flatMap(Function<? super T, Optional<U>> mapper)Optional 类中的一个方法,用于对 Optional 对象中的值进行转换,并返回一个新的 Optional 对象。该方法接受一个 Function 参数,这个参数也是一个函数式接口,需要自己实现其中的 apply(T t) 方法。apply(T t) 方法用于将指定类型的对象转换为另一种类型的 Optional 对象。

        如果 Optional 对象中的值不为空,则将该值作为参数传递给 Function 对象中的 apply(T t) 方法,得到一个新的 Optional 对象作为转换后的结果;否则直接返回一个空的 Optional 对象。与 map 方法不同,flatMap 方法可以将最终产生的 Optional 对象展开,使其成为一个扁平的对象。

示例代码:

import java.util.Optional;

public class Example {
    public static void main(String[] args) {
        Optional<String> optionalStr = Optional.of("Hello World!");

        Optional<Integer> lengthOptional = optionalStr.flatMap(str -> {
            if(str.contains("World")) {
                return Optional.of(str.length());
            } else {
                return Optional.empty();
            }
        });
        lengthOptional.ifPresent(len -> System.out.println("字符串长度为:" + len));
    }
}

        在上面的示例中,我们首先创建了一个值为 "Hello World!"Optional 对象。接着,我们使用 flatMap 方法并传入一个 Function 参数,这个 Function 参数将根据字符串中是否包含 "World" 子串,返回一个或者空的 Optional 对象。

        在这里,如果字符串中包含 "World" 子串,则返回包含字符串长度的 Optional 对象;否则返回一个空的 Optional 对象。最终得到的结果是一个扁平化的 Optional 对象。

        接着,我们使用 ifPresent 方法判断新的 Optional 对象是否为空,如果不为空则输出其中的值。

输出结果如下:

字符串长度为:11

        需要注意的是,在调用 flatMap 方法时,返回值是一个新的 Optional 对象,因此我们可以在该对象上连续调用其他方法来进行操作,比如 orElse(T other)orElseGet(Supplier<? extends T> other) 等。同时如果 Function 对象中的转换过程中抛出了异常,则该方法也会将该异常包装进一个 RuntimeException 中重新抛出。 

orElseThrow()

  orElseThrow()方法,用于在 Optional 对象为空时抛出指定的异常。该方法不接受任何参数,在 Optional 对象为空时会抛出一个默认的 NoSuchElementException 异常。如果需要指定其他类型的异常,请使用带有 Supplier<? extends X> exceptionSupplier 参数的重载方法。

示例代码:

import java.util.Optional;

public class Example {
    public static void main(String[] args) {
        Optional<String> optionalStr1 = Optional.of("Hello World!");
        String str1 = optionalStr1.orElseThrow();
        System.out.println(str1);

        Optional<String> optionalStr2 = Optional.empty();
        String str2 = optionalStr2.orElseThrow(() -> new RuntimeException("值不存在!"));
    }
}

        在上面的示例中,我们首先创建了一个值为 "Hello World!"Optional 对象 optionalStr1。接着,我们调用了 orElseThrow() 方法获取 optionalStr1 中的值,由于 optionalStr1 不为空,因此可以直接返回其中的值,并将其赋值给 str1。最终输出结果为 "Hello World!"。

     接着,我们创建了一个空的 Optional 对象 optionalStr2。接着,我们调用了 orElseThrow(Supplier<? extends X> exceptionSupplier) 方法,由于 optionalStr2 为空,因此该方法会抛出一个 RuntimeException 异常。在这里,我们通过 lambda 表达式传入了一个异常信息,表示值不存在。最终程序抛出异常,输出结果如下:   

Hello World!
Exception in thread "main" java.lang.RuntimeException: 值不存在!
	at Example.main(Example.java:10)

        需要注意的是,在调用 orElseThrow() 方法时,如果 Optional 对象为空,则该方法会抛出一个异常。因此在使用该方法时,需要确保 Optional 对象中有值。同时,如果需要抛出指定类型的异常,也可以调用带有 Supplier<? extends X> exceptionSupplier 参数的重载方法并传入异常信息。


上述是Java8中Optional类提供的常用方法,开发者可以根据自己的需求灵活使用。

 五、Optional类方法组合使用的示例

   组合使用 filter 和 map 方法

import java.util.Optional;

public class Example {
    public static void main(String[] args) {
        Optional<String> optionalStr = Optional.of("123");

        int value = optionalStr
                .filter(str -> str.length() > 0) // 筛选出非空字符串
                .map(Integer::parseInt) // 将字符串转换成整型数字
                .orElse(0); // 如果 Optional 对象为空,返回默认值 0

        System.out.println(value); // 输出结果为 123
    }
}

        在上面的示例中,我们通过 Optional 类中的 filter 方法和 map 方法组合对字符串进行处理。首先,我们对字符串进行了非空过滤,然后将其转换成整型数字。最后,如果 Optional 对象为空,我们设置了一个默认值 0。最终输出结果为 123。

组合使用 filter 和 flatMap 方法

import java.util.Optional;

public class Example {
    public static void main(String[] args) {
        Optional<String> optionalStr = Optional.of("hello, world");

        optionalStr
                .filter(str -> str.contains("world")) // 筛选出包含 "world" 的字符串
                .flatMap(str -> Optional.of(str.length())) // 将符合条件的字符串封装成新的 Optional 对象
                .ifPresent(System.out::println); // 输出长度大于等于 5 的字符串

    }
}

        在上面的示例中,我们使用了 filter 方法对字符串进行过滤,只保留包含 "world" 的字符串。接着,我们使用 flatMap 方法将符合条件的字符串封装成新的 Optional 对象。最后,我们通过 ifPresent 方法输出长度大于等于 5 的字符串的长度。

组合使用 map 和 orElseThrow 方法

import java.util.Optional;

public class Example {
    public static void main(String[] args) {
        Optional<String> optionalStr = Optional.of("hello");
        
        int length = optionalStr
                .map(String::length) // 将字符串映射成其长度
                .orElseThrow(IllegalArgumentException::new); // 如果 Optional 对象为空,抛出 IllegalArgumentException 异常
        
        System.out.println(length); // 输出结果为 5
    }
}

        在上面的示例中,我们使用了 map 方法将字符串映射成其长度,并使用 orElseThrow 方法当 Optional 对象为空时抛出异常。

        需要注意的是,在使用 Optional 类中的方法组合时,每一个方法的返回值都是一个 Optional 对象,因此可以在该对象上继续调用其他方法,直到最终得到需要的值。同时,如果在方法组合的过程中出现了空值,那么后续的方法将不会被执行,并返回一个空的 Optional 对象。

组合示例

import java.util.Optional;

public class Example {
    public static void main(String[] args) {
        Optional<String> optionalStr = Optional.of("Hello, World!");

        optionalStr
                .filter(str -> str.contains("World")) // 筛选出包含 "World" 的字符串
                .map(String::length) // 将剩余的字符串映射成其长度
                .flatMap(len -> {
                    if (len >= 10) {
                        return Optional.of("String length: " + len);
                    } else {
                        return Optional.empty();
                    }
                }) // 对字符串长度进行判断并封装成 Optional 对象
                .ifPresent(System.out::println); // 输出长度大于等于 10 的字符串
    }
}

        在上面的示例中,我们首先创建了一个值为 "Hello, World!"Optional 对象 optionalStr。接着,我们使用 filter 方法对 optionalStr 对象中的值进行筛选,只保留包含 "World" 子串的字符串。然后,我们使用 map 方法将剩余的字符串映射成其长度。接着,我们使用 flatMap 方法对字符串长度进行判断,并将符合条件的长度封装成一个新的 Optional 对象。最后,我们通过 ifPresent 方法输出长度大于等于 10 的字符串。

        需要注意的是,在调用 Optional 方法组合时,每一个方法的返回值都是一个 Optional 对象,因此可以在该对象上继续调用其他方法,直到最终得到需要的值。同时,如果在方法组合的过程中出现了空值,那么后续的方法将不会被执行,并返回一个空的 Optional 对象。

输出结果如下:

String length: 13

多层判断组合示例

获取用户信息

SecurityContextHolder.getContext().getAuthentication();
    if (authentication != null) {
		Object principal = authentication.getPrincipal();
		if (principal != null && principal instanceof LoginUser) {
			return (LoginUser) principal;
		}
	}

使用Java 8中的Optional类优化上述代码,使其更加简洁和易读。优化后的代码如下:

    
   // 使用Java 8中的Optional类优化上述代码,使其更加简洁和易读。优化后的代码如下:
   return Optional.ofNullable(SecurityContextHolder.getContext().getAuthentication())
    .map(Authentication::getPrincipal)
    .filter(principal -> principal instanceof LoginUser)
    .map(LoginUser.class::cast)
    .orElse(null);

解释:

  1. 使用ofNullable方法将可能为null的对象包装成Optional对象,以便在后续流式处理中操作。

  2. 使用map方法将Optional中的Authentication对象映射为其principal属性。

  3. 使用filter方法过滤类型不是LoginUser的情况。

  4. 如果存在符合条件的LoginUser对象,则使用map方法将其强转为LoginUser类型返回;否则,返回null。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐