给女朋友讲解什么是Optional【JDK 8特性】

手把手教你用ZLMediaKit搭建WebRTC直播:本地推流与播放实战 本文详细介绍了如何使用ZLMediaKit搭建WebRTC直播系统,涵盖从环境准备、编译部署、SSL证书配置到本地推流与播放的完整实战流程。通过一步步的指导,帮助开发者快速掌握基于ZLMediaKit的WebRTC推拉流技术,构建低延迟的实时音视频应用。 阅读详情

前言

只有光头才能变强

前两天带女朋友去图书馆了,随手就给她来了一本《与孩子一起学编程》的书,于是今天就给女朋友讲解一下什么是Optional类。

  • 至于她能不能看懂,那肯定是看不懂的。(学到变量/for循环的女人怎么能看懂呢)

不知道大家还记得上一篇《阿里巴巴 Java开发手册》读后感不,当时阅读到空指针异常(NPE)时,书上提到JDK 8有个Optional类供我们使用,该类可以尽可能地防止出现空指针异常(NPE)。

文本力求简单讲清每个知识点,希望大家看完能有所收获

一、基础铺垫

我们都知道JDK 8最重要的新特性是Lambda表达式,这个可以让我们简化非常多的代码编写,不知道大家会使用了没有。这里我简单跟大家来回顾一下~

1.1Lambda简化代码例子

下面就以几个例子来看看Lambda表达式是怎么简化我们代码的编写的。

首先我们来看看创建线程:


public static void main(String[] args) {
    // 用匿名内部类的方式来创建线程
    new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("公众号:Java3y---回复1进群交流");
        }
    });

    // 使用Lambda来创建线程
    new Thread(() -> System.out.println("公众号:Java3y---回复1进群交流"));
}

再来看看遍历Map集合:



public static void main(String[] args) {
    Map<String, String> hashMap = new HashMap<>();
    hashMap.put("公众号", "Java3y");
    hashMap.put("交流群", "回复1");

    // 使用增强for的方式来遍历hashMap
    for (Map.Entry<String, String> entry : hashMap.entrySet()) {
        System.out.println(entry.getKey()+":"+entry.getValue());
    }

    // 使用Lambda表达式的方式来遍历hashMap
    hashMap.forEach((s, s2) -> System.out.println(s + ":" + s2));
}

在List中删除某个元素


public static void main(String[] args) {

    List<String> list = new ArrayList<>();
    list.add("Java3y");
    list.add("3y");
    list.add("光头");
    list.add("帅哥");
    
    // 传统的方式删除"光头"的元素
    ListIterator<String> iterator = list.listIterator();
    while (iterator.hasNext()) {
        if ("光头".equals(iterator.next())) {
            iterator.remove();
        }
    }

    // Lambda方式删除"光头"的元素
    list.removeIf(s -> "光头".equals(s));
    
    // 使用Lambda遍历List集合
    list.forEach(s -> System.out.println(s));
}

从上面的例子我们可以看出,Lambda表达式的确是可以帮我们简化代码的。

1.1函数式接口

使用Lambda表达式,其实都是建立在函数式接口上的。我们看看上面的代码的接口:

创建多线程的Runnable接口:


@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

遍历HashMap的BiConsumer接口:


@FunctionalInterface
public interface BiConsumer<T, U> {
    void accept(T t, U u);
    default BiConsumer<T, U> andThen(BiConsumer<? super T, ? super U> after) {
        Objects.requireNonNull(after);
        return (l, r) -> {
            accept(l, r);
            after.accept(l, r);
        };
    }
}

在List中删除元素的Predicate接口:


@FunctionalInterface
public interface Predicate<T> {

    boolean test(T t);

    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }
    default Predicate<T> negate() {
        return (t) -> !test(t);
    }
    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }
    static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }
}

函数式接口的特点:由@FunctionalInterface注解标识,接口有且仅有一个抽象方法!

1.2Lambda简单讲解

或许我们一开始看到Lambda的时候,发现Lambda表达式的语法有点奇葩,甚至有点看不懂。没事,这里3y给大家用图的形式画一画:

Lambda表达式组成

以Runnable接口来举例:

Lambda表达式很简单!

