我们经常会遇到这种情况:首先判断一个对象是否为null,如果不为null,获取一个对象中的一个属性,如果该属性不为null,又获取该属性的属性,如果该属性的属性不为null,又获取属性的属性的属性;

使用Java8中类Optional优雅解决

 

例子

一个pojo类;

该类有两个属性,有个属性Project是对象,Project也有属性是DiscoverCenter也是对象,DiscoverCenter中有String属性discoverName;

build方法初始化一个Org对象,并给其属性赋值。

import lombok.Data;

@Data
public class Org {
    private String name;
    private Project project;

    @Data
    public static class Project {
        private DiscoverCenter discoverCenter;
    }

    @Data
    public static class DiscoverCenter {
        private String discoverName;
    }

    public static Org build(String name,String discoverName){
        DiscoverCenter discoverCenter = new DiscoverCenter();
        discoverCenter.setDiscoverName(discoverName);

        Project project = new Project();
        project.setDiscoverCenter(discoverCenter);

        Org org = new Org();
        org.setProject(project);
        org.setName(name);

        return org;
    }

    private Org(){}
}

 

现在我们要做的事情是获得嵌套对象最内层的属性String discoverName;

先初始化:

public class TestJava8Optional {
    private Org org;
    @Before
    public void init(){
        org = Org.build("Alibaba", "Nacos");
    }

 

用最常规的if-else方式,逐层判断其属性,不为null,才继续获取属性:

@Test
    public void ifElse(){
        if (null != org){
            Org.Project project = org.getProject();
            if(null != project){
                Org.DiscoverCenter discoverCenter = project.getDiscoverCenter();
                if(null != discoverCenter){
                    String discoverName = discoverCenter.getDiscoverName();
                    System.out.println(discoverName);
                    return;
                }
            }
        }

        throw new IllegalArgumentException("Invalid Object.");

    }

 

 

用Java8 Optional类来处理,先判断org不为null,然后在判断它的属性project,继续逐层判断……

@Test
    public void testNestedObject(){

        String s = Optional.ofNullable(org)
                .map(o -> o.getProject())
                .map(p -> p.getDiscoverCenter())
                .map(d -> d.getDiscoverName())
                .orElseThrow(() -> new IllegalArgumentException("Invalid Object."));
        System.out.println(s);
    }

 

是不是比上面的if-else看起来更加简洁和清晰;

Optional.ofNullable方法是可以接受null值的,Optional的map()函数返回的Optional的泛型是map函数中lambda表达式返回的对象类型,orElseThrow()函数表示如果其中上面一个map函数中的lambda表达式,就抛出的异常。

 

下面对一个嵌套的Map对象获取最内层的value:

/**
     * 获取嵌套最内部的value
     */
    @Test
    public void testNestedMap(){
        Map<String,Object> map = new HashMap<>();
        Map<String,Object> project = new HashMap<>();
        project.put("Nacos","discover");

        Map<String,Object> alibaba = new HashMap<>();
        alibaba.put("project",project);

        Map<String,Object> org = new HashMap<>();
        org.put("alibaba",alibaba);

        map.put("org",org);
        Object o1 = Optional.ofNullable(map)
                .map(m -> m.get("org"))
                .map(o -> ((Map) o).get("alibaba"))
                .map(a -> ((Map) a).get("project"))
                .map(p -> ((Map) p).get("Nacos"))
                .orElse("default value");

        System.out.println(o1);
    }