optional 订阅
optional 是一个英语单词,形容词,作形容词时意思是“可选择的,随意的”。 展开全文
optional 是一个英语单词,形容词,作形容词时意思是“可选择的,随意的”。
信息
外文名
optional
词    性
形容词
optional单词发音
英[ˈɒpʃənl];美[ˈɑːpʃənl] [1] 
收起全文
精华内容
下载资源
问答
  • 主要介绍了详解Maven optional关键字透彻图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 主要介绍了Java8 Optional原理及用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • Optional

    千次阅读 2019-08-04 10:15:29
    1. Optional中包含一个可以为空的对象,应该在所有可能为空的地方都加上Optional作为返回值。强迫调用方自行判断是否为空。自己因为老是忘记判断是否为null而导致空指针。 2. Optional之前自己最习惯的用法是先判断...

    目前的理解:

    1. Optional中包含一个可以为空的对象,应该在所有可能为空的地方都加上Optional作为返回值。强迫调用方自行判断是否为空。自己因为老是忘记判断是否为null而导致空指针。

    2. Optional之前自己最习惯的用法是先判断是否是ifPresent,然后去进行下一步操作。看了代码之后,发现也可以通过orElse来设定默认值,或者是通过orElseThrow来抛出为空时的异常。

    3. 看了Effective java,容器类的集合不应该返回Optional,直接返回一个空集合更加合适。

    以下为查看源代码学习:

    Optional是一个包含了可能为空的对象的容器对象,如果值存在(isPresent()),可以利用get()获取到

    -----------------------

    第一个对象:

    private static final Optional<?> EMPTY = new Optional<>();

    一个空对象

    -------------------------

    private final T value;

    非空,get()获取到的就是这个对象

    ---------------------------

    private Optional() {
    
    this.value = null;
    
    }

    构造一个空的实例

    -----------------------------

    public static<T> Optional<T> empty() {
    
    @SuppressWarnings("unchecked")
    
    Optional<T> t = (Optional<T>) EMPTY;
    
    return t;
    
    }

    返回一个空的Optional对象,即EMPTY

    ------------------------------

    private Optional(T value) {
    
    this.value = Objects.requireNonNull(value);
    
    }

    这里只能传入一个非空的对象,给value赋值

    ------------------------------

    public static <T> Optional<T> of(T value) {
    
    return new Optional<>(value);
    
    }

    这里只能传入非空对象,返回一个Optional对象,且该对象的isPresent()是为true

    --------------------------------

    public static <T> Optional<T> ofNullable(T value) {
    
    return value == null ? empty() : of(value);
    
    }

    与上面的方法类似,这里传入的是可以为空的对象,如果为空返回empty(),否则与of方法相同

    -----------------------------------

    public T get() {
    
    if (value == null) {
    
    throw new NoSuchElementException("No value present");
    
    }
    
    return value;
    
    }

    获取value,如果为空,跑出异常,否则返回value。

    补充:

    @NotNull

    @Contract(pure=true):

    可参考文档

    https://ice1000.org/2017/01/07/JBAnnotations2/

    例子:

    @NotNull

    @Contract(value = "_, _ -> !null", pure = true)

    返回值为非null,因此@NotNull,

    不管传进来任何值,都不会返回null,因此value是_, _ -> !null,pure=true说明是纯函数。纯函数这里理解为,对于特定的输入,都将产生对应的唯一输出,且不会影响别的东西。

    -------------------------------------

    public boolean isPresent() {
    
    return value != null;
    
    }

    判断value是否为null

    ---------------------------------------

    public void ifPresent(Consumer<? super T> consumer) {
    
    if (value != null)
    
    consumer.accept(value);
    
    }

    如果value不存在,调用传入的consumer,

    补充:

    Consumer接口:

    void accept(T t);

    调用accept方法

    default Consumer<T> andThen(Consumer<? super T> after) {

    Objects.requireNonNull(after);

    return (T t) -> { accept(t); after.accept(t); };

    }

    传入的after不能为空,先调用默认的accept,然后调用after实现的accept方法

    Consumer接口上有个注解:@FunctionalInterface

    https://www.cnblogs.com/chenpi/p/5890144.html

    函数式接口,即接口里边只有一个抽象方法,用于编译级错误检查,接口不符合函数式接口定义,就会报错。函数式接口里边还可以包含默认方法、静态方法、java.lang.Object里边的public方法

    ---------------------------------------------------

    public Optional<T> filter(Predicate<? super T> predicate) {
    
    Objects.requireNonNull(predicate);
    
    if (!isPresent())
    
    return this;
    
    else
    
    return predicate.test(value) ? this : empty();
    
    }

    如果value不为null切符合predicate,返回这个Optional对象,否则返回empty()

    -----------------------------------------------------

    public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
    
    Objects.requireNonNull(mapper);
    
    if (!isPresent())
    
    return empty();
    
    else {
    
    return Optional.ofNullable(mapper.apply(value));
    
    }
    
    }

    如果value不为null,调用传入的mapper方法,然后返回Optional.ofNullable(mapper结果),否则返回empty();

    --------------------------------------------------

    public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
    
    Objects.requireNonNull(mapper);
    
    if (!isPresent())
    
    return empty();
    
    else {
    
    return Objects.requireNonNull(mapper.apply(value));
    
    }
    
    }

    这个方法与上一个类似,但是mapper本身的返回就是在optional中了。

    --------------------------------------------------------

    public T orElse(T other) {
    
    return value != null ? value : other;
    
    }

    传入参数非空,返回也非空,value不为null返回value,value为null,返回输入的other

    -------------------------------------------------------

    public T orElseGet(Supplier<? extends T> other) {
    
    return value != null ? value : other.get();
    
    }

    与上一个方法类似,但是传入的是实现了接口Supplier的

    ----------------------------------------------------

    public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
    
    if (value != null) {
    
    return value;
    
    } else {
    
    throw exceptionSupplier.get();
    
    }
    
    }

    value为null抛出异常,否则返回value

    ---------------------------------------------

    @Override
    
    public boolean equals(Object obj) {
    
    if (this == obj) {
    
    return true;
    
    }
    
    if (!(obj instanceof Optional)) {
    
    return false;
    
    }
    
    Optional<?> other = (Optional<?>) obj;
    
    return Objects.equals(value, other.value);
    
    }

    相等

    其他方法略。

    展开全文
  • 我们知道 Java 8 增加了一些很有用的 API, 其中一个就是 Optional,下面这篇文章主要给大家介绍了关于Java8中Optional的一些常见错误用法的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
  • optional_c C语言中Rust的Optional类型的实现 这是一个可怕的概念证明,试图通过宏的魔力将Rust的Optional Type(在许多其他语言中)的功能引入C。 您可以将其与标准类型,您自己的类型,结构定义一起使用,用法是...
  • 标准可选 c++17 草案中 std::optional 接口的实现
  • 主要介绍了还在用if(obj!=null)做非空判断,带你快速上手Optional,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 主要给大家介绍了关于Java如何使用Optional与Stream取代if判空逻辑(JDK8以上)的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Java具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
  • Optional可以让你的代码具有可读性,且会避免出现空指针异常。下面这篇文章主要给大家介绍了关于利用Java8 Optional如何避免空指针异常的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下。
  • import { optional } from "optional-chain" ; type User = { name ?: { first : string } } const user : User = getUser ( ) ; // { name: null } const optionalUser = optional ( user ) ; optionalUser . k...
  • std::optional单头实现,具有功能样式的扩展和对引用的支持。 lang + GCC: MSVC: std::optional是表示可能具有或不具有值的对象的首选方式。 不幸的是,将可能会或可能不会产生值的许多计算链接在一起可能是...
  • npm i @eastbanctech/ts-optional API文档 文档可。 用法示例 可以使用以下方法创建可选实例: Optional.ofNullable(someValue) Optional.of(nonNullableValue) Optional.empty() 可以像这样使用: const ...
  • optional lite:C++17-like optional 的单文件头版本,C++98、C++11 和更高版本的可为空对象 内容 std::optionaloptional lite 和Boost.Optional 的比较 报告与 构建测试 实施说明 可选的其他实现 注释和参考 ...
  • Boost.Optional的教育性C ++ 20实现,也是-C ++ 20 std :: optional。 boost20.optional Boost.Optional的教育性C ++ 20实现,也是-C ++ 20 std :: optional。 此实现的主要动机是探索以下C ++ 20功能:概念受限的...
  • optional-stock Chrome自选股小助手 价格实时更新。 可设置价格区间,Chrome 桌面 notification 提醒
  • 本文我们介绍了Java 9 Optional Api新增的三个方法。or方法在Optional为空时返回Optional对象。 ifPresentOrElse()在值存在时执行Consumer参数,反之执行另一个参数回调参数。感兴趣的朋友跟随小编一起看看吧
  • 我们知道 Java 8 增加了一些很有用的 API, 其中一个是 Optional. 如果对它不稍假探索, 只是轻描淡写的认为它可以优雅的解决 NullPointException 的问题, 于是代码开始这么写了  Optional<User> user = ……  ...
  • 主要给大家介绍了关于Java8中Optional类型和Kotlin中可空类型的使用对比,文中通过示例代码给大家介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
  • optional

    2018-07-05 17:35:18
    从 Java 8 引入的一个很有趣的特性是 Optional 类。Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) —— 每个 Java 程序员都非常了解的异常。本质上,这是一个包含有可选值的包装类,这...
    从 Java 8 引入的一个很有趣的特性是 Optional  类。Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) —— 每个 Java 程序员都非常了解的异常。

    本质上,这是一个包含有可选值的包装类,这意味着 Optional 类既可以含有对象也可以为空。

    Optional 是 Java 实现函数式编程的强劲一步,并且帮助在范式中实现。但是 Optional 的意义显然不止于此。



    我们从一个简单的用例开始。在 Java 8 之前,任何访问对象方法或属性的调用都可能导致 NullPointerException

    String isocode = user.getAddress().getCountry().getIsocode().toUpperCase();

    在这个小示例中,如果我们需要确保不触发异常,就得在访问每一个值之前对其进行明确地检查:

    if (user != null) {
        Address address = user.getAddress();
        if (address != null) {
            Country country = address.getCountry();
            if (country != null) {
                String isocode = country.getIsocode();
                if (isocode != null) {
                    isocode = isocode.toUpperCase();
                }
            }
        }
    }

    你看到了,这很容易就变得冗长,难以维护。

    为了简化这个过程,我们来看看用 Optional  类是怎么做的。从创建和验证实例,到使用其不同的方法,并与其它返回相同类型的方法相结合,下面是见证 Optional  奇迹的时刻。



    创建 Optional  实例

    重申一下,这个类型的对象可能包含值,也可能为空。你可以使用同名方法创建一个空的 Optional。

    @Test(expected = NoSuchElementException.class)
    public void whenCreateEmptyOptional_thenNull() {
        Optional<User> emptyOpt = Optional.empty();
        emptyOpt.get();
    }

    毫不奇怪,尝试访问 emptyOpt 变量的值会导致 NoSuchElementException

    你可以使用  of() 和 ofNullable() 方法创建包含值的 Optional。两个方法的不同之处在于如果你把 null 值作为参数传递进去,of() 方法会抛出 NullPointerException

    @Test(expected = NullPointerException.class)
    public void whenCreateOfEmptyOptional_thenNullPointerException() {
        Optional<User> opt = Optional.of(user);
    }

    你看,我们并没有完全摆脱 NullPointerException。因此,你应该明确对象不为 null  的时候使用 of()

    如果对象即可能是 null 也可能是非 null,你就应该使用 ofNullable() 方法:

    Optional<User> opt = Optional.ofNullable(user);


    访问 Optional 对象的值

    从 Optional 实例中取回实际值对象的方法之一是使用 get() 方法:

    @Test
    public void whenCreateOfNullableOptional_thenOk() {
        String name = "John";
        Optional<String> opt = Optional.ofNullable(name);
    
        assertEquals("John", opt.get());
    }

    不过,你看到了,这个方法会在值为 null 的时候抛出异常。要避免异常,你可以选择首先验证是否有值:

    @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());
    }

    检查是否有值的另一个选择是 ifPresent() 方法。该方法除了执行检查,还接受一个Consumer(消费者) 参数,如果对象不是空的,就对执行传入的 Lambda 表达式:

    opt.ifPresent( u -> assertEquals(user.getEmail(), u.getEmail()));

    这个例子中,只有 user 用户不为 null 的时候才会执行断言。

    接下来,我们来看看提供空值的方法。



    返回默认值

    Optional 类提供了 API 用以返回对象值,或者在对象为空的时候返回默认值。

    这里你可以使用的第一个方法是 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());
    }

    这里 user 对象是空的,所以返回了作为默认值的 user2

    如果对象的初始值不是 null,那么默认值会被忽略:

    @Test
    public void whenValueNotNull_thenIgnoreDefault() {
        User user = new User("john@gmail.com","1234");
        User user2 = new User("anna@gmail.com""1234");
        User result = Optional.ofNullable(user).orElse(user2);
    
        assertEquals("john@gmail.com", result.getEmail());
    }

    第二个同类型的 API 是 orElseGet() —— 其行为略有不同。这个方法会在有值的时候返回值,如果没有值,它会执行作为参数传入的 Supplier(供应者) 函数式接口,并将返回其执行结果:

    User result = Optional.ofNullable(user).orElseGet( () -> user2);


    orElse() 和 orElseGet() 的不同之处

    乍一看,这两种方法似乎起着同样的作用。然而事实并非如此。我们创建一些示例来突出二者行为上的异同。

    我们先来看看对象为空时他们的行为:

    @Test
    public void givenEmptyValue_whenCompare_thenOk() {
        User user = null
        logger.debug("Using orElse");
        User result = Optional.ofNullable(user).orElse(createNewUser());
        logger.debug("Using orElseGet");
        User result2 = Optional.ofNullable(user).orElseGet(() -> createNewUser());
    }
    
    private User createNewUser() {
        logger.debug("Creating New User");
        return new User("extra@gmail.com""1234");
    }

    上面的代码中,两种方法都调用了 createNewUser() 方法,这个方法会记录一个消息并返回 User 对象。

    代码输出如下:

    Using orElse
    Creating New User
    Using orElseGet
    Creating New User

    由此可见,当对象为空而返回默认对象时,行为并无差异。



    我们接下来看一个类似的示例,但这里 Optional  不为空:

    @Test
    public void givenPresentValue_whenCompare_thenOk() {
        User user = new User("john@gmail.com""1234");
        logger.info("Using orElse");
        User result = Optional.ofNullable(user).orElse(createNewUser());
        logger.info("Using orElseGet");
        User result2 = Optional.ofNullable(user).orElseGet(() -> createNewUser());
    }

    这次的输出:

    Using orElse
    Creating New User
    Using orElseGet

    这个示例中,两个 Optional  对象都包含非空值,两个方法都会返回对应的非空值。不过,orElse() 方法仍然创建了 User 对象。与之相反,orElseGet() 方法不创建 User 对象。

    在执行较密集的调用时,比如调用 Web 服务或数据查询,这个差异会对性能产生重大影响



    返回异常

    除了 orElse() 和 orElseGet() 方法,Optional 还定义了 orElseThrow() API —— 它会在对象为空的时候抛出异常,而不是返回备选的值:

    @Test(expected = IllegalArgumentException.class)
    public void whenThrowException_thenOk() {
        User result = Optional.ofNullable(user)
          .orElseThrow( () -> new IllegalArgumentException());
    }

    这里,如果 user 值为 null,会抛出 IllegalArgumentException

    这个方法让我们有更丰富的语义,可以决定抛出什么样的异常,而不总是抛出 NullPointerException

    现在我们已经很好地理解了如何使用 Optional,我们来看看其它可以对 Optional 值进行转换和过滤的方法。



    转换值

    有很多种方法可以转换 Optional  的值。我们从 map() 和 flatMap() 方法开始。

    先来看一个使用 map() API 的例子:

    @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());
    }

    map() 对值应用(调用)作为参数的函数,然后将返回的值包装在 Optional 中。这就使对返回值进行链试调用的操作成为可能 —— 这里的下一环就是 orElse()

    相比这下,flatMap() 也需要函数作为参数,并对值调用这个函数,然后直接返回结果。

    下面的操作中,我们给 User 类添加了一个方法,用来返回 Optional

    public class User {    
        private String position;
    
        public Optional<String> getPosition() {
            return Optional.ofNullable(position);
        }
    
        //...
    }

    既然 getter 方法返回 String 值的 Optional,你可以在对 User 的 Optional 对象调用 flatMap() 时,用它作为参数。其返回的值是解除包装的 String 值:

    @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());
    }


    过滤值

    除了转换值之外,Optional  类也提供了按条件“过滤”值的方法。

    filter() 接受一个 Predicate 参数,返回测试结果为 true 的值。如果测试结果为 false,会返回一个空的 Optional

    来看一个根据基本的电子邮箱验证来决定接受或拒绝 User(用户) 的示例:

    @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());
    }

    如果通过过滤器测试,result 对象会包含非空值。

    Optional 类的链式方法

    为了更充分的使用 Optional,你可以链接组合其大部分方法,因为它们都返回相同类似的对象。

    我们使用 Optional  重写最早介绍的示例。

    首先,重构类,使其 getter 方法返回 Optional 引用:

    public class User {
        private Address address;
    
        public Optional<Address> getAddress() {
            return Optional.ofNullable(address);
        }
    
        // ...
    }
    public class Address {
        private Country country;
    
        public Optional<Country> getCountry() {
            return Optional.ofNullable(country);
        }
    
        // ...
    }

    上面的嵌套结构可以用下面的图来表示:

    optional nested

    现在可以删除 null 检查,替换为 Optional 的方法:

    @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");
    }

    上面的代码可以通过方法引用进一步缩减:

    String result = Optional.ofNullable(user)
      .flatMap(User::getAddress)
      .flatMap(Address::getCountry)
      .map(Country::getIsocode)
      .orElse("default");

        结果现在的代码看起来比之前采用条件分支的冗长代码简洁多了。

    展开全文
  • JAVA Optional类用法分享

    2020-08-28 13:37:00
    本篇文章主要给大家分析了JAVA中Optional类用法以及代码分析,跟着小编学习下吧。
  • 我们知道 Java 8 增加了一些很有用的 API, 其中一个就是 Optional,下面这篇文章主要给大家介绍了关于如何正确使用Java8中Optional机制的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面来...
  • 主要介绍了Swift中Optional值的链式调用学习笔记,Optional链是Swift入门学习中的基础知识,需要的朋友可以参考下
  • Java 8 已经发布很久了,很多报道表明Java 8 是一次重大的...下面这篇文章主要给大家介绍了关于Java8中新特性Optional、接口中默认方法和静态方法的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下。
  • optional详解

    千次阅读 2019-09-19 10:59:15
    public class Test { public static void main(String[] args) { People people = new People();... Optional<People> p = Optional.ofNullable(people); String name = p.flatMap(People::getCa...
    public class Test {
    
      public static void main(String[] args) {
        People people = new People();
        Optional<People> p = Optional.ofNullable(people);
        String name = p.flatMap(People::getCar).flatMap(Car::getInsurence).map(Insurence::getName).orElse("string");
      }
    
    }
    
    class People{
      private Optional<Car> car;
    
      public Optional<Car> getCar() {
        return car;
      }
    }
    
    class Car{
      private Optional<Insurence> insurence;
    
      public Optional<Insurence> getInsurence() {
        return insurence;
      }
    }
    
    class Insurence{
      String name;
      public String getName() {
        return name;
      }
    }

     

    1.Optional简述 

    到目前为止,著名的NullPointerException是导致Java应用程序失败的最常见原因。过去,为了解决空指针异常,Google公司著名的Guava项目引入了Optional类,Guava通过使用检查空值的方式来防止代码污染,它鼓励程序员写更干净的代码。如今,受到Google Guava的启发,Optional类已经成为Java 8类库的一部分。


    Optional:按照字面英文解释为“可选的” 意思,但此处的语义是指某个值可能有也可能没有(null)

    Optional 被定义为一个简单的容器,其值可能是null或者不是null。在Java 8之前一般某个函数应该返回非空对象但是偶尔却可能返回了null,而在Java 8 以后,不推荐你返回null而是返回Optional。

     

    Optional英文文档地址:http://docs.oracle.com/javase/8/docs/api/java/util/Optional.html

     

    2.对 Optional 应用的理解

    Java 8借鉴了Scala和Haskell,提供了一个新的Optional模板,可以用它来封装可能为空的引用。但它绝不是终结空指针,更多只是使API的设计者可以在代码层面声明一个方法可能会返回空值,调用方应该注意这种情况。因此,这只对新的API有效,前提是调用者不要让引用逃逸出封装类,否则引用可能会在外面被不安全的废弃掉。

    个人对这个新的特性是又爱又恨。一方面,空指针是一个大问题,只要能解决这个问题的东西笔者都欢迎。但另一方面,个人对它是否能担此重任执怀疑的态度。这是由于使用它需要全公司的集体努力,短期内很难会有见效。若非大力地推广使用,很可能会功亏一篑。

     

    3.Optional的优点

    1)显式的提醒你需要关注null的情况,对程序员是一种字面上的约束
    2)将平时的一些显式的防御性检测给标准化了,并提供一些可串联操作

    3)解决null会导致疑惑的概念

    eg:Map里面的key==null的情况,以及value==null的情况

     

    4.Optional类

     

    4.1 Optional类的官方描述

     

     

    A container object which may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value.

     

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

     

    4.2 Optional的简单使用

     

    Optional类的包名:java.util.Optional<T>

     

    为了防止抛出java.lang.NullPointerException 异常,我们经常会写出这样的代码:

     

    [java]  view plain  copy

     

    1. Student student = person.find("Lucy");  
    2.         if (student != null) {  
    3.             student.doSomething();  
    4.         }  

    使用Optional的代码写法:

     

     

    [java]  view plain  copy

     

    1. Student student = person.find("Lucy");  
    2.         if (student.isPresent()) {  
    3.             student.get().doSomething();  
    4.         }  
    说明:如果isPresent()返回false,说明这是个空对象;否则,我们就可以把其中的内容取出来做相应的操作了。
    单从代码量上来说,Optional的代码量并未减少,甚至比原来的代码还多。但好在,你绝对不会忘记判空,因为这里我们得到的不是Student类的对象,而是Optional。

     

     

    4.3Optional类的主要方法

    1) of(T value)

    为非null的值创建一个Optional。

    of()方法通过工厂方法创建Optional类。需要注意,创建对象时传入的参数不能为null。如果传入参数为null,则抛出NullPointerException 。

    eg:

     

    [java]  view plain  copy

     

    1. //调用工厂方法创建Optional实例  
    2.     Optional<String> myValue = Optional.of("OptionalTest");  
    3.     //传入参数为null,抛出NullPointerException.  
    4.     Optional<String> someNull = Optional.of(null);  

     

     

    2) ofNullable(T value)

    为指定的值创建一个Optional,如果指定的值为null,则返回一个空的Optional。

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

    eg:

     

    [java]  view plain  copy

     

    1. //下面创建了一个不包含任何值的Optional实例  
    2. //eg:值为'null'  
    3. Optional empty = Optional.ofNullable(null);  

     

     

    3) isPresent()

    如果值存在返回true,否则返回false。

    eg:

     

    [java]  view plain  copy

     

    1. //isPresent()方法用来检查Optional实例中是否包含值  
    2. if (myValue.isPresent()) {  
    3. //在Optional实例内调用get()返回已存在的值  
    4. System.out.println(myValue.get());//输出OptionalTest }  
     

     

    4) get()

    如果Optional有值则将其返回,否则抛出异常 NoSuchElementException。

    在上面的示例中,get方法用来得到Optional实例中的值。下面是一个抛出NoSuchElementException的示例:

    eg:

     

    [java]  view plain  copy

     

    1. //执行下面的代码会输出:No value present   
    2.         try {  
    3.           //在空的Optional实例上调用get(),抛出NoSuchElementException  
    4.           System.out.println(empty.get());  
    5.         } catch (NoSuchElementException ex) {  
    6.           System.out.println(ex.getMessage());  
    7.         }  
     

     

    5) ifPresent(Consumer<? super T> consumer)

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

    要理解ifPresent()方法,首先需要了解Consumer类。简单地说,Consumer类包含一个抽象方法。该抽象方法对传入的值进行处理,但没有返回值。Java8支持不用接口直接通过lambda表达式传入参数。

    如果Optional实例有值,调用ifPresent()可以接受接口段或lambda表达式。

    eg:

     

    [java]  view plain  copy

     

    1. //ifPresent()方法接受lambda表达式作为参数。  
    2.         //lambda表达式对Optional的值调用consumer进行处理。  
    3.         myValue.ifPresent((value) -> {  
    4.           System.out.println("The length of the value is: " + value.length());  
    5.         });  

     

     

    6) orElse(T other)

    如果有值则将其返回,否则返回指定的其它值。
    如果Optional实例有值则将其返回,否则返回orElse方法传入的参数。即:参数other为默认返回值

    eg:

     

    [java]  view plain  copy

     

    1. //如果值不为null,orElse方法返回Optional实例的值。  
    2.         //如果为null,返回传入的消息。  
    3.         //输出:There is no value present!  
    4.         System.out.println(empty.orElse("There is no value present!"));  
    5.         //输出:OptionalTest  
    6.         System.out.println(myValue.orElse("There is some value!"));  

     

     

    7) orElseGet(Supplier<? extends T> other)

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

    eg:

     

    [java]  view plain  copy

     

    1. //orElseGet可以接受一个lambda表达式生成默认值。  
    2.         //输出:Default Value  
    3.         System.out.println(empty.orElseGet(() -> "Default Value"));  
    4.         //输出:OptionalTest  
    5.         System.out.println(myValue.orElseGet(() -> "Default Value"));  

     

     

    8) orElseThrow(Supplier<? extends X> exceptionSupplier)

    如果有值则将其返回,否则抛出supplier接口创建的异常。
    在orElseGet()方法中,我们传入一个Supplier接口。然而,在orElseThrow中我们可以传入一个lambda表达式或方法,如果值不存在就抛出异常。

    eg:

     

    [java]  view plain  copy

     

    1. try {  
    2.           //orElseThrow与orElse方法类似。与返回默认值不同,  
    3.           //orElseThrow会抛出lambda表达式或方法生成的异常   
    4.            
    5.           empty.orElseThrow(ValueAbsentException::new);  
    6.         } catch (Throwable ex) {  
    7.           //输出: No value present in the Optional instance  
    8.           System.out.println(ex.getMessage());  
    9.         }  

     

    [java]  view plain  copy

     

    1. class ValueAbsentException extends Throwable {  
    2.    
    3.   public ValueAbsentException() {  
    4.     super();  
    5.   }  
    6.    
    7.   public ValueAbsentException(String msg) {  
    8.     super(msg);  
    9.   }  
    10.    
    11.   @Override  
    12.   public String getMessage() {  
    13.     return "No value present in the Optional instance";  
    14.   }  
    15. }  
     

     

     

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

    如果有值,则对其执行调用mapping函数得到返回值。如果返回值不为null,则创建包含mapping返回值的Optional作为map方法返回值,否则返回空Optional。
    map方法用来对Optional实例的值执行一系列操作。通过一组实现了Function接口的lambda表达式传入操作。

    eg:

     

    [java]  view plain  copy

     

    1. //map方法执行传入的lambda表达式参数对Optional实例的值进行修改。  
    2. //为Lambda表达式的返回值创建新的Optional实例作为map方法的返回值。  
    3. Optional<String> upperName = myValue.map((value) -> value.toUpperCase());  
    4. System.out.println(upperName.orElse("No value found"));  
     

     

    10) flatMap(Function<? super T,Optional<U>> mapper)

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

    flatMap方法与map方法类似,区别在于mapping函数的返回值不同。map方法的mapping函数返回值可以是任何类型T,而flatMap方法的mapping函数必须是Optional。

    eg:

    下面参照map函数,使用flatMap重写的示例

     

    [java]  view plain  copy

     

    1. //map方法中的lambda表达式返回值可以是任意类型,在map函数返回之前会包装为Optional。   
    2. //但flatMap方法中的lambda表达式返回值必须是Optionl实例。   
    3. upperName = myValue.flatMap((value) -> Optional.of(value.toUpperCase()));  
    4. System.out.println(upperName.orElse("No value found"));  
     

     

    11) filter(Predicate<? super T> predicate)

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


    filter个方法通过传入限定条件对Optional实例的值进行过滤。

    对于filter函数我们可以传入实现了Predicate接口的lambda表达式。

    eg:

     

    [java]  view plain  copy

     

    1. //filter方法检查给定的Option值是否满足某些条件。  
    2.     //如果满足则返回同一个Option实例,否则返回空Optional。  
    3.     Optional<String> longName = myValue.filter((value) -> value.length() > 6);  
    4.     System.out.println(longName.orElse("The name is less than 6 characters"));//输出OptionalTest  
    5.        
    6.     //另一个例子是Optional值不满足filter指定的条件。  
    7.     Optional<String> anotherName = Optional.of("Test");  
    8.     Optional<String> shortName = anotherName.filter((value) -> value.length() > 6);  
    9.     //输出:name长度不足6字符  
    10.     System.out.println(shortName.orElse("The name is less than 6 characters"));  
     

     

    12) empty()

    返回一个空Optional实例。

    eg:

     

    [java]  view plain  copy

     

    1. Optional.<String>empty(); // 返回一个空Optional<String>  

     

     

    Note:

    Optional有这么多方法,那Optional的初衷是什么?而且Optional也是一个对象,所以它本身也有可能是null,这可如何是好。所以,个人认为,Optional比较适用的地方是作为返回值,这样可以给使用者一个善意的提醒。

     

    4.4  map 与 flatMap 的区别

     

    map(mapper) 与 flatMap(mapper) 功能上基本是一样的,只是最后的返回值不一样。map(mapper)方法中的mapper可以返回任意类型,但是flatMap(mapper)方法中的mapper只能返回Optional类型。

    如果mapper返回结果result的不是null,那么map就会返回一个Optional,但是 flatMap不会对result进行任何包装。

    eg:

     

    [java]  view plain  copy

     

    1. Optional<String> o;  
    2. o.map((value)->Optional.of(value)) //返回的类型是Optional<Optional<String>>  
    3. o.flatMap((value)->Optional.of(value)) //返回的类型是Optional<String>  
     

     

    4.5 Optional应用示例:

    Note:测试的时候最好是新建一个java项目(或者直接用eclipse测试),因为Android项目目前不完全支持java8的新特性,需要配置很多东西,也一样容易出现各种问题。

     

    [java]  view plain  copy

     

    1. import java.util.NoSuchElementException;  
    2. import java.util.Optional;  
    3.   
    4. public class OptionalTest {  
    5.   
    6.     public static void main(String[] args) {  
    7.          // 创建Optional  
    8.         String mayBeNull = null;  
    9.         Optional<String> opt1 = Optional.of(" Hello! ");  
    10.         Optional<String> opt2 = Optional.ofNullable(mayBeNull);  
    11.         Optional<String> opt3 = Optional.empty();  
    12.         opt1.ifPresent(System.out::println); // " Hello! "  
    13.         opt2.ifPresent(System.out::println);  
    14.         opt3.ifPresent(System.out::println);  
    15.   
    16.         //方法测试示例  
    17.         ofTest();  
    18.         ofNullableTest();  
    19.         isPresentTest();  
    20.         ifPresentTest();  
    21.         orElseTest();  
    22.         orElseGetTest();  
    23.         mapTest();  
    24.         flatMapTest();  
    25.         filterTest();  
    26.   
    27.     }  
    28.       
    29.     /** 
    30.      * of后面接给optional设置的值 但是不能为空 如果为空会报空指针异常 
    31.      */  
    32.     public static void ofTest() {  
    33.         Optional<String> optional = Optional.of("123");  
    34.         System.out.println(optional.get());  
    35.         try {  
    36.             optional = Optional.of(null);  
    37.             System.out.println("null值--"+optional.get());  //get方法是获取optional的值 类型取决于声明的时候  
    38.         } catch (NullPointerException e) {  
    39.             System.out.println("空指针异常");  
    40.         }  
    41.     }  
    42.   
    43.     /** 
    44.      * ofNullable 和of类似 但是ofNullable可以设置null值  如果是Null值得话取值会报NoSuchElementException 异常 
    45.      */  
    46.     public static void ofNullableTest() {  
    47.         Optional<String> optional = Optional.ofNullable("123");  
    48.         System.out.println(optional.get());  
    49.         try {  
    50.             optional = Optional.ofNullable(null);  
    51.             System.out.println("null值---"+optional.get());  
    52.         } catch (NoSuchElementException e) {  
    53.             System.out.println("NoSuchElementException 异常");  
    54.         }  
    55.     }  
    56.   
    57.     /** 
    58.      * ifPresent用来判断optional中有没有值存在 如果有则为真 
    59.      */  
    60.     public static void isPresentTest() {  
    61.         Optional<String> optional = Optional.ofNullable(null);  
    62.         if (optional.isPresent()) {  
    63.             System.out.println(optional.get());  
    64.         } else {  
    65.             System.out.println("值为空");  
    66.         }  
    67.     }  
    68.   
    69.     /** 
    70.      * ifPresent和isPresent类似 只不过它支持λ表达式 
    71.      */  
    72.     public static void ifPresentTest() {  
    73.         Optional<String> optional = Optional.ofNullable("123");  
    74.         optional.ifPresent(var -> {  
    75.             System.out.println(var);  
    76.         });  
    77.     }  
    78.   
    79.     /** 
    80.      * orElse方法,如果值为空的话会用参数中的值去替换 即设置默认值 
    81.      */  
    82.     public static void orElseTest() {  
    83.         Optional<String> optional = Optional.ofNullable("123");  
    84.         System.out.println(optional.orElse("有没有"));  
    85.         optional = Optional.ofNullable(null);  
    86.         System.out.println(optional.orElse("有没有000"));  
    87.     }  
    88.   
    89.     /** 
    90.      * orElseGet方法 和orElse类似 不过此方法接受Supplier接口的实现用来生成默认值 
    91.      */  
    92.     public static void orElseGetTest() {  
    93.         Optional<String> optional = Optional.ofNullable("123");  
    94.         System.out.println(optional.orElseGet(() -> "123456"));  
    95.         optional = Optional.ofNullable(null);  
    96.         System.out.println(optional.orElseGet(() -> "1234567"));  
    97.     }  
    98.   
    99.     /** 
    100.      * map方法  如果有值则会对值进行mapping中的处理 处理结果存在则创建并返回Optional类型的结果 否则返回空 
    101.      */  
    102.     public static void mapTest() {  
    103.         Optional<String> optional = Optional.ofNullable("abc");  
    104.         System.out.println(optional.map(var -> var.toUpperCase()).get());  
    105.     }  
    106.   
    107.     /** 
    108.      * flatMap和map类似 只不过mapping中必须返回Option类型的数据 
    109.      */  
    110.     public static void flatMapTest() {  
    111.         Optional<String> optional = Optional.ofNullable("abc");  
    112.         System.out.println(optional.flatMap(var -> Optional.of(var.toUpperCase())).get());  
    113.     }  
    114.   
    115.     /** 
    116.      * filter对optional进行过滤,mapping中为过滤的条件  如果不满足条件 返回一个为空的Optional 
    117.      */  
    118.     public static void filterTest() {  
    119.         try {  
    120.             Optional<String> optional = Optional.ofNullable("一二三四五六七八");  
    121.             System.out.println(optional.filter(var -> var.length() > 6).get());  
    122.             System.out.println(optional.filter(var -> var.length() < 6).get());  
    123.         } catch (NoSuchElementException e) {  
    124.             System.out.println("optional的值为空");  
    125.         }  
    126.     }  
    127.   
    128. }  

     

    展开全文
  • 2.1 创建Optional容器 21 2.2 容器简单方法 22 2.3 容器进阶方法 23 1.3.5 ifPresent方法 23 1.3.6 orElseGet和orElseThrow方法 23 1.3.7 filter方法 24 1.3.8 map方法 24 1.3.9 flatMap方法 25 2.4 总结 25
  • sojo-optional-0.5.0

    2015-01-21 13:14:16
    Download sojo-optional-0.5.0.jar META-INF/MANIFEST.MF net.sf.sojo.common.CompareResult.class net.sf.sojo.common.GenericComparator.class net.sf.sojo.common.IterateableUtil.class ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 378,607
精华内容 151,442
关键字:

optional