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 对象为空,返回默认值 0System.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);
解释:
-
使用
ofNullable
方法将可能为null的对象包装成Optional对象,以便在后续流式处理中操作。 -
使用
map
方法将Optional中的Authentication
对象映射为其principal
属性。 -
使用
filter
方法过滤类型不是LoginUser
的情况。 -
如果存在符合条件的
LoginUser
对象,则使用map
方法将其强转为LoginUser
类型返回;否则,返回null。