再不济,我们在用IDE的时候,可以提示出Lambda表达式的语法的,这样可以帮我们快速上手Lambda表达式:

IDEA提示Lambda表达式

说白了,我们使用Lambda表达式的架子是这样的()->{},具体的时候看看函数式接口的抽象方法要求就可以了,再不济就使用IDE智能提示。

1.3泛型回顾

比如说public<U> Optional<U> map(Function<? super T, ? extends U> mapper)这个声明,你看懂了吗?


// 接口
@FunctionalInterface
public interface Function<T, R> {
    R apply(T t);
}

在泛型的上限和下限中有一个原则:PECS(Producer Extends Consumer Super)

  • 带有子类限定的可以从泛型读取【也就是—>(? extend T)】-------->Producer Extends
  • 带有超类限定的可以从泛型写入【也就是—>(? super T)】-------->Consumer Super

解析:传入的参数是泛型 T 或者其父类,返回值是U或其子类。

具体可参考:

二、Optional类

一句话介绍Optional类:使用JDK8的Optional类来防止NPE(空指针异常)问题。

接下来我们看看文档是怎么说的:

A container object which may or may not contain a non-null value.Additional methods that depend on the presence or absence of a contained value are provided

它是一个容器,装载着非NULL元素(或者没有装载元素),提供了一系列的方法供我们判断该容器里的对象是否存在(以及后续的操作)。

Optional类的方法结构图:

Optional类的方法结构图

2.1创建Optional容器

我们先来看看Optional的属性以及创建Optional容器的方法:


	// 1、创建出一个Optional容器,容器里边并没有装载着对象
    private static final Optional<?> EMPTY = new Optional<>();

	// 2、代表着容器中的对象
    private final T value;

	// 3、私有构造方法
    private Optional() {
        this.value = null;
    }

	// 4、得到一个Optional容器,Optional没有装载着对象
    public static<T> Optional<T> empty() {
        @SuppressWarnings("unchecked")
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
    }

	// 5、私有构造方法(带参数),参数就是具体的要装载的对象,如果传进来的对象为null,抛出异常
    private Optional(T value) {
        this.value = Objects.requireNonNull(value);
    }

	// 5.1、如果传进来的对象为null,抛出异常
    public static <T> T requireNonNull(T obj) {
        if (obj == null)
            throw new NullPointerException();
        return obj;
    }


	// 6、创建出Optional容器,并将对象(value)装载到Optional容器中。
	// 传入的value如果为null,抛出异常(调用的是Optional(T value)方法)
    public static <T> Optional<T> of(T value) {
        return new Optional<>(value);
    }

	// 创建出Optional容器,并将对象(value)装载到Optional容器中。
	// 传入的value可以为null,如果为null,返回一个没有装载对象的Optional对象
    public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
    }

所以可以得出创建Optional容器有两种方式:

  • 调用ofNullable()方法,传入的对象可以为null
  • 调用of()方法,传入的对象不可以为null,否则抛出NullPointerException

下面我们简单就可以看看用法了:

现在我有一个User对象,这里用到了Lombok,有兴趣的同学可去学学了解一下:两个月的Java实习结束,继续努力


import lombok.Data;
@Data
public class User {

    private Integer id;
    private String name;
    private Short age;
}

测试:


public static void main(String[] args) {

    User user = new User();
    User user1 = null;

    // 传递进去的对象不可以为null,如果为null则抛出异常
    Optional<User> op1 = Optional.of(user1);

    // 传递进去的对象可以为null,如果为null则返回一个没有装载对象的Optional容器
    Optional<User> op2 = Optional.ofNullable(user);
}

结果

2.2Optional容器简单的方法


// 得到容器中的对象,如果为null就抛出异常
public T get() {
    if (value == null) {
        throw new NoSuchElementException("No value present");
    }
    return value;
}

// 判断容器中的对象是否为null
public boolean isPresent() {
    return value != null;
}

// 如果容器中的对象存在,则返回。否则返回传递进来的参数
public T orElse(T other) {
    return value != null ? value : other;
}

这三个方法是Optional类比较常用的方法,并且是最简单的。(因为参数不是函数式接口)

下面我们继续看看用法:


