Java8:Optional类的解析

来源:互联网 发布:林心如真恶心知乎 编辑:程序博客网 时间:2024/06/13 04:11

Optional类的Javadoc描述如下:
Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。

Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。
Optional 类的引入很好的解决空指针异常。

Java 8 Optional 优点:

  • 不需要检查对象是否为空;
  • 在运行时不再有NullPointerException;
  • 我们可以开发干净整洁的API,减少代码量。

Optional.of()
为非null的值创建一个Optional。

Optional.ofNullable() ofNullable与of方法相似,唯一的区别是可以接受参数为null的情况。

Optional.empty()
创建一个为空的Optional

public static void main(String[] args) {    Optional<String> gender = Optional.of("MALE");    String answer1 = "Yes";    String answer2 = null;    System.out.println("Non-Empty Optional:" + gender);    // Non-Empty Optional:Optional[MALE]    System.out.println("Non-Empty Optional: Gender value : " + gender.get());    //Non-Empty Optional: Gender value : MALE    System.out.println("Empty Optional: " + Optional.empty());    //Empty Optional: Optional.empty    System.out.println("ofNullable on Non-Empty Optional: " + Optional.ofNullable(answer1));    //ofNullable on Non-Empty Optional: Optional[Yes]    System.out.println("ofNullable on Empty Optional: " + Optional.ofNullable(answer2));    //ofNullable on Empty Optional: Optional.empty    // java.lang.NullPointerException    System.out.println("ofNullable on Non-Empty Optional: " + Optional.of(answer2));}

Optional.map()
如果有值,则对其执行调用mapping函数得到返回值。如果返回值不为null,则创建包含mapping返回值的Optional作为map方法返回值,否则返回空Optional。
Optional.flatMap()
如果有值,为其执行mapping函数返回Optional类型返回值,否则返回空Optional。flatMap与map(Funtion)方法类似,区别在于flatMap中的mapper返回值必须是Optional。调用结束时,flatMap不会对结果用Optional封装。

public static void main(String[] args) {    Optional<String> oGender = Optional.of("male");    Optional<String> emptyGender = Optional.empty();    System.out.println("Non-Empty Optional::" + oGender.map(String::toUpperCase));    //Non-Empty Optional::Optional[MALE]    System.out.println("Empty Optional::" + emptyGender.map(String::toUpperCase));    //Empty Optional::Optional.empty    Optional<Optional<String>> ooGender = Optional.of(Optional.of("male"));    System.out.println("Optional value::" + ooGender);    //Optional value::Optional[Optional[male]]    System.out.println("Optional.map:: " + ooGender.map(gender -> gender.map(String::toUpperCase)));    //Optional.map:: Optional[Optional[MALE]]    System.out.println("Optional.flatMap::" + ooGender.flatMap(gender -> gender.map(String::toUpperCase)));    //Optional.flatMap::Optional[MALE]}

Optional.filter()
如果有值并且满足断言条件返回包含该值的Optional,否则返回空Optional。

public static void main(String[] args) {    Optional<String> gender = Optional.of("male");    Optional<String> emptyGender = Optional.empty();    //Filter on Optional    System.out.println(gender.filter(g -> g.equals("MALE")));    //Optional.empty    System.out.println(gender.filter(g -> g.equalsIgnoreCase("MALE")));    //Optional[male]    System.out.println(emptyGender.filter(g -> g.equalsIgnoreCase("MALE")));    //Optional.empty    // filter方法检查给定的Option值是否满足某些条件。    // 如果满足则返回同一个Option实例,否则返回空Optional。    Optional<String> longName = Optional.of("123456789").filter((value) -> value.length() > 6);    System.out.println(longName.orElse("The name is less than 6 characters"));//输出Sanaulla    //123456789    //另一个例子是Optional值不满足filter指定的条件。    Optional<String> anotherName = Optional.of("1234");    Optional<String> shortName = anotherName.filter((value) -> value.length() > 6);    System.out.println(shortName.orElse("The name is less than 6 characters"));    //The name is less than 6 characters}

Optional.isPresent()
如果值存在返回true,否则返回false。

Optional.get()
如果Optional有值则将其返回,否则抛出NoSuchElementException。

Optional.ifPresent()
如果Optional实例有值则为其调用consumer,否则不做处理。

Optional.orElse()
如果有值则将其返回,否则返回指定的其它值。

Optional.orElseGet()
orElseGet与orElse方法类似,区别在于得到的默认值。orElse方法将传入的字符串作为默认值,orElseGet方法可以接受Supplier接口的实现用来生成默认值。

Optional.orElseThrow()
如果有值则将其返回,否则抛出supplier接口创建的异常。

public static void main(String[] args) {    Optional<String> gender = Optional.of("MALE");    Optional<String> emptyGender = Optional.empty();    if (gender.isPresent()) {      System.out.println("Value available.");    } else {      System.out.println("Value not available.");    }    try {      //在空的Optional实例上调用get(),抛出NoSuchElementException      System.out.println(emptyGender.get());    } catch (NoSuchElementException ex) {      System.out.println(ex.getMessage());      //No value present    }    gender.ifPresent(g -> System.out.println("In gender Option, value is " + g));    //In gender Option, value is MALE    //condition failed, no output print    emptyGender.ifPresent(g -> System.out.println("In emptyGender Option, value available."));    System.out.println(gender.orElse("<N/A>"));    //MALE    System.out.println(emptyGender.orElse("<N/A>"));    //<N/A>    System.out.println(gender.orElseGet(() -> "<N/A>"));    //MALE    System.out.println(emptyGender.orElseGet(() -> "<N/A>"));    //<N/A>    try {      //orElseThrow与orElse方法类似。与返回默认值不同,      //orElseThrow会抛出lambda表达式或方法生成的异常      emptyGender.orElseThrow(ValueAbsentException::new);    } catch (Throwable ex) {      System.out.println(ex.getMessage());      //No value present in the Optional instance    }}public static class ValueAbsentException extends Throwable {    public ValueAbsentException() {      super();    }    public ValueAbsentException(String msg) {      super(msg);    }    @Override    public String getMessage() {      return "No value present in the Optional instance";    }}

例:Without Java 8 Optional

//分辨率public class ScreenResolution {  private int width;  private int height;  //...}//显示屏public class DisplayFeatures {  private String size; // In inches  private ScreenResolution resolution;  //...}//手机public class Mobile {  private long id;  private String brand;  private String name;  private DisplayFeatures displayFeatures;  //...}public static void main(String[] args) {    ScreenResolution resolution = new ScreenResolution(750, 1334);    DisplayFeatures dfeatures = new DisplayFeatures("4.7", resolution);    Mobile mobile = new Mobile(2015001, "Apple", "iPhone 6s", dfeatures);    int mobileWidth = 0;    if (mobile != null) {      DisplayFeatures df = mobile.getDisplayFeatures();      if (df != null) {        ScreenResolution sr = df.getResolution();        if (sr != null) {          return sr.getWidth();        }      }    }    System.out.println("Apple iPhone 6s Screen Width = " + mobileWidth);    //Apple iPhone 6s Screen Width = 750}

例:With Java 8 Optional

//分辨率public class ScreenResolution {  private int width;  private int height;  //...}//显示屏public class DisplayFeaturesOptional {  private String size; // In inches  private Optional<ScreenResolution> resolution;  //...}//手机public class MobileOptional {  private long id;  private String brand;  private String name;  private Optional<DisplayFeaturesOptional> displayFeatures;  //...}public static void main(String[] args) {    ScreenResolution resolution = new ScreenResolution(750, 1334);    DisplayFeaturesOptional dfeatures = new DisplayFeaturesOptional("4.7", Optional.of(resolution));    MobileOptional mobile = new MobileOptional(2015001, "Apple", "iPhone 6s", Optional.of(dfeatures));    int width = mobile.flatMap(MobileOptional::getDisplayFeatures)        .flatMap(DisplayFeaturesOptional::getResolution)        .map(ScreenResolution::getWidth)        .orElse(0);    System.out.println("Apple iPhone 6s Screen Width = " + width);    //Apple iPhone 6s Screen Width = 750}
原创粉丝点击