首页 > 其他分享 >Optional详解

Optional详解

时间:2023-08-18 18:34:15浏览次数:40  
标签:get System 详解 println null Optional out

1.介绍

Optional是Java8引入的一个新的类,它是java.util包下面的一个类。主要目的是为了解决空指针异常问题,它既可以含有对象也可以为空。

2.Optional的使用

2.1:创建一个Optional
如果需要创建一个空的Optional的话,则可以使用Optional的empty()方法。empty方法的代码为:

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

该方法的作用就是返回个空对象,样例代码:

Optional<Object> empty = Optional.empty();
System.out.println(empty.get());

输出结果:
image
可以看出其是没有值得,所以报了个异常,这个异常是get方法进行判断与抛出的。
如果要创建的对象可以明确的确认该对象不为null,那么可以使用Optional的of()方法,但是需要注意的是对象为null是该方法会报一个空指针异常。of的源码为:

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

样例代码为:

System.out.println(Optional.of("5"));
System.out.println(Optional.of(null));

输出结果为:
image
可以从输出结果看出值不为null时则会创建一个有值的实例对象,如果值为null时则会抛出一个空指针异常。
如果要创建的对象不能够确定是否为null的话,则可以使用Optional的ofNullable()方法,这个方法会根据传入的值是否为null来返回实例对象,如果为null的话,则会返回empty(),不为null的话,则会调用of()方法创建实例。其源码为:

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

样例代码如下:

System.out.println(Optional.ofNullable("5"));
System.out.println(Optional.ofNullable(null));

运行结果为:
image
从结果可以看出,当值为null时,ofNullable()方法并不会提示一个空指针异常,而是返回了一个Optional.empty。
2.2:获取Optional的值
Optional获取值的方法为get()方法,但是如果Optional的值为null时,调用get方法则会抛出个NoSuchElementEsception异常。源码为:

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

样例代码如下:

Optional<String> s1 = Optional.ofNullable("测试get方法获取值");
System.out.println(s1.get());
Optional<Object> s2 = Optional.ofNullable(null);
System.out.println(s2.get());

运行结果为:
image
从上面的结果可以看到当Optional的值为null时,调用get方法会抛出一个NoSuchElementException。
从上面get方法的样例可以看出,当Optional的值为null时,直接调用get方法会抛出一个异常,所以这里在调用之前就需要先判断Optional的值是否为null,而判断的则会有两个方法,分别是isPresent()和ifPresent()。源码为:

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

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

样例代码为:

Optional<String> s1 = Optional.ofNullable("测试get方法获取值");
System.out.println(s1.isPresent());
if (s1.isPresent()) {
    System.out.println(s1.get());
} else {
    System.out.println("s1的值为null");
}
s1.ifPresent(u -> System.out.println(u.replace("get", "java")));
Optional<String> s2 = Optional.ofNullable(null);
System.out.println(s2.isPresent());
if (s2.isPresent()) {
    System.out.println(s2.get());
} else {
    System.out.println("s2的值为null");
}
s2.ifPresent(u -> System.out.println(u.replace("get", "java")));

运行结果为:
image
从上面的样例可以看出isPresent()方法是判断该参数值是否为null,不为null就返回true,为null则返回false。而ifPresent()方法则是先看Optional的值是否为null,如果不为null则进行后面括号里的操作,如果为null则不进行处理。
2.3:filter过滤值
Optional的filter()方法是一个过滤方法,其中的参数是Predicate断言型函数式接口。源码为:

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

样例代码为:

Optional<String> s = Optional.ofNullable("10");
System.out.println(s.filter(u -> u.equals("5")));
System.out.println(s.filter(u -> u.equals("10")));

运行结果为:
image
从上面样例的结果可以看出,filter是进行一个过滤函数,当该Optional的值符合过滤条件时,则会返回该Optional,如果不符合时,则会返回Optional.empty。
2.4:map转换值
Optional的map函数可以对已有的Optional的值进行一些转换,当其值不存在时,则会直接返回empty,值存在时才会进行相关的处理。主要的方法有map()方法和flatMap()方法,不过flatMap()方法与map()方法也是有区别的,flatMap()方法的 参数类型需要转化为Optional,而map()方法的参数类型为值,其源码为:

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



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

样例代码为:

Optional<Object> s = Optional.ofNullable("10");
System.out.println(s.get() instanceof Integer);
System.out.println(s.map(u -> Integer.valueOf(u.toString())).get() instanceof Integer);
Optional<Object> s2 = Optional.ofNullable(null);
System.out.println(s2.map(u -> Integer.valueOf(u.toString())));

Optional<Object> s3 = Optional.ofNullable("10");
System.out.println(s3.get() instanceof Integer);
System.out.println(s3.flatMap(u -> Optional.ofNullable(Integer.valueOf(u.toString()))).get() instanceof Integer);
Optional<Object> s4 = Optional.ofNullable(null);
System.out.println(s4.flatMap(u -> Optional.ofNullable(Integer.valueOf(u.toString()))));