public static void main(String[] args) {

        User user = new User();
        User user1 = null;

        Optional<User> op1 = Optional.ofNullable(user);
        System.out.println(op1.isPresent());
        System.out.println(op1.get());
        System.out.println(op1.orElse(user1));

    }

结果很明显,因为我们的user是不为null的:

结果

我们调换一下顺序看看:


public static void main(String[] args) {

    User user = new User();
    User user1 = null;

    Optional<User> op1 = Optional.ofNullable(user1);
    System.out.println(op1.isPresent());
    System.out.println(op1.orElse(user));
    System.out.println(op1.get());

}

结果

2.3Optional容器进阶用法

当然了,我们到目前为止看起来Optional类好像就这么一回事了,这样代码写起来还不如我自己判断null呢…

我们对比一下:

对比

我们可以发现,手动判断是否为null好像还更方便简洁一点呢。

所以,我们带函数式接口的方法登场了!

2.3.1ifPresent方法

首先来看看ifPresent(Consumer<? super T> consumer)方法



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

@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);
}

如果容器中的对象存在,则调用accept方法,比如说:


public static void main(String[] args) {

    User user = new User();
    user.setName("Java3y");
    test(user);
}

public static void test(User user) {

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

    // 如果存在user,则打印user的name
    optional.ifPresent((value) -> System.out.println(value.getName()));

    // 旧写法
    if (user != null) {
        System.out.println(user.getName());
    }
}

2.3.2orElseGet和orElseThrow方法

直接看源码:


// 如果对象存在,则直接返回,否则返回由Supplier接口的实现用来生成默认值
public T orElseGet(Supplier<? extends T> other) {
    return value != null ? value : other.get();
}


@FunctionalInterface
public interface Supplier<T> {
    T get();
}


// 如果存在,则返回。否则抛出supplier接口创建的异常
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
    if (value != null) {
        return value;
    } else {
        throw exceptionSupplier.get();
    }
}

例子:


public static void main(String[] args) {

    User user = new User();
    user.setName("Java3y");
    test(user);
}

public static void test(User user) {

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

    // 如果存在user,则直接返回,否则创建出一个新的User对象
    User user1 = optional.orElseGet(() -> new User());
    
    // 旧写法
    if (user != null) {
        user = new User();
    }
}

总的来说跟我们上面所讲的orElse()差不多,只不过它可以通过Supplier接口的实现来生成默认值。

2.3.3filter方法

直接看源码:


// 如果容器中的对象存在,并且符合过滤条件,返回装载对象的Optional容器,否则返回一个空的Optional容器
public Optional<T> filter(Predicate<? super T> predicate) {
    Objects.requireNonNull(predicate);
    if (!isPresent())
        return this;
    else
        return predicate.test(value) ? this : empty();
}


// 接口
@FunctionalInterface
public interface Predicate<T> {

    boolean test(T t);
}

返回Optional对象我们就可以实现链式调用了!

例子:


public static void test(User user) {

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

    // 如果容器中的对象存在,并且符合过滤条件,返回装载对象的Optional容器,否则返回一个空的Optional容器
    optional.filter((value) -> "Java3y".equals(value.getName()));
}

2.3.4map方法

直接看源码:


// 如果容器的对象存在,则对其执行调用mapping函数得到返回值。然后创建包含mapping返回值的Optional,否则返回空Optional。
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));
    }
}


// 接口
@FunctionalInterface
public interface Function<T, R> {
    R apply(T t);
}

例子:


public static void test(User user) {

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

    // 如果容器的对象存在,则对其执行调用mapping函数得到返回值。然后创建包含mapping返回值的Optional,否则返回空Optional。
    optional.map(user1 -> user1.getName()).orElse("Unknown");
}

// 上面一句代码对应着最开始的老写法:

public String tradition(User user) {
    if (user != null) {
        return user.getName();
    }else{
        return "Unknown";
    }
}

2.3.5flatMap方法

直接看源码:


// flatMap方法与map方法类似,区别在于apply函数的返回值不同。map方法的apply函数返回值是? extends U,而flatMap方法的apply函数返回值必须是Optional
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));
    }
}

2.3.6总结

