Java8 Optional常用方法使用场景

前言:

        Optional 是 Java 8 的新特性,专治空指针异常(NullPointerException, 简称 NPE)问题,它是一个容器类,里面只存储一个元素(这点不同于 Conllection)。

        为方便用户通过 Lambda 表达式调用 Optional 的方法,部分方法(如:filter、ifPresent、map、orElseGet)需传入函数式接口(如:Predicate、Consumer、Function、Supplier)参数。


项目场景:

  业务需求是这样的,从第三方拉取用户信息,然后保存到公司自己的数据库,而第三方接口返回的数据是 JSON 格式的,需要获取到用户地址相关信息,但是用户地址相关信息却藏的十分深,如下面所示,JSON 节点是这样的:

{"userInfo":{"userDetails":{"city":"深圳市"}}}

基本实现

创建相关实体用来接收

import lombok.Data;

@Data
public class User {
	private Integer id;				//   id
	private UserInfo userInfo;		//   用户信息

	public User(UserInfo userInfo) {
		this.userInfo = userInfo;
	}
}
import lombok.Data;

@Data
public class UserInfo {
	private String userName;			//   用户名称
	private UserDetails userDetails;	//   用户详情

	public UserInfo(UserDetails userDetails) {
		this.userDetails = userDetails;
	}
}
import lombok.Data;

@Data
public class UserDetails {
	private String address;			//   住址
	private String city;			//   城市

	public UserDetails(String city) {
		this.city = city;
	}
}

示例代码:

1.常用的写法

缺点:if嵌套非常深

import com.test.entity.User;
import com.test.entity.UserDetails;
import com.test.entity.UserInfo;

import java.util.Optional;

public class TestService {

    public static void main(String[] args) {
        UserDetails userDetails = new UserDetails("深圳市");
        UserInfo userInfo = new UserInfo(userDetails);
        User user = new User(userInfo);

        System.out.println(getCity(user));
    }

    /**
     * 以前的写法
     * @param user  用户对象
     * @return  用户所在城市
     */
    public static String getCity(User user){
        if(user != null){
            UserInfo userInfo = user.getUserInfo();
            if(userInfo != null){
                UserDetails userDetails = userInfo.getUserDetails();
                if(userDetails != null){
                    return userDetails.getCity();
                }
            }
        }
        return null;
    }
}

2.JAVA8写法

优点:不用再额外判断空指针

import com.test.entity.User;
import com.test.entity.UserDetails;
import com.test.entity.UserInfo;

import java.util.Optional;

public class TestService {

    public static void main(String[] args) {
        UserDetails userDetails = new UserDetails("深圳市");
        UserInfo userInfo = new UserInfo(userDetails);
        User user = new User(userInfo);

        System.out.println(getCity_java8(user));
    }

    /**
     * java8写法
     * @param user  用户对象
     * @return  用户所在城市
     */
    public static String getCity_java8(User user){
        return Optional.ofNullable(user)
                        .map(u -> u.getUserInfo())
                        .map(d -> d.getUserDetails())
                        .map(t -> t.getCity())
                        .orElse(null);
    }
}

源码解析:

为什么Optional不用判断空指针了呢,其实这并没有用什么高超的技术,看源码可以发现其实是它已经帮我们处理好了

1.映射元素(map)

//将 T 类型元素映射为 U 类型元素
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));
	}
}

 2.创建容器(ofNullable)

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

3.容器判空(isPresent) 

// 判断 Optional Value 有没有值
public boolean isPresent() {
    return value != null;
}

  • 10
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

涛哥是个大帅比

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值