欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java8新特性之Optional的深入解析

 更新時間:2019年02月06日 10:30:52   作者:Owen Jia  
這篇文章主要給大家介紹了關(guān)于java8新特性之Optional的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧

前言

最近腦袋發(fā)熱追著java8源碼看的很起勁,還有了執(zhí)念,罪過。

本文以jdk1.8.0_111源碼為例

public final class Optional<T> {}

Optional是一個為了解決NullPointerException設(shè)計而生可以包含對象也可以包含空的容器對象。封裝了很多對空處理的方法也增加了filter、map這樣的檢索利器,其中函數(shù)式編程會有種炫酷到爆的感覺。

基礎(chǔ)測試用例對象:

public class Java8OptionalTest {
 List<String> stringList = null;
 ICar car = new WeiLaiCar();
}

public class WeiLaiCar implements ICar {
 Integer wheels = new Integer(4);
}

Api中提供的4種optional

最核心的當(dāng)屬Optional對象,泛型的引入支持了所有對象類型,又增加對常用場景下的dubbo\int\long進(jìn)行擴展。重點介紹一下Optional對象的方法其他三個類似。

  • public final class Optional<T> {
  • public final class OptionalDouble {
  • public final class OptionalInt {
  • public final class OptionalLong {

@FunctionalInterface
Predicate\Consumer\Supplier三個接口都是函數(shù)式接口

靜態(tài)方法of

private Optional() {
 this.value = null;
}

構(gòu)造方法被private,不能new但提供了of這樣的靜態(tài)方法去初始化類;

public static <T> Optional<T> of(T value) {
 return new Optional<>(value);
}
public static <T> Optional<T> ofNullable(T value) {
 return value == null ? empty() : of(value);
}
public static<T> Optional<T> empty() {
 @SuppressWarnings("unchecked")
 Optional<T> t = (Optional<T>) EMPTY;
 return t;
}

1、empty支持你去創(chuàng)建一個空的optional類,這樣的類直接get()會報錯:java.util.NoSuchElementException: No value present

2、of(x)傳入的對象不能為null,而ofNullable(x)是支持傳入null的對象,一般用這兩個比較多。

present 方法

isPresent是用來判斷optional中對象是否為null,ifPresent的參數(shù)是當(dāng)對象不為null時執(zhí)行的lamdba表達(dá)式。

public boolean isPresent() {
 return value != null;
}
public void ifPresent(Consumer<? super T> consumer) {
 if (value != null)
 consumer.accept(value);
}

示例詳解介紹了ifPresent特性:

Java8OptionalTest test = new Java8OptionalTest();
Optional<Java8OptionalTest> optional = Optional.of(test);

pringTest(optional.isPresent());
//true
optional.ifPresent( a -> pringTest(a.getCar().getClass().getName()));
//com.ts.util.optional.WeiLaiCar
optional.ifPresent( a -> Optional.ofNullable(a.getStringList()).ifPresent(b -> pringTest("StringList:" + (b == null))));
//第一級的ifPresent是存在test對象,所以執(zhí)行了lambda表達(dá)式,而第二級的ifPresent的stringList是null,所以沒有執(zhí)行表達(dá)式
optional.ifPresent( a -> Optional.ofNullable(a.getCar()).ifPresent(b -> pringTest("car:" + (b == null))));
//car:false
//第二級ifPresent的car對象是存在的,所以第二級的表達(dá)式執(zhí)行了

map 方法

源碼提供了兩種map和flatMap。

  • map方法的參數(shù)是個當(dāng)包含的對象不為null時才執(zhí)行的lambda表達(dá)式,返回該表達(dá)式執(zhí)行結(jié)果的封裝optional對象,同理支持鏈?zhǔn)秸{(diào)用,逐層深入和遞歸遞進(jìn)很像;
  • flatMap區(qū)別在于lambda表達(dá)式的返回結(jié)果必須主動包裹Optinoal,否則報錯
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));
 }
}
public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
 Objects.requireNonNull(mapper);
 if (!isPresent())
  return empty();
 else {
  return Objects.requireNonNull(mapper.apply(value));
 }
}

測試示例:

Java8OptionalTest test = new Java8OptionalTest();
Optional<Java8OptionalTest> optional = Optional.of(test);

Optional opt1 = optional.map( a -> a.getCar());
pringTest(opt1.get());
//com.ts.util.optional.WeiLaiCar@5d6f64b1
int wheel = 0;//傳統(tǒng)null判斷寫法
if(test != null){
 if(test.getCar() != null){//實際業(yè)務(wù)里面層級也許會超過3層
  wheel = test.getCar().getWheelCount();
 }
}
pringTest("傳統(tǒng):"+wheel);
//傳統(tǒng):4
Optional opt2 = optional.map( a -> a.getCar()).map(b -> b.getWheelCount());//Optional支持下的寫法
pringTest("optinal:"+opt2.get());
//optinal:4
Optional opt3 = optional.map( a -> a.getStringList()).map(b -> b.size());
pringTest(opt3);
//Optional.empty

Optional opt4 = optional.flatMap(a -> Optional.of(a.getCar()));//主動包裹Optional對象
pringTest(opt4);
//Optional[com.ts.util.optional.WeiLaiCar@5d6f64b1]
Optional opt5 = optional.flatMap(a -> Optional.of(a.getCar())).flatMap(b -> Optional.ofNullable(b.getWheelCount()));
pringTest(opt5);
//Optional[4]

filter 方法

源碼如下:

public Optional<T> filter(Predicate<? super T> predicate) {
 Objects.requireNonNull(predicate);
 if (!isPresent())
  return this;
 else
  return predicate.test(value) ? this : empty();
}

filter方法傳入一個斷言語句條件的lambda表達(dá)式,返回一個原對象的optional包裝,所以支持鏈?zhǔn)秸{(diào)用;只要記住這三點你便掌握如何使用了。

看下面的例子:

Java8OptionalTest test = new Java8OptionalTest();

Optional<Java8OptionalTest> optional = Optional.of(test);

Optional result = optional.filter( a -> a.getCar() != null).filter( b -> b.getClass().getName() != null);
pringTest(result.isPresent()? result.get().getClass().getName(): result.isPresent());
//com.ts.util.Java8OptionalTest
Optional result1 = optional.filter( a -> a.getStringList() != null);
pringTest(result1.get());
//java.util.NoSuchElementException: No value present

orElse 方法

Api提供了三個方法。

  • orElse 當(dāng)optional內(nèi)對象為null就返回這個參數(shù),比較像很多默認(rèn)值設(shè)置;
  • orElseGet 基本同orElse,區(qū)別是傳入?yún)?shù)支持lambda表達(dá)式,返回的就是表達(dá)式執(zhí)行結(jié)果;
  • orElseThrow 也是傳入lambda表達(dá)式,但是表達(dá)式是拋出異常
public T orElse(T other) {
 return value != null ? value : other;
}

public T orElseGet(Supplier<? extends T> other) {
 return value != null ? value : other.get();
}

public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
 if (value != null) {
  return value;
 } else {
  throw exceptionSupplier.get();
 }
}

測試用例如下:

Java8OptionalTest one = null;
Java8OptionalTest test = new Java8OptionalTest();
Optional<Java8OptionalTest> optional = Optional.ofNullable(one);
pringTest(optional);
//Optional.empty
pringTest(optional.orElse(test));
//com.ts.util.Java8OptionalTest@5197848c
pringTest(optional.orElseGet(() -> new Java8OptionalTest()));
//com.ts.util.Java8OptionalTest@5d6f64b1
pringTest(optional.orElseThrow(() -> new RuntimeException("orElseThrow")));
//java.lang.RuntimeException: orElseThrow

總結(jié)

官方推出Optional絕不會就是替大家判斷一下null,filter\map\orElse這三種使用場景是比較容易想到的,很多業(yè)務(wù)場景需要慢慢摸索使用。多函數(shù)式的用法需要好好掌握,技術(shù)發(fā)展是非??焖俚?。

后面會專門開一篇講函數(shù)式和Lambda表達(dá)式用法,保持好奇心關(guān)注我的博客。

好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關(guān)文章

  • springboot?Long?精度丟失問題解決

    springboot?Long?精度丟失問題解決

    這篇文章主要為大家介紹了解決springboot?Long?精度丟失問題的方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • SpringMVC中MultipartFile上傳獲取圖片的寬度和高度詳解

    SpringMVC中MultipartFile上傳獲取圖片的寬度和高度詳解

    本篇文章主要介紹了SpringMVC中MultipartFile上傳獲取圖片的寬度和高度,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • grade構(gòu)建閱讀spring源碼環(huán)境 Idea2020.3的過程

    grade構(gòu)建閱讀spring源碼環(huán)境 Idea2020.3的過程

    這篇文章主要介紹了grade構(gòu)建閱讀spring源碼環(huán)境 Idea2020.3,本文分步驟通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10
  • Spring MVC框架配置方法詳解

    Spring MVC框架配置方法詳解

    這篇文章主要為大家詳細(xì)介紹了Spring MVC框架的配置方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • spring boot啟動加載數(shù)據(jù)原理分析

    spring boot啟動加載數(shù)據(jù)原理分析

    實際應(yīng)用中,我們會有在項目服務(wù)啟動的時候就去加載一些數(shù)據(jù)或做一些事情這樣的需求。這時spring Boot 為我們提供了一個方法,通過實現(xiàn)接口 CommandLineRunner 來實現(xiàn)。下面給大家詳細(xì)介紹下,需要的的朋友參考下吧
    2017-04-04
  • git stash 和unstash的使用操作,git unstash failed

    git stash 和unstash的使用操作,git unstash failed

    這篇文章主要介紹了git stash 和unstash的使用操作,git unstash failed,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • springboot+element-ui實現(xiàn)多文件一次上傳功能

    springboot+element-ui實現(xiàn)多文件一次上傳功能

    這篇文章主要介紹了springboot+element-ui多文件一次上傳功能,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06
  • Java?超詳細(xì)講解十大排序算法面試無憂

    Java?超詳細(xì)講解十大排序算法面試無憂

    這篇文章主要介紹了Java常用的排序算法及代碼實現(xiàn),在Java開發(fā)中,對排序的應(yīng)用需要熟練的掌握,這樣才能夠確保Java學(xué)習(xí)時候能夠有扎實的基礎(chǔ)能力。那Java有哪些排序算法呢?本文小編就來詳細(xì)說說Java常見的排序算法,需要的朋友可以參考一下
    2022-04-04
  • mybatis plus的3種查詢方式(小結(jié))

    mybatis plus的3種查詢方式(小結(jié))

    這篇文章主要介紹了mybatis plus的3種查詢方式(小結(jié)),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • Java HashSet集合存儲遍歷學(xué)生對象代碼實例

    Java HashSet集合存儲遍歷學(xué)生對象代碼實例

    這篇文章主要介紹了Java HashSet集合存儲遍歷學(xué)生對象代碼實例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-04-04

最新評論