再来感受一下Optional的魅力


public static void main(String[] args) {
    User user = new User();
    user.setName("Java3y");
    System.out.println(test(user));
}

// 以前的代码v1
public static String test2(User user) {
    if (user != null) {
        String name = user.getName();
        if (name != null) {
            return name.toUpperCase();
        } else {
            return null;
        }
    } else {
        return null;
    }
}

// 以前的代码v2
public static String test3(User user) {
    if (user != null && user.getName() != null) {
        return user.getName().toUpperCase();
    } else {
        return null;
    }
}

// 现在的代码
public static String test(User user) {
    return Optional.ofNullable(user)
            .map(user1 -> user1.getName())
            .map(s -> s.toUpperCase()).orElse(null);
}

Optional总结:

filter,map或flatMap一个函数,函数的参数拿到的值一定不是null。所以我们通过filter,map 和 flatMap之类的函数可以将其安全的进行变换,最后通过orElse系列,get,isPresent 和 ifPresent将其中的值提取出来。

其实吧,用Optional类也没有简化很多的代码,只是把NPE异常通过各种方法隐藏起来(包装了一层)。通过Lambda表达式可以让我们处理起来更加"优雅"一些。

三、最后

之前在初学的时候没在意JDK8的特性,其实JDK更新很多时候都能给我们带来不少好处的(简化代码编写,提高性能等等),所以作为一名Java程序员,还是得多学学新特性。(话说JDK9该类又有新特性了…)

如果你要评论“醒醒吧,程序员哪来的女朋友”,“我尿黄,让我来”之类的话,我建议你是不是好好反省一下自己,为什么别的程序员都有女朋友,就你没有,是不是自己技术不过关了?通过“工厂”找一个有那么难吗?再不济也能自己new一个出来啊。

当然了,我的女朋友是现实存在的。

参考资料:

如果你觉得我写得还不错,了解一下:

微信小程序获取用户手机号全流程实战(附完整代码) 本文详细介绍了微信小程序获取用户手机号的全流程实战,包括前端授权、后端解密及安全合规要点。通过传统授权按钮和新版手机号快速验证组件两种方案,帮助开发者高效实现功能,并附完整代码示例。重点解析了微信小程序接口的使用技巧和常见问题解决方案,确保数据安全与用户体验。 阅读详情

相关推荐

自定义css属性实现渐变边框动画

自定义cs属性实现渐变边框动画

lemon的博客 1875

JDK8-Optional类避免NPE

1.需求分析 调用RPC返回结果、包装类转简单类型,拆箱过程最容易出现NPE问题。JDK8之前需要小心翼翼对各种类型进行判空,可通过JKD8-Optional类来预发未知的NPE错误。 2.关于避免NPE的常识 【强制】所有POJO类属性必须使用包装数据类型 【强制】所有RPC方法的返回和参数必须使用包装数据类型 【推荐】所有局部变量使用基本简单数据类型 Ps: POJO类属性没有初值是提醒...

侠客小虎的博客 6829

STM32硬件SPI驱动W5500以太网模块全流程(附避坑指南)

本文详细介绍了STM32硬件SPI驱动W5500以太网模块的全流程,包括硬件架构设计、SPI接口选型、官方驱动移植、网络协议栈配置与优化等关键步骤。通过实战案例和性能对比数据,帮助开发者快速实现稳定高效的网络连接,特别提供了常见问题排查指南和性能调优技巧。

weixin_29194693的博客 268

lambda表达式:Stream 解析,内部迭代和外部迭代解析

