一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專(zhuān)注于服務(wù)器技術(shù)及軟件下載分享
分類(lèi)導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - java8新特性之Optional的深入解析

java8新特性之Optional的深入解析

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

這篇文章主要給大家介紹了關(guān)于java8新特性之Optional的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

前言

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

本文以jdk1.8.0_111源碼為例

?
1
public final class optional<t> {}

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

基礎(chǔ)測(cè)試用例對(duì)象:

?
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

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

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

@functionalinterface
predicate\consumer\supplier三個(gè)接口都是函數(shù)式接口

靜態(tài)方法of

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

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

?
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支持你去創(chuàng)建一個(gè)空的optional類(lèi),這樣的類(lèi)直接get()會(huì)報(bào)錯(cuò):java.util.nosuchelementexception: no value present

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

present 方法

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

?
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))));
//第一級(jí)的ifpresent是存在test對(duì)象,所以執(zhí)行了lambda表達(dá)式,而第二級(jí)的ifpresent的stringlist是null,所以沒(méi)有執(zhí)行表達(dá)式
optional.ifpresent( a -> optional.ofnullable(a.getcar()).ifpresent(b -> pringtest("car:" + (b == null))));
//car:false
//第二級(jí)ifpresent的car對(duì)象是存在的,所以第二級(jí)的表達(dá)式執(zhí)行了

map 方法

源碼提供了兩種map和flatmap。

  • map方法的參數(shù)是個(gè)當(dāng)包含的對(duì)象不為null時(shí)才執(zhí)行的lambda表達(dá)式,返回該表達(dá)式執(zhí)行結(jié)果的封裝optional對(duì)象,同理支持鏈?zhǔn)秸{(diào)用,逐層深入和遞歸遞進(jìn)很像;
  • flatmap區(qū)別在于lambda表達(dá)式的返回結(jié)果必須主動(dòng)包裹optinoal,否則報(bào)錯(cuò)
?
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));
 }
}

測(cè)試示例:

?
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;//傳統(tǒng)null判斷寫(xiě)法
if(test != null){
 if(test.getcar() != null){//實(shí)際業(yè)務(wù)里面層級(jí)也許會(huì)超過(guò)3層
  wheel = test.getcar().getwheelcount();
 }
}
pringtest("傳統(tǒng):"+wheel);
//傳統(tǒng):4
optional opt2 = optional.map( a -> a.getcar()).map(b -> b.getwheelcount());//optional支持下的寫(xiě)法
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()));//主動(dòng)包裹optional對(duì)象
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方法傳入一個(gè)斷言語(yǔ)句條件的lambda表達(dá)式,返回一個(gè)原對(duì)象的optional包裝,所以支持鏈?zhǔn)秸{(diào)用;只要記住這三點(diǎn)你便掌握如何使用了。

看下面的例子:

?
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提供了三個(gè)方法。

  • orelse 當(dāng)optional內(nèi)對(duì)象為null就返回這個(gè)參數(shù),比較像很多默認(rèn)值設(shè)置;
  • orelseget 基本同orelse,區(qū)別是傳入?yún)?shù)支持lambda表達(dá)式,返回的就是表達(dá)式執(zhí)行結(jié)果;
  • orelsethrow 也是傳入lambda表達(dá)式,但是表達(dá)式是拋出異常
?
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();
 }
}

測(cè)試用例如下:

?
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

總結(jié)

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

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

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

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 69japanese日本100 6969精品视频在线观看 | 美女的让男人桶爽网站 | 99久久99久久免费精品蜜桃 | 二次元美女脱裤子让男人桶爽 | 国产精品久久久天天影视香蕉 | 精品无码久久久久久久久 | 欧美激情综合 | 九色PORNY丨视频入口 | 日本四虎影视 | 日韩欧美国产成人 | 久久99r66热这里有精品 | 国产成人手机在线好好热 | 红怡院欧洲 | 国产精品永久免费视频 | 久久精品视在线观看2 | 色老板影视 | 国产成人精品一区二三区 | 精品成人一区二区 | 波多野结衣同性系列698 | 亚洲精品国产成人中文 | 国产色视频一区二区三区 | 欧美图片小说 | 日韩欧美亚洲每日更新网 | 色综合中文字幕在线亚洲 | 精品无码久久久久久久动漫 | 国产日韩欧美综合在线 | 26uuu老色哥| 色播影院性播影院私人影院 | 日本免费久久久久久久网站 | 国产欧美成人免费观看 | 91精品国产综合久久消防器材 | 欧美va在线| 湿好紧太硬了我太爽了 | free嫩白的12sex性自由 | 久久天堂成人影院 | 我和黑色丝袜班主任 | 久久99re热在线播放7 | 欧美综合一区二区三区 | 国色天香社区在线视频播放 | 亚洲视频在线一区二区三区 | 贰佰麻豆剧果冻传媒一二三区 |