还在使用if进行空判断?

一、前言

我们在编程中经常会进行空指针判断,常用if来完成,这会让代码非常冗余,像下面这样:

    /**
     * 获取用户所在的城市
     *
     * @param user 用户
     * @return 城市的大写
     */
    public static String getCity(User user) throws Exception {
        // return user.getAddress().getCity().toUpperCase(Locale.ENGLISH);//这写法存中空指针问题
        if (user != null) {
            Address address = user.getAddress();
            if (address != null) {
                if (address.getCity() != null) {
                    return address.getCity().toUpperCase(Locale.ENGLISH);
                }
            }
        }
        throw new Exception("有空指针");
    }
   // Lombok构造实体类
    @Data
    @Builder
    class User {
        private String name;
        private Address address;
    }

    @Data
    @Builder
    class Address {
        private String city;
    }
我们想取用户的大写地址,需要进行多重判断,代码进行了多次缩进,看着也不美观。Optional因此而生。

二、Optional类

optional类是jdk8引入的,主要是为了解决空指针问题。optional本质是一个容器,把值放入容器中,可以规避空指针问题。官方解释如下:

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

此类的常用方法如下:

  • get():如果 Optional中有一个值,返回值,否则抛出 NoSuchElementException 。

  • ifPresent(Consumer<? super T> consumer):如果存在值,则使用该值调用指定的消费者,否则不执行任何操作。

  • map(Function<? super T, ? extends U> mapper):如果存在一个值,则应用提供的映射函数,如果结果不为空,则返回一个 Optional结果的 Optional 。

  • ofNullable(T value):返回一个 Optional指定值的Optional,如果非空,则返回一个空的 Optional 。

  • orElse(T other):返回值如果存在,否则返回 other

  • orElseGet(Supplier<? extends T> other):返回值(如果存在),否则调用 other并返回该调用的结果。

三、改进与总结

重写getCity()方法,暂且命名getCity2(),具体如下:

    public static String getCity2(User user) throws Exception {
        return Optional.ofNullable(user)
                .map(User::getAddress)
                .map(address -> address.getCity().toUpperCase(Locale.ENGLISH))
                .orElseThrow(() -> new Exception("有空指针"));
    }
    public static void main(String[] args) {
        User user = User.builder().name("ZS").address(Address.builder().city("beijing").build()).build();
        User user1 = null;
        User user2 = User.builder().name("ZS").address(null).build();
		// 1、传统形式及结果
        try {
            System.out.println(getCity(user));// BEIJING
            //System.out.println(getCity(user1)); // 有空指针
            System.out.println(getCity(user2)); // 有空指针
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 2、optional形式及结果
        try {
            System.out.println(getCity2(user));// BEIJING
            //System.out.println(getCity2(user1)); // 有空指针
            System.out.println(getCity2(user2)); // 有空指针
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
  其实他的功能不仅如此,比如我要获取用户的姓名,如果传来的user=null,则返回一个默认用户。下面一起看看传统形式与optional形式。
    /**
     * 获取用户名,如果是空,则返回默认名
     *
     * @param user 用户
     * @return 用户名
     */
    public static String getName(User user) {
        // 1、传统形式
        if (user != null) {
            return user.getName();
        } else {
            return "默认用户名:张三";
        }

        // 2、Optional形式
        return Optional.ofNullable(user).map(User::getName).orElse("默认用户名:张三");
    }
可以看到,原本需要四行代码完成的逻辑,如今只需要一行了,变更更简洁了。

获取更多内容,请关注微信公众号。搜索“码圈小橙子”,这里会不时的更新。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值