java8 Optional

1.介绍


Optional 是一个包含或着不包含一个非空值的容器对象。如果一个值存在,isPresent()将会返回true 并且 get() 将会返回所对应的值.

其他的方法依赖于所包含的值是否出现,比如orElse(如果值不存在就返回一个默认值)并且ifPresent()(如果值存在就执行一个代码块)。

2.map

使用Optional 的map() 方法去处理可能为null 的值,而并不做显式的null 类型检查:

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

example:

String value = null;

return Optional.ofNullable(value).map(String::toUpperCase).orElse("NONE");
// returns "NONE"

String value = "something";

return Optional.ofNullable(value).map(String::toUpperCase).orElse("NONE");
// returns "SOMETHING"

3.Null-safe chaining

因为 当它的mapping函数返回null Optional.map() 就会返回一个空的Optional,你能够链式的调用map() 操作来作为空指针安全的一种解决方式。考虑下面的列子:

 String value = foo.getBar().getBaz().toString();

getBar, getBaz, 和toString 可能潜在的抛出NullPointerException 接下来变换一种方式使用Optional来从toString() 中得到值 :

 String value = Optional.ofNullable(foo)
                       .map(Foo::getBar)
                       .map(Bar::getBaz)
                       .map(Baz::toString)
                       .orElse("");

如果任何一个mapping函数返回null 结果都将返回一个空字符串。

Optional.ofNullable(foo)
        .map(Foo::getBar)
        .map(Bar::getBaz)
        .map(Baz::toString)
        .ifPresent(System.out::println);

这个例子仅仅在没有任何mapping函数返回null 的情况下打印该值。

4.Return default value if Optional is empty

不要使用Optional.get() 因为这可能抛出 NoSuchElementException .。Optional.orElse(T) 和 Optional.orElseGet(Supplier

String value = "something";

return Optional.ofNullable(value).orElse("defaultValue");
// returns "something"

return Optional.ofNullable(value).orElseGet(() -> getDefaultValue());
// returns "something" (never calls the getDefaultValue() method)
 String value = null;

return Optional.ofNullable(value).orElse("defaultValue");
// returns "defaultValue"

return Optional.ofNullable(value).orElseGet(() -> getDefaultValue());
// calls getDefaultValue() and returns its results

orElse 和 orElseGet 的关键不同之处在于当Optional为空后者才被调用同时返回的参数被提供给前者(ofNullable),前者是无论Optional是否为空都会被调用。orElse 因此应该被用于常量,并且永远不会提供基于任何排序计算的值。

5.Throw exception if there is no value edit share

使用Optional 方法的orElseThrow() 方法去得到所包含的值或着抛出一个异常,如果值从未被设置。 除了它允许任意的异常类型,这和调用get()很相似 , 这个方法采用一个必须返回将要抛出异常的supplier。
在第一个示例中,方法简单的返回所包含的值:

Optional optional = Optional.of("something");

return optional.orElseThrow(IllegalArgumentException::new);
// returns "something" string

6.Using Optional containers for primitive number types

OptionalDouble, OptionalInt 和 OptionalLong 的工作就像Optional ,但是它们被专门的被设计为包装基本类型:

7.Filter

filter() 被用来表示能够匹配你给定的条件的某些你想要的值。 把他想象成if (!somePredicate(x)) { x = null; }.
代码示例:

String value = null;
Optional.ofNullable(value) // nothing
        .filter(x -> x.equals("cool string"))// this is never run since value is null
        .isPresent(); // false

8.Lazily provide a default value using a Supplier

(使用Supplier懒惰的提供一个默认值)
正常的 orElse 方法需要一个Object 对象作为参数,所以你可能想知道为什么有一个选项来提供Supplier
Consider:

String value = "something";
return Optional.ofNullable(value)
               .orElse(getValueThatIsHardToCalculate()); // returns "something"

它仍然会调用getValueThatIsHardToCalculate() 即使它的结果没有被使用,因为optional非空。
要避免这个“惩罚”,你要提供一个supplier:

String value = "something";
return Optional.ofNullable(value)
               .orElseGet(() -> getValueThatIsHardToCalculate()); // returns "something"

这样 getValueThatIsHardToCalculate() 只有在Optional 为空的时候才会被调用。

9.flatMap

flatMap 和map 很相似, 但是如果你链式的调用返回Optional 的方法,你可能更倾向于使用flatMap ,这样你最终不用使用嵌套的Optionals
Given the following classes:

class Foo {
    Optional<Bar> getBar(){
        return Optional.of(new Bar());
    }
}

class Bar {
}
如果你使用map, 你将得到嵌套的Optional<Optional < Bar >>
Optional<Optional<Bar>> nestedOptionalBar =
    Optional.of(new Foo())
        .map(Foo::getBar);
然而,当使用flatMap ,一个简单的Optional<Bar> 被返回
Optional<Bar> optionalBar =
    Optional.of(new Foo())
        .flatMap(Foo::getBar);

10.例子补充

public class TestOptional {

    public static void main(String[] args) throws InterruptedException {
        Student student = new Student();
        Teacher teacher = new Teacher();
        teacher.name = "zz";
        student.teacher = teacher;
        String name = Optional.of(student).map(Student::getTeacher).map(Teacher::getName).orElse("hh");
        System.out.println(name);
    }

    static class Student {
        private Teacher teacher;

        public Teacher getTeacher() {
            return teacher;
        }

        public void setTeacher(Teacher teacher) {
            this.teacher = teacher;
        }
    }

    static class Teacher {
        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}

例子二:使用map转变数据类型

 public static void main(String[] args) throws InterruptedException {
       Student student = new Student();
       Teacher teacher = new Teacher();
       teacher.name = "zz";
       student.teacher = teacher;
       boolean isZZ = Optional.of(student).map(Student::getTeacher).map(Teacher::getName).map(String::toLowerCase).map(n -> n.equals("zc")).orElse(false);
       System.out.println(isZZ);
   }

例子三:flatMap主要适用于Optional的类型是Optional

public static void main(String[] args) throws InterruptedException {
       Student student = new Student();
       Teacher teacher = new Teacher();
       Optional<Teacher> teacher1 = Optional.of(teacher);
       teacher.name = "zz";
       student.teacher =teacher1;
       boolean isZZ = Optional.of(student).flatMap(Student::getTeacher).map(Teacher::getName).map(String::toLowerCase).map(n -> n.equals("zc")).orElse(false);
       System.out.println(isZZ);
   }

   static class Student {
       private Optional<Teacher> teacher;

       public Optional<Teacher> getTeacher() {
           return teacher;
       }

   }

   static class Teacher {
       private String name;

       public String getName() {
           return name;
       }

       public void setName(String name) {
           this.name = name;
       }
   }

转发:https://blog.csdn.net/lsgqjh/article/details/54564063

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值