在某些状况下,首先要判断某个参数或者某个方法的返回值是否为null,才能继续操做该参数。对于某些链式操做须要屡次经过if语句判断是否为空,才能确保不抛出NullPointerException,这段非空判断的代码显得很是冗长和恶心。好比下面这段代码:java
String isoCode = "default"; if (user != null) { Address address = user.getAddress(); if (address != null) { Country country = address.getCountry(); if (country != null) { isocode = country.getIosCode(); if (isocode != null) { isocode = isocode.toUpperCase(); } } } }
在java 8里,JDK引入了一个Optional类,该类是一个能够为null的容器对象。若是值存在则isPresent()方法会返回true,调用get()方法会返回该对象。经过本文的学习,咱们看下如何经过Optional类重写上面那段判空代码。ios
接下来,咱们一块儿学习Optional类的初始化和它里面的方法。lambda表达式和四个基本函数式接口是本文的基础,能够经过 java8 -函数式编程之Lambda表达式 和 java8 -函数式编程之四个基本接口 充分了解。编程
Optional类的构造方法是私有方法,因此只能经过它的静态工厂方法进行初始化。它的初始化方法有以下四种:app
(1) <T> Optional<T> of (T value) :为非null的值建立一个Optional。若是传入参数为null,抛出NullPointerException。函数式编程
//调用工厂方法建立Optional实例 Optional<String> name = Optional.of("hello"); //传入参数为null,抛出NullPointerException. Optional<String> someNull = Optional.of(null);
(2)<T> Optional<T> ofNullable (T value) :为指定的值建立一个Optional,若是指定的值为null,则返回一个空的Optional。它和 of 的区别是能够传null值。在它的实现代码中,若是传的值为null,会调用另外一个静态工厂方法 empty 获取一个Optional对象。函数
Optional empty = Optional.ofNullable(null);
(3)<T> Optional<T> empty () :ofNullable静态工厂方法,传null值时的实现,返回一个空的Optional。学习
(1)isPresent :若是值存在返回true,不然返回false。测试
// false Optional<String> empty = Optional.ofNullable(null); System.out.println(empty.isPresent()); // true Optional<String> optionalS2 = Optional.of(s2); System.out.println(optionalS2.isPresent());
(2)get:若是Optional有值则将其返回,不然抛出NoSuchElementExceptionspa
//获取hello Optional.of("hello").get(); //抛出NoSuchElementException Optional.empty().get();
(3)void ifPresent (Consumer<? super T> consumer) :若是Optional实例有值则调用consumer,不然不作处理。.net
//调用ifPresent方法里面的consumer Optional.of("hello") .ifPresent(System.out::println);
(4)orElse:若是有值则将其返回,不然返回指定的其它值
//输出:null System.out.println(Optional.empty().orElse("null")); //输出:hello System.out.println(Optional.of("hello").orElse("null"));
(5)T orElseGet (Supplier<? extends T> other) :orElseGet与orElse方法相似,区别在于获得的默认值。orElse方法将传入的字符串做为默认值,orElseGet方法能够接受 Supplier接口 的实现用来生成默认值。
//输出null System.out.println(Optional.empty().orElseGet(() -> "null")); //输出hello System.out.println(Optional.of("hello").orElseGet(() -> "null"));
(6)<X extends Throwable> T orElseThrow (Supplier<? extends X> exceptionSupplier) throws X :若是有值则将其返回,不然抛出supplier接口建立的异常。
//抛出exception try { Optional.empty().orElseThrow(()->new Exception("为空")); } catch (Exception e) { e.printStackTrace(); }
(7)<U> Optional<U> map (Function<? super T, ? extends U> mapper) :若是参数 mapper 有值,则调用map方法执行mapper参数的Function方法获得返回值。若是mapper的返回值不为null,则建立包含mapping返回值的Optional做为map方法返回值,不然返回空Optional。若是传入的mapper参数是null,抛出NullPointerException。
//输出 JACK Optional<String> stringOptional = Optional.of("jack").map((value) -> value.toUpperCase()); System.out.println(stringOptional.orElse("default")); //输出 default Optional<String> stringOptional1 = Optional.of("jack").map((value) -> null); System.out.println(stringOptional1.orElse("default")); //输出 default,而且不会调用mapper String s2 = null; Optional<String> stringOptional2 = Optional.ofNullable(s2).map((value) -> value.toUpperCase()); System.out.println(stringOptional2.orElse("default")); //若是参数mapper为null,抛NullPointerException异常 try { String s3 = null; Optional<String> stringOptional3 = Optional.ofNullable(s3).map(null); System.out.println(stringOptional3.orElse("default")); } catch (Exception e) { }
(8)<U> Optional<U> flatMap (Function<? super T, Optional<U>> mapper) :flatMap与map方法相似,区别在于flatMap中的mapper返回值必须是Optional。调用结束时,flatMap不会对结果用Optional封装。
//flatMap,输出 JACK Optional<String> stringOptional4 = Optional.of("jack").flatMap((value) -> Optional.ofNullable(value.toUpperCase())); System.out.println(stringOptional4.orElse("default")); //flatMap,输出 default Optional<String> stringOptional5 = Optional.of("jack").flatMap((value) -> Optional.ofNullable(null)); System.out.println(stringOptional5.orElse("default")); //flatMap,输出 default,而且不会调用mapper String s6 = null; Optional<String> stringOptional6 = Optional.ofNullable(s6).flatMap((value) -> Optional.ofNullable(value.toUpperCase())); System.out.println(stringOptional6.orElse("default")); //flatMap 若是map的参数mapper为null,抛NullPointerException异常 try { String s7 = null; Optional<String> stringOptional7 = Optional.ofNullable(s7).flatMap(null); System.out.println(stringOptional7.orElse("default")); } catch (Exception e) { System.out.println("出错了"); }
(9)Optional<T> filter (Predicate<? super T> predicate) :若是有值而且知足断言条件返回包含该值的Optional,不然返回空Optional。
//输出default String filterString = Optional.of("hugo") .filter(s -> "jack".equals(s)) .orElse("default"); System.out.println(filterString); //输出hugo String filterString2 = Optional.of("hugo") .filter(s -> "hugo".equals(s)) .orElse("default"); System.out.println(filterString2); //输出default,断言接口里面的语句不会执行 String nullableString = null; String filterString3 = Optional.ofNullable(nullableString) .filter(s -> { System.out.println("测试是否调用"); return "jack".equals(s); }) .orElse("default"); System.out.println(filterString3);
通过上面学习Optional的相关API,已经对它有了必定的了解。下面,咱们运用上面的知识解决在前言中遗留的问题。
ioscode = Optional.ofNullable(user) .map(u -> u.getAddress()) .map(addr -> addr.getCountry()) .map(country -> country.getIosCode()) .map(String::toUpperCase) .orElse("default");
从上面的学习能够知道,只有Optional是empty的,map方法不会被调用。
Java 8 函数式编程系列