激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - java8新特性之Optional的深入解析

java8新特性之Optional的深入解析

2021-07-14 16:10Owen Jia Java教程

這篇文章主要給大家介紹了關于java8新特性之Optional的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧

前言

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

本文以jdk1.8.0_111源碼為例

?
1
public final class optional<t> {}

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

基礎測試用例對象:

?
1
2
3
4
5
6
7
8
public class java8optionaltest {
 list<string> stringlist = null;
 icar car = new weilaicar();
}
 
public class weilaicar implements icar {
 integer wheels = new integer(4);

api中提供的4種optional

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

  • public final class optional<t> {
  • public final class optionaldouble {
  • public final class optionalint {
  • public final class optionallong {

@functionalinterface
predicate\consumer\supplier三個接口都是函數式接口

靜態方法of

?
1
2
3
private optional() {
 this.value = null;
}

構造方法被private,不能new但提供了of這樣的靜態方法去初始化類;

?
1
2
3
4
5
6
7
8
9
10
11
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支持你去創建一個空的optional類,這樣的類直接get()會報錯:java.util.nosuchelementexception: no value present

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

present 方法

ispresent是用來判斷optional中對象是否為null,ifpresent的參數是當對象不為null時執行的lamdba表達式。

?
1
2
3
4
5
6
7
public boolean ispresent() {
 return value != null;
}
public void ifpresent(consumer<? super t> consumer) {
 if (value != null)
 consumer.accept(value);
}

示例詳解介紹了ifpresent特性:

?
1
2
3
4
5
6
7
8
9
10
11
12
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對象,所以執行了lambda表達式,而第二級的ifpresent的stringlist是null,所以沒有執行表達式
optional.ifpresent( a -> optional.ofnullable(a.getcar()).ifpresent(b -> pringtest("car:" + (b == null))));
//car:false
//第二級ifpresent的car對象是存在的,所以第二級的表達式執行了

map 方法

源碼提供了兩種map和flatmap。

  • map方法的參數是個當包含的對象不為null時才執行的lambda表達式,返回該表達式執行結果的封裝optional對象,同理支持鏈式調用,逐層深入和遞歸遞進很像;
  • flatmap區別在于lambda表達式的返回結果必須主動包裹optinoal,否則報錯
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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));
 }
}

測試示例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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;//傳統null判斷寫法
if(test != null){
 if(test.getcar() != null){//實際業務里面層級也許會超過3層
  wheel = test.getcar().getwheelcount();
 }
}
pringtest("傳統:"+wheel);
//傳統: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 方法

源碼如下:

?
1
2
3
4
5
6
7
public optional<t> filter(predicate<? super t> predicate) {
 objects.requirenonnull(predicate);
 if (!ispresent())
  return this;
 else
  return predicate.test(value) ? this : empty();
}

filter方法傳入一個斷言語句條件的lambda表達式,返回一個原對象的optional包裝,所以支持鏈式調用;只要記住這三點你便掌握如何使用了。

看下面的例子:

?
1
2
3
4
5
6
7
8
9
10
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 當optional內對象為null就返回這個參數,比較像很多默認值設置;
  • orelseget 基本同orelse,區別是傳入參數支持lambda表達式,返回的就是表達式執行結果;
  • orelsethrow 也是傳入lambda表達式,但是表達式是拋出異常
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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();
 }
}

測試用例如下:

?
1
2
3
4
5
6
7
8
9
10
11
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

總結

官方推出optional絕不會就是替大家判斷一下null,filter\map\orelse這三種使用場景是比較容易想到的,很多業務場景需要慢慢摸索使用。多函數式的用法需要好好掌握,技術發展是非常快速的。

后面會專門開一篇講函數式和lambda表達式用法,保持好奇心關注我的博客。

好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。

原文鏈接:https://blog.shareworld.vip/article/optional01

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 午夜爱爱福利 | 免费国产一级特黄久久 | 欧美高清一级片 | 欧美精品一区二区三区久久久 | 欧美高清一级片 | 日韩色视频在线观看 | 91在线色视频 | 欧日韩 | 夏目友人帐第七季第一集 | 免费永久在线观看黄网 | 久久精品黄 | 日韩欧美电影一区二区三区 | 狠狠撸电影| 日韩中文字幕一区二区三区 | 国产亚洲精品影达达兔 | 98国内自拍在线视频 | 日韩欧美精品中文字幕 | 国产乱淫av片免费观看 | 亚洲精品久久久久久久久久 | 国产成人综合在线 | 国产精品亚洲三区 | 91精品国产综合久久久动漫日韩 | 久久久久久久国产视频 | 亚洲一区播放 | 欧美性久久久 | 日本羞羞影院 | 久久国精品 | 久久96国产精品久久久 | 日本aⅴ在线| 国产寡妇xxxxxxxx性开放 | 国产精品久久77777 | 欧美日本综合 | 亚洲国产精品高潮呻吟久久 | 国产精品久久久久免费视频 | 草久在线 | 91美女视频在线 | 国产一级不卡毛片 | 日韩精品一区二区在线播放 | 成人精品 | 视频一区二区久久 | 国产精品夜色视频一级区 |