运行结果为:
image
从结果可以看出其将值转化为了Integer类型,如果值不存在的话则会返回一个empty。
2.5:默认操作
Optional的默认操作有三个方法,分别是orElse(),orElseGet(),orElseThrow()这三个方法,这三个方法都是当Optional的值为null时会进行一些默认操作,不过这三个方法也是有些区别的,orElse()方法返回的值是直接传入的参数值,orElseGet()方法返回的值则是通过Supplier来获取的,而orElseThrow()方法则是会直接抛出一个异常。他们三个方法的源码如下:

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


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


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

样例代码:

Optional<Object> s = Optional.ofNullable("10");
Optional<Object> s1 = Optional.ofNullable(null);

System.out.println(s.orElse("No Value!"));
System.out.println(s1.orElse("No Value!"));
System.out.println(s.orElseGet(() -> new String("No Value")));
System.out.println(s1.orElseGet(() -> new String("No Value")));
System.out.println(s.orElseThrow(() -> new RuntimeException("s参数没有值")));
System.out.println(s1.orElseThrow(() -> new RuntimeException("s1参数没有值")));

运行结果为:
image
从上面的结果可以看出,这几个orElse(),orElseGet(),orElseThrow()方法只是当Optional的值为null时才会进行后面的操作,如果不为null,则还是返回Optional的值

标签:get,System,详解,println,null,Optional,out
From: https://www.cnblogs.com/mcj123/p/17629386.html

相关文章

  • 技术分享| WebRTC之SDP详解
    一,什么是SDPWebRTC是WebReal-TimeCommunication,即网页实时通信的缩写,是RTC协议的一种Web实现,项目由Google开源,并和IETF和W3C制定了行业标准。WebRTC是点对点通讯,他的通话建立需要交换媒体信息才能建立,媒体信息的载体就是SDP。SDP(SessionDescriptionProtocol)是......
  • 融媒行业落地客户旅程编排,详解数字化用户运营实战
    移动互联网时代是流量红利的时代,企业常用低成本的方式进行获客,“增长黑客”的概念大范围传播。与此同时,机构媒体受到传播环境的影响,也开始启动全行业的媒体融合转型。在此背景下,2015年神策数据成立,核心解决的是帮助客户通过数据分析实现更好的增长。2020年之后数字化转型的大趋势......
  • 软件测试|Linux三剑客之grep命令详解
    简介grep是一款在Linux和类Unix系统中广泛使用的文本搜索工具。它的名字来源于GlobalRegularExpressionPrint(全局正则表达式打印),它的主要功能是根据指定的模式(正则表达式)在文本文件中搜索并打印匹配的行。grep非常强大且灵活,可以用于日志分析、文件过滤、代码搜索等多种场......
  • 软件测试|Linux三剑客之sed命令详解
    简介sed(StreamEditor)是一款流式文本编辑器,在Linux和类Unix系统中广泛使用。它的设计目的是用于对文本进行处理和转换,可以用于替换、删除、插入、打印等操作。sed命令通过逐行处理文本,允许您使用简单的命令来编辑大量文本数据。本文将详细介绍sed命令的基本用法和一些常见的......
  • 鸿蒙万能卡片开发详解-记忆翻牌游戏
    (目录)1.前言      翻牌游戏万能卡片,随机生成16张共包含8张完全不同的图像,游戏的目标是在有限30秒时间内,将16张卡片中包含相同的图像的卡片两两配对。匹配的规则是连续点击两张卡片,若卡背面的图像相同,则匹配成功,若不同则配对失败。游戏主要考察玩家的记忆力,因为游戏还规定......
  • JS数据类型详解
    JS的数据类型分为基本数据类型+引用数据类型基本数据类型:number,boolean,string,null,undefined, symbol(独一无二并且不可变的数据类型),bigint引用数据类型: Function,Array,Object区别:基本数据类型由于所占内存大小可控所以放于栈中,引用数据类型所占空间不固定放于堆中,并生......
  • 4G工业路由器的功能与选型!详解工作原理、关键参数、典型品牌
    随着工业互联网的发展,4G工业路由器得到越来越广泛的应用。但是如何根据实际需求选择合适的4G工业路由器,是许多用户关心的问题。为此,本文将深入剖析4G工业路由器的工作原理、重要参数及选型要点,并推荐优质的品牌及产品,以提供选型参考。  一、4G工业路由器的工作原理4G......
  • C++ 多线程详解之异步编程 std::packaged_task
    std::packaged_task将任何可调用对象(比如函数、lambda表达式等等)封装成一个task,可以异步执行。执行结果可以使用std::future获取。比如下面的例子,构造一个std::packaged_task后,get_future()函数返回一个std::future对象,可以获取task异步或者同步执行的结果。#includ......
  • java中volatile关键字详解
    简介volatile是Java语言中的一种轻量级的同步机制,它可以确保共享变量的内存可见性,也就是当一个线程修改了共享变量的值时,其他线程能够立即知道这个修改。跟synchronized一样都是同步机制,但是相比之下,synchronized属于重量级锁,volatile属于轻量级锁。JMM概述JMM就是Java内存模型(Jav......
  • vue3 vue.config.js配置详解
    //vue.config.js文件是用于VueCLI项目的全局配置的module.exports={  //部署应用包时的公共路径  publicPath:"./",  //生产环境构建文件的目录名(默认为dist)  outputDir:"dist",  //放置生成的静态资源的目录(默认为dist/static),可以修改为public。  assetsDir......