• Java基础知识11--Optional类


    1.Optional概念

    java.util.Optional<T>类是一个封装了Optional值的容器对象,Optional值可以为null,如果值存在,调用isPresent()方法返回true,调用get()方法可以获取值。

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

    Optional 类的引入很好的解决空指针异常。

    以下是 java.util.Optional<T> 类的声明:

    public final class Optional<T> extends Object

    2.为什么要使用Optional

    目的:避免使用null检查

    作为Java开发人员,几乎所有人都遇到过NullPointerException异常,大多数人遇到NullPointerException异常时都会在异常出现的地方加上if代码块来判断值不为空,比如下面的代码:

    public void bindUserToRole(User user) {
        if (user == null) {
            return;
        }
    
        String roleId = user.getRoleId();
        if (roleId == null) {
            return;
        }
    
        Role = roleDao.findOne(roleId);
        if (role != null) {
            role.setUserId(user.getUserId());
            roleDao.save(role);
        }
    }

    方法内有三个不同的返回点,出错后调试也不容易,你都不知道是那个值导致了NullPointerException异常。

    基于上面的原因,Java 8中引入了一个新的类Optional,用以避免使用null值引发的种种问题。

    Optional<String> roleOpt = Optional.ofNullable(user).map(User::getRoleId);
    if(roleOpt.isPresent()){
        ....
    }

    3.创建Optional对象

     Optional类提供类三个方法用于实例化一个Optional对象,它们分别为empty()of()ofNullable(),这三个方法都是静态方法,可以直接调用。

    (1)empty()方法

    empty()方法用于创建一个没有值的Optional对象:

    Optional<String> emptyOpt = Optional.empty();

    empty()方法创建的对象没有值,如果对emptyOpt变量调用isPresent()方法会返回false,调用get()方法抛出NullPointerException异常。

    (2)of()方法

    of()方法使用一个非空的值创建Optional对象:

    String str = "Hello World";
    Optional<String> notNullOpt = Optional.of(str);

    (3)ofNullable()方法

    ofNullable()方法接收一个可以为null的值:

    Optional<String> nullableOpt = Optional.ofNullable(str);

    如果str的值为null,得到的nullableOpt是一个没有值的Optional对象。

    若是集合类型:

    Optional<List<Student>> studentList1 = Optional.ofNullable(studentList);

    (4)of()ofNullable()方法辨析

    当你很确定一个对象不可能为null的时候,应该使用of()方法,否则,尽可能使用ofNullable()方法,比如:

    public static void method(Role role) {
        // 当Optional的值通过常量获得或者通过关键字new初始化,可以直接使用of()方法
        Optional<String> strOpt = Optional.of("Hello World");
        Optional<User> userOpt = Optional.of(new User());
    
        // 方法参数中role值不确定是否为null,使用ofNullable()方法创建
        Optional<Role> roleOpt = Optional.ofNullable(role);
    }

    4.map()方法提取Optional对象中的值

    如果我们要获取User对象中的roleId属性值,常见的方式是直接获取:

    String roleId = null;
    if (user != null) {
        roleId = user.getRoleId();
    }

    使用Optional中提供的map()方法可以以更简单的方式实现:

    Optional<User> userOpt = Optional.ofNullable(user);
    Optional<String> roleIdOpt = userOpt.map(User::getRoleId);
    List<String> paramNameList = Optional.ofNullable(ruleProcessParaList).orElse(new ArrayList<>()).stream().map(PmRuleProcessPara::getAttrCode).collect(Collectors.toList());

    map()方法与Stream API中的map()一样,类似于映射操作,将原始类型映射为一个新的类型。

    5.使用orElse()方法获取值

    源码:

    public T orElse(T var1) {
            return this.value != null ? this.value : var1;
        }

    orElse():如果有值就返回T,否则返回一个给定的值作为默认值;

    案例1:

    return str != null ? str : "Hello World"

    上面的代码表示判断字符串str是否为空,不为空就返回,否则,返回一个常量。使用Optional类可以表示为:

    return strOpt.orElse("Hello World")

    案例2:

    public class OptionalTest {
        public static void main(String[] args) {
            List<Student> studentList=new ArrayList<>();
            Student student1=new Student();
            student1.setAge(10);
            student1.setName("lucky");
            Student student2=new Student();
            student2.setAge(12);
            student2.setName("linda");
            studentList.add(student1);
            studentList.add(student2);
            Optional<List<Student>> studentList1 = Optional.ofNullable(studentList);
            List<Student> studentList2 = Optional.ofNullable(studentList).orElse(new ArrayList<>());
            
            List<Integer> collect = Optional.ofNullable(studentList).orElse(new ArrayList<>()).stream().map(Student::getAge).collect(Collectors.toList());
            System.out.println("hello");
    
        }
    }

    debug截图:

    6.ifPresent()方法

    如果值存在则使用该值调用 consumer , 否则不做任何事情。示例如下

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

    代码实例:

    Optional<String> optional=Optional.ofNullable("zh");
    optional.ifPresent(s1 -> System.out.println(s1));

    典型应用:将map转为字符串str

        public static String map2Str(Map<String,String> params){
            StringBuffer stringBuffer=new StringBuffer();
            //Optional<Set<Map.Entry<String, String>>> optionalEntrySet = Optional.ofNullable(params.entrySet());
            Optional.ofNullable(params.entrySet()).ifPresent((paramsSet)-> {
                paramsSet.forEach((entry)->{
                    stringBuffer.append(entry.getKey())
                            .append("=")
                            .append(entry.getValue())
                            .append("&");
                });
            });
            return stringBuffer.deleteCharAt(stringBuffer.length()-1).toString();
    
            //Optional.ofNullable(params.entrySet())
        }

    参考文献:https://lw900925.github.io/java/java8-optional.html

  • 相关阅读:
    [Swift]LeetCode811. 子域名访问计数 | Subdomain Visit Count
    [Objective-C语言教程]程序结构(3)
    [Objective-C语言教程]开发环境设置(2)
    [Objective-C语言教程]简介(1)
    [Swift]LeetCode810. 黑板异或游戏 | Chalkboard XOR Game
    [Swift]LeetCode809. 情感丰富的文字 | Expressive Words
    [Swift]LeetCode808. 分汤 | Soup Servings
    转:用ANT执行SQL
    转:让开发自动化: 实现自动化数据库迁移
    转 让开发自动化: 使用自动化加速部署
  • 原文地址:https://www.cnblogs.com/luckyplj/p/15269297.html
Copyright © 2020-2023  润新知