Option類型
Optional<T>是一個T對象的封裝相速,比直接指向對象的引用更安全碟渺,正確的使用情況下不會返回Null
使用optional值
optional的值存在
Optional的關鍵,在于 接受正確值或者返回替代值的方法- ifPresent() 方法
如果需要返回值突诬,可以使用 optionalObject.map( function對象 ) 苫拍,類似于Stream的map方法,此處可以將Optional 可選值類旺隙,當做一個大小為 0 或者1 的流绒极,返回的結果也是同樣的 0 或者1 的流。
Optional<String> a=Optional.of("有值");
//無返回值 一個接受String 的consumer的lambda表達式,當a有值時才執(zhí)行
a.ifPresent(s-> System.out.println(s));
//有返回值 接受一個function的函數 返回一個對應類型的Optional對象
Optional<Integer> result=a.map(String::length);
optional的值不存在
optionalObject.orElse() 為空時返回一個自定義值
optionalObject.orElseGet( Function ) 為空時執(zhí)行一個自定義函數蔬捷,并且返回自定義值
optionalObject.orElseThrow() 接受一個返回異常的 Supplier
//2垄提、optional沒有值的處理,有值時正常返回正常值
Optional<String> emptyOptional = Optional.empty();
//為空就返回默認值
System.out.println(emptyOptional.orElse("為空時的默認值"));
//為空進行特殊處理,并自定義返回值
System.out.println(emptyOptional.orElseGet(()->{
System.out.println("值為空啊,我返回空串了");
return "";}));
//為空時拋異常
emptyOptional.orElseThrow(()->new NullPointerException("值為空啊 塔淤,我不管了 我要拋異常摘昌!"));
創(chuàng)建optional值
通過Optional 提供的靜態(tài)方法創(chuàng)建
Optional.empty() 創(chuàng)建一個空的Optional
Optional.of(obj) 從一個對象創(chuàng)建出一個對應的Optional對象速妖,obj如果為空則會拋出空指針異常
Optional.ofNullable() 介于1和2之間高蜂,相當于 Optional a=a==null?Optional.empty():Optional.of(obj)
使用flatMap組合可選值函數
理解:flatmap和map都接受function作為參數,返回一個function結果罕容,如果function已經返回Optional<String> 那么Map返回 Optional<Optional<String>>备恤,但是flatMap會返回Optional<String>。這樣對于多個返回Optional的方法锦秒,可以鏈接組合返回類型為Optional的方法露泊。
static Optional<Integer> f(String a ){
return Optional.of(555);
}
//4、flatMap 組合可選值函數
Optional<String> optional =Optional.of("666");
//接受 Function<? super T, Optional<U>> 旅择,返回的參數必須是Optional,flatMap不會對其進行二次包裝
Optional<Integer> nn=optional.flatMap(OptionTest::f);
//Function<? super T, ? extends U> ,不管返回的參數是啥惭笑,都會包裝一層Optional
Optional<Optional<Integer>> mm= optional.map(OptionTest::f);
對比map和flatMap
map和flatMap都接收一個mapping function參數。
map和flatMap返回的都是Optional類型的數據生真。
當mapping function返回的是Optional類型的數據時沉噩,可以直接使用flatMap,flatMap直接返回該Optional柱蟀。
當mapping function返回的不是Optional類型的數據時川蒙,使用map,因為map會進行一次Optional的包裝长已。
Optional在哪兒用
Optional *****不是***** Serializable畜眨。因此,它不應該用作類的字段术瓮。
如果需要序列化的對象包含 Optional 值康聂,Jackson 庫支持把 *Optional 當作普通對象。也就是說胞四,Jackson *會把空對象看作 null恬汁,而有值的對象則把其值看作對應域的值。這個功能在 jackson-modules-java8 項目中
它在另一種情況下也并不怎么有用撬讽,就是在將其類型用作方法或構建方法的參數時蕊连。這樣做會讓代碼變得復雜,完全沒有必要:
User user = new User("john@gmail.com", "1234", Optional.empty());
*Optional *****主要用作返回類型游昼。在獲取到這個類型的實例后甘苍,如果它有值,你可以取得這個值烘豌,否則可以進行一些替代行為载庭。
Optional 類有一個非常有用的用例,就是將其與流或其它返回* Optional* 的方法結合,以構建流暢的API囚聚。
@Test
public void whenEmptyStream_thenReturnDefaultOptional() {
List<User> users = new ArrayList<>();
User user = users.stream().findFirst().orElse(new User("default", "1234"));
assertEquals(user.getEmail(), "default");
}