import java.util.Optional; /** * java 8新特性 * * @author wang-xiaoming * @date 2019年7月2日 */ public class OptionalTest { public static void ofNullable(String value) { Optional<String> opt = Optional.ofNullable(value); System.out.println("【ofNullable】,value:" + opt.get()); } public static void of(String value) { Optional<String> opt = Optional.of(value); System.out.println("【of】,value:" + opt.get()); } /** * 有值則返回值,沒有則返回【指定屬性】 * * @param value */ public static void orElse(String value) { String orElse = Optional.ofNullable(value).orElse("default"); System.out.println("【orElse】,value:" + orElse); } /** * 有值則返回值,沒有則執行‘->’后的【執行方法】 * * @param value */ public static void orElseGet(String value) { String orElseGet = Optional.ofNullable(value).orElseGet(() -> "default"); System.out.println("【orElseGet】,value:" + orElseGet); } /** * 判斷當前value是否為null,為null,返回false;不為null,返回true * * @param value */ public static void isPresent(String value) { boolean present = Optional.ofNullable(value).isPresent(); System.out.println("【isPresent】,result:" + present); } /** * ep:當拋出NPE時,可以自己指定異常 * * @param value */ public static void orElseThrow(String value) { String orElseThrow = Optional.ofNullable(value).orElseThrow(() -> new IllegalArgumentException()); System.out.println("【orElseThrow】,exception:" + orElseThrow); } /** * 轉換值-map map() 對值應用(調用)作為參數的函數,然后將返回的值包裝在 Optional 中。這就使對返回值進行鏈試調用的操作成為可能 * * @param user */ public static void map(User user) { String map = Optional.ofNullable(user).map(u -> u.getName()).orElse("轉換值-map"); System.out.println("【map】,result:" + map); } /** * 轉換值-flatMap 既然 getter 方法返回 String 值的 Optional,你可以在對 User 的 Optional 對象調用 flatMap() 時,用它作為參數 * * @param user */ public static void flatMap(User user) { String flatMap = Optional.ofNullable(user).flatMap(u -> u.getHobby()).orElse("轉換值-flatMap"); System.out.println("【flatMap】,result:" + flatMap); } /** * 添加過濾 * * @param user */ public static void filter(User user) { boolean filter = Optional.ofNullable(user).filter(u -> u.getName() != null && u.getName().contains("m")).isPresent(); System.out.println("【filter】,result:" + filter); } /** * 簡化if...else...? * * @param user * @param type */ public static void doCheck(User user, int type) { String countryName = ""; if (type == 0) { countryName = Optional.ofNullable(user).flatMap(u -> u.getAddress()).flatMap(u -> u.getCountry()) .map(c -> c.getName()).orElse("濮陽"); } else if (type == 1) { countryName = Optional.ofNullable(user).flatMap(User::getAddress).flatMap(Address::getCountry) .map(Country::getName).orElse("濮陽"); } System.out.println("【doCheck】,result:" + countryName); } public static final String value = null; public static final User user0 = new User(); public static void main(String[] args) { // of(null);// Exception in thread "main" java.lang.NullPointerException // ofNullable(null);// Exception in thread "main" java.util.NoSuchElementException: No value present // orElse(null);// 【orElse】,value:default // orElseGet(null);// 【orElseGet】,value:default // isPresent(null);// 【isPresent】,result:false // orElseThrow(null);// Exception in thread "main" java.lang.IllegalArgumentException // map(new User(6, null, "籃球-basketball"));// 【map】,result:轉換值-map // flatMap(new User(6, "xm", null));// 【flatMap】,result:轉換值-flatMap // filter(new User(6, "xx", "籃球-basketball"));// 【filter】,result:false // 正常情況下,拿出用戶城市名稱 /*if (user != null) { Address address = user.getAddress(); if (address != null) { Country country = address.getCountry(); if (country != null) { String isocode = country.getIsocode(); if (isocode != null) { isocode = isocode.toUpperCase(); } } } }*/ doCheck(new User(6, "xx", "籃球-basketball"), 0);// 【doCheck】,result:濮陽s doCheck(new User(6, "xx", "籃球-basketball"), 1);// 【doCheck】,result:濮陽s } } /** * 用戶 * * @author wang-xiaoming * @date 2019年7月1日 */ class User { private Integer sno; private String name; private String hobby; private Address address; public Integer getSno() { return sno; } public void setSno(Integer sno) { this.sno = sno; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Optional<String> getHobby() { return Optional.ofNullable(hobby); } public void setHobby(String hobby) { this.hobby = hobby; } public Optional<Address> getAddress() { return Optional.ofNullable(address); } public void setAddress(Address address) { this.address = address; } public User(Integer sno, String name, String hobby) { super(); this.sno = sno; this.name = name; this.hobby = hobby; } public User() { super(); } } /** * 地址 * * @author wang-xiaoming * @date 2019年7月1日 */ class Address { private Country country; public Optional<Country> getCountry() { return Optional.ofNullable(country); } public void setCountry(Country country) { this.country = country; } } /** * 城市 * * @author wang-xiaoming * @date 2019年7月1日 */ class Country { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
雖然參考網上有查到一些示例,但是感覺用到的地方有限,就上段代碼中備注掉的傳統非空判斷,其實沒有必要將每個對象取出,直接判斷也行,不過為了代碼簡潔,新特性需要多加借鑒。
下面的這個例子倒是有讓人眼前一亮的感覺,如有更多漸變代碼編程實例,歡迎留言!
// 求出集合中小於4的個數 // int[] arr = {0, 2, 5, 8, -6}; Integer[] arr = {null, 2, 5, 8, -6}; List<Integer> list = Arrays.asList(arr); System.out.println(list.stream().filter(rand -> rand != null && rand < 4).count());
套用公司的一句話:我們的目標是簡單、直接地解決問題,任何復雜的套路都是耍流氓!