Stream 流(重要) 流由三部分构成 源(要操作的数据) 零个或多个中间操作(每次操作都会产生一个新的流) 终止操作(得到结果) 流操作的分类: 惰性求值 及早求值 steam.xxx().yyy().zzz().sum(); xxx().yyy().zzz() 就叫做惰性操作如果没有终止操作将不会执行,也叫做中间操作 .sum()就叫做及早求值,直接把值求出来 也叫终止操作 流的三种创建方法 /** * 流的三种创建方式 */ public class StreamTest {

qq_42261668的博客 1293

gd32 spi 发送&中断接收例程

【代码】gd32 spi 发送&中断接收例程。

weixin_43026921的博客 1653

RouterOS网桥VLAN实战:从零构建安全隔离的二层虚拟网络

本文详细讲解了如何在RouterOS上利用网桥和VLAN功能,从零开始构建安全隔离的二层虚拟网络。通过分步实战演示,涵盖核心概念、网桥创建、PVID设置、VLAN规则配置及安全过滤,帮助网络管理员实现办公、访客与服务器网络的逻辑隔离与灵活管理,提升网络安全性。

u9v0w的博客 504

巧用 Java 8 的 Optional 优雅的规避 NPE

先介绍一下API,与其他文章不同的是,本文采取类比的方式来讲,同时结合源码。而不像其他文章一样,一个个API罗列出来,让人找不到重点。

m0_57042151的博客 339

嵌入式学习笔记- 关于电容的纹波电流

纹波电流是导致电解电容发热、影响其寿命的关键交流电流成分。它不是一种特殊的电流,而是电路中必然存在的现象。要重视,不能忽视。必须保证电路中的纹波电流 < 电容的额定纹波电流。电容鼓包爆浆,要怀疑是否是纹波电流过大或电容ESR变大所致。希望这个解释能帮助您彻底理解这个概念!二 电容纹波电流与频率的关系在大多数情况下,频率越高,电容所能承受的额定纹波电流值越大。【个人理解:因为频率越低ESR越大,具体见第三节ESR与频率的关系】下面我为您详细解释为什么会这样,以及在实际应用中如何考虑。

qq_35771411的博客 2194

jdk8新特性-Optional

jdk8-Optional使用

xiao_yu_gan的博客 2466

SAP UI5 OData V4 操作结果访问:从 getObject 到返回值上下文与 $$inheritExpandSelect

SAP UI5 OData V4 操作结果获取指南 摘要:在 SAP UI5 OData V4 模型中,操作结果需通过绑定上下文获取而非直接从 invoke() 返回。本文详解核心要点: 数据获取路径 使用 invoke() 发起请求后,通过 getBoundContext().getObject() 获取结果 特定场景下 invoke() 可能返回返回值上下文(如草稿切换) 关键实践技巧 使用 $$inheritExpandSelect 继承字段选择,避免二次读取 对象页应用中,通过替换绑定上下文实现无缝

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 314

Python爬虫实战 | 拼多多商品评论采集与深度分析

本文从 API 调用、网页渲染到情感分析与关键词提取,全流程剖析了“拼多多商品评论采集与分析”项目。Scrapy + API 可快速抓取评论;Playwright 可突破 API 限制,抓取完整页面内容;数据清洗 + 分析揭示用户真实反馈;可持续部署、扩展至更多商品 & 时间段;

2201_76125261的博客 1696

JDK8新特性(四):Optional 类的使用

Optional类的使用 JDK8以前,编写代码,通常会出现 NullPointerException (空指针异常),通常情况下我们都是通过 if ... else... 来对对象进行为空判断,然后再进行逻辑处理,代码写起来也比较冗余。 JDK8新增了Optional类,使用该类可以避免我们对空指针的检查,使代码看起来比较优雅。 1.Optional类介绍 ...

扛麻袋的少年的博客 6953

论文复现5:UMI Universal Manipulation Interface

UMI 采用手持式夹具,加上精心的界面设计,可实现便携式、低成本和信息丰富的数据收集,以进行具有挑战性的双手和动态操作演示。配备这些功能后,UMI 框架解锁了新的机器人操作功能,只需更改每个任务的训练数据,即可实现零样本可推广的动态、双手、精确和长视野行为。我们通过全面的现实世界实验展示了 UMI 的多功能性和有效性,其中通过 UMI Zeroshot 学习的策略在对不同的人类演示进行训练时可以推广到新的环境和对象。项目主页:https://umi-gripper.github.io/

github_38060285的博客 1974

推荐一个java技术文章公众号

☕️Java基础 2018年如何快速学Java 泛型就这么简单 注解就这么简单 Druid数据库连接池就是这么简单 Object对象你真理解了吗? JDK10都发布了,nio你了解多少? COW奶牛!Copy On Write机制了解一下 给女朋友讲解什么是Optional【JDK 8特性】 还在用Synchronized?Atomic你了解不? 《阿里巴巴 Java开发手册》读后感 JVM如...

神棍之路 3198

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

这是一篇java3y的优选文章总结

目录 Java基础: 2018年如何快速学Java: 泛型就这么简单: 注解就这么简单: 数据库连接池就是这么简单: Object对象你真理解了吗? JDK10都发布了,nio你了解多少?: COW奶牛!Copy On Write机制了解一下 给女朋友讲解什么是Optional【JDK 8特性】 还在用Synchronized?Atomic你了解不? JVM如何从入门到放弃的? Java容器 Collection总览 List集合就这么简单【源码剖析】 Map集合、散列表.

Lonely Programmer 8063

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

工作中使用到的单词(软件开发)

1.エイリアス   alias 别名 powershell使用 get-help 命令时,会得到与此命令 相关(别名)的命令 2.プロキシ proxy 代 理 3.プロモート   promote 促进,提升   开发的系统新功能上线发布,有时会使用到这个词,比如 STプロモート 还有使用リリース这个词的。比如STリリース。个人认为两者含义相同。 4.見逃し み................................................................

sun0322 6万+

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

详解 JDK8 新特性之 Optional 类

详解 JDK8 新特性之 Optional 类

h2806504347的博客 565

Java新特性:Optional类

Optional 类是 Java 8 才引入的,Optional 是个容器,它可以保存类型 T 的值,或者仅仅保存 null。Optional 提供了很多方法,这样我们就不用显式进行空值检测。Optional 类的引入很好的解决空指针异常。 Java 8 引入 Optional 类,用来解决 NullPointerException。 Optional 代替 if…else 解决空指针问题,使代码更加简洁。

栗筝i的博客 9143

JDK8新特性(一):Optional类

JDK8新增了Optional 类,它是一个没有子类的工具类。我们可以把它看作是一个容器。这个容器有两种情况:①要么有值 ②要么为null。

weixin_54009596的博客 668

JDK8特性:Optional类的用法

JDK8中新增的Optional工具类使用说明

Newbie的专栏 637

Optional使用教程

Java 8 之 Optional 使用

weixin_46058921的博客 4694

JDK8新特性之Optional类,5分钟包你完全学会

在编写代码的时候为了防止空指针异常,往往需要各种非空的判段,而过多的判段会导致代码臃肿不堪。为了解决这一问题JDK8引入了Optional类,对于程序员,养成使用Optional类习惯,可以写出更为优雅的代码。Optional类就好像是一个包装类,我们可以把具体的数据封装到Optional对象内部。3,map和flatMap都是对操作的数据进行转换,得到的数据依然时OPtional类包装好的,保证了使用的安全。4,filter 对数据进行过滤如果都不符合判段的条件返回一个无数据的Optional对象。

m0_74340515的博客 558

详细介绍JDK8中Optional对象的高级用法

Optional 是 Java 8 引进的一个新特性,我们通常认为 Optional 是用于缓解 Java 臭名昭著的空指针异常问题。Optional 是个容器:它可以保存类型 T 的值,或者仅仅保存 null。如果值存在则 isPresent() 方法会返回 true,调用 get() 方法会返回该对象。Optional 提供很多有用的方法,这样我们就不用显式进行空值检测。

sbcsdn111的博客 1411

JDK8:使用Optional进行变量判空、集合遍历

NPE(Null Pointer Exception)一直是我们最头疼的问题,也是最容易忽视的地方。NPE常是导致Java应用程序失败的最常见的原因。在日常研发工作中,经常会处理各种变量、集合,但在使用的过程中,往往要进行空判断,不然会出现NPE。 JDK8新特性之Optional介绍 Optional类实际上是个容器:它可以保存类型T的值,或者仅仅保存null。Optional 类的引入很好的解决空指针异常。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。尽量避免在程序中直接调用O

YHJ 1万+

JDK8之Optional

java之Optional的用法

sijiwang95的博客 232
上一篇: 《阿里巴巴 Java开发手册》读后感
下一篇: 还在用Synchronized?Atomic你了解不?
Java3y
Java3y 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄9年 1万+粉丝 509原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值