Optional
Java8引入的新特性
转自: https://www.cnblogs.com/zhangboyu/p/7580262.html
解决的痛点问题
空指针异常(NullPointerException),任何访问对象方法或属性的调用都可能导致 NullPointerException
特性
创建Optional实例
-
对象不为 null 的时候使用 of()。
-
如果对象即可能是 null 也可能是非 null,你就应该使用 ofNullable() 方法
public static void main(String args[]){ Java8Tester java8Tester = new Java8Tester(); Integer value1 = null; Integer value2 = new Integer(10); // Optional.ofNullable - 允许传递为 null 参数 Optional<Integer> a = Optional.ofNullable(value1); // Optional.of - 如果传递的参数是 null,抛出异常 NullPointerException Optional<Integer> b = Optional.of(value2); System.out.println(java8Tester.sum(a,b)); }
访问
-
先判断是否存在isPresent()
-
再调用get()
@Test public void whenCheckIfPresent_thenOk() { User user = new User("john@gmail.com", "1234"); Optional<User> opt = Optional.ofNullable(user); assertTrue(opt.isPresent()); assertEquals(user.getEmail(), opt.get().getEmail()); }
返回值
-
orElse
@Test public void whenEmptyValue_thenReturnDefault() { User user = null; User user2 = new User("anna@gmail.com", "1234"); User result = Optional.ofNullable(user).orElse(user2); assertEquals(user2.getEmail(), result.getEmail()); }
-
orElseGet()
User result = Optional.ofNullable(user).orElseGet( () -> user2);
-
空值时, 都返回user2对象;非空值时,orElse() 方法不创建 User 对象, orElseGet()总会创建新对象,性能上可能差一些
返回异常
-
orElseThrow()
@Test(expected = IllegalArgumentException.class) public void whenThrowException_thenOk() { User result = Optional.ofNullable(user) .orElseThrow( () -> new IllegalArgumentException()); }
转化值
-
map():map() 对值应用(调用)作为参数的函数,然后将返回的值包装在 Optional 中
@Test public void whenMap_thenOk() { User user = new User("anna@gmail.com", "1234"); String email = Optional.ofNullable(user) .map(u -> u.getEmail()).orElse("default@gmail.com"); assertEquals(email, user.getEmail()); }
-
flatMap(), 返回解除包装类的值
@Test public void whenFlatMap_thenOk() { User user = new User("anna@gmail.com", "1234"); user.setPosition("Developer"); String position = Optional.ofNullable(user) .flatMap(u -> u.getPosition()).orElse("default"); assertEquals(position, user.getPosition().get()); }
过滤值
-
filter(): bool参数。返回测试结果为 true 的值;false,会返回一个空的 Optional
@Test public void whenFilter_thenOk() { User user = new User("anna@gmail.com", "1234"); Optional<User> result = Optional.ofNullable(user) .filter(u -> u.getEmail() != null && u.getEmail().contains("@")); assertTrue(result.isPresent()); }
链式方法
@Test
public void whenChaining_thenOk() {
User user = new User("anna@gmail.com", "1234");
String result = Optional.ofNullable(user)
.flatMap(u -> u.getAddress())
.flatMap(a -> a.getCountry())
.map(c -> c.getIsocode())
.orElse("default");
assertEquals(result, "default");
}
应用场景
- Optional 不是 Serializable, 所以它不应该用作类的字段
- 不应该作为方法或构建函数的参数,会将代码复杂化
- 主要用作返回类型