我們經常會遇到這種情況:首先判斷一個對象是否為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); }