中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

如何使用JavaOptional類(lèi)-創(chuàng)新互聯(lián)

這篇文章主要講解了“如何使用Java Optional類(lèi)”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“如何使用Java Optional類(lèi)”吧!

成都創(chuàng)新互聯(lián)公司從2013年開(kāi)始,是專(zhuān)業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元青銅峽做網(wǎng)站,已為上家服務(wù),為青銅峽各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:13518219792

注意:示例代碼要求使用Java 11及更高版本。所有代碼在 Vavr0.10.2環(huán)境下完成測(cè)試。

Java Optional 簡(jiǎn)介

Optional 并不是什么新概念,像 Haskell、Scala 這樣的函數(shù)式編程語(yǔ)言已經(jīng)提供了實(shí)現(xiàn)。調(diào)用方法后,返回值未知或者不存在(比如 null)的情況下,用 Optional 處理非常好用。下面通過(guò)實(shí)例進(jìn)行介紹。

新建 Optional 實(shí)例

首先,需要獲得 Optional 實(shí)例,有以下幾種方法可以新建 Optional 實(shí)例。不僅如此,還可以創(chuàng)建empty Optional。方法一,通過(guò) value 創(chuàng)建,過(guò)程非常簡(jiǎn)單:

Optional<Integer> four = Optional.of(Integer.valueOf(4));
if (four.isPresent){
System.out.println("Hoorayy! We have a value");
} else {
System.out.println("No value");
}

為Integer 4 新建一個(gè)Optional實(shí)例。這種方法得到的 Optional 始終包含一個(gè) value 且不為 null,例如上面這個(gè)示例。使用 ifPresent() 可以檢查value是否存在。可以注意到 four 不是 Integer,而是一個(gè)裝有整數(shù)的容器。如果確認(rèn) value 存在,可以用 get() 方法執(zhí)行拆箱操作。具有諷刺意味的是,調(diào)用 get() 前如果不進(jìn)行檢查,可能會(huì)拋出 NoSuchElementException。

方法二,得到 Optional 對(duì)象的另一種方法是使用 stream。Stream提供的一些方法會(huì)返回Optional,可以用來(lái)檢查結(jié)果是否存在,例如:

  • findAny 

  • findFirst 

  • max 

  • min 

  • reduce 

查看下面的代碼段:

Optional<Car> car = cars.stream().filter(car->car.getId().equalsIgnoreCase(id)).findFirst();

方法三,使用 Nullable 新建 Optional??赡墚a(chǎn)生 null:

Optional<Integer> nullable = Optional.ofNullable(client.getRequestData());

最后,可以新建一個(gè) empty Optional:

Optional<Integer> nothing = Optional.empty();

如何使用 Optional

獲得 Optional 對(duì)象后即可使用。一種典型的場(chǎng)景是在 Spring 倉(cāng)庫(kù)中根據(jù) Id 查找記錄??梢允褂?Optional 實(shí)現(xiàn)代碼邏輯,避免 null 檢查(順便提一下,Spring 也支持 Vavr Option)。比如,從圖書(shū)倉(cāng)庫(kù)里查找一本書(shū)。

Optional<Book> book = repository.findOne("some id");

首先,如果有這本書(shū),可以繼續(xù)執(zhí)行對(duì)應(yīng)的業(yè)務(wù)邏輯。在前面的章節(jié)用 if-else實(shí)現(xiàn)了功能。當(dāng)然,還有其他辦法:Optional 提供了一個(gè)方法,接收 Consumer 對(duì)象作為輸入:

repository.findOne("some id").ifPresent(book -> System.out.println(book));

還可以直接使用方法引用,看起來(lái)更簡(jiǎn)單:

repository.findOne("some id").ifPresent(System.out::println);

如果倉(cāng)庫(kù)中沒(méi)有該書(shū),可以用ifPresentOrElseGet提供回調(diào)函數(shù):

repository.findOne("some id").ifPresentOrElseGet(book->{
// 如果 value 存在
}, ()->{
// 如果 value 不存在
});

如果結(jié)果不存在,可以返回另一個(gè)value:

Book result = repository.findOne("some id").orElse(defaultBook);

但是,Optional 也有缺點(diǎn),使用時(shí)需要注意。最后一個(gè)例子中,“確?!睙o(wú)論如何都能獲得一本書(shū),可能在倉(cāng)庫(kù)中,也可能來(lái)自 orElse。但如果默認(rèn)的返回值不是常量或者需要支持一些復(fù)雜方法該怎么辦?首先,Java 無(wú)論如何都會(huì)執(zhí)行 findOne,然后調(diào)用 orElse方法。默認(rèn)返回值可以為常量,但正如我之前所說(shuō)那樣,執(zhí)行過(guò)程比較耗時(shí)。

另一個(gè)示例

下面用一個(gè)簡(jiǎn)單的示例介紹如何實(shí)際使用 Optional 和 Option 類(lèi)。有一個(gè) CarRepository,可以根據(jù)提供的 ID(比如車(chē)牌號(hào))查找汽車(chē),接下來(lái)用這個(gè)示例介紹如何使用 Optional 和 Option。

首先,加入下面代碼

從 POJO 類(lèi) Car 開(kāi)始。它遵循 immutable 模式,所有字段都標(biāo)記為 final,只包含 getter 沒(méi)有 setter。初始化時(shí)提供所有數(shù)據(jù):

public class Car {
   private final String name;
   private final String id;
   private final String color;
   public Car (String name, String id, String color){
       this.name = name;
       this.id = id;
       this.color = color;
   }
   public String getId(){
       return id;
   }
   public String getColor() {
       return color;
   }
   public String getName() {
       return name;
   }
   @Override
   public String toString() {
       return "Car "+name+" with license id "+id+" and of color "+color;
   }
}

接下來(lái)創(chuàng)建 CarRepository類(lèi)。提供兩種方法根據(jù)Id查找汽車(chē):一種是老辦法,使用 Optional。和之前在 Spring 倉(cāng)庫(kù)的做法類(lèi)似,結(jié)果可能為 null。

publicclass CarRepository {
   private List<Car> cars;
   public CarRepository(){
      getSomeCars();
   }
   Car findCarById(String id){
       for (Car car: cars){function(){   //外匯跟單www.gendan5.com            if (car.getId().equalsIgnoreCase(id)){
               return car;
           }
       }
       return null;
   }
   Optional<Car> findCarByIdWithOptional(String id){
       return cars.stream().filter(car->car.getId().equalsIgnoreCase(id)).findFirst();
   }
   private void getSomeCars(){
       cars = new ArrayList<>();
       cars.add(new Car("tesla", "1A9 4321", "red"));
       cars.add(new Car("volkswagen", "2B1 1292", "blue"));
       cars.add(new Car("skoda", "5C9 9984", "green"));
       cars.add(new Car("audi", "8E4 4321", "silver"));
       cars.add(new Car("mercedes", "3B4 5555", "black"));
       cars.add(new Car("seat", "6U5 3123", "white"));
   }
}

注意:初始化過(guò)程會(huì)在倉(cāng)庫(kù)中添加一些汽車(chē)模擬數(shù)據(jù),便于演示。為了突出重點(diǎn),避免問(wèn)題復(fù)雜化,下面的討論專(zhuān)注于 Optional 和 Option。

使用Java Optional

使用JUnit創(chuàng)建一個(gè)新測(cè)試:

@Test
void getCarById(){
   Car car = repository.findCarById("1A9 4321");
   Assertions.assertNotNull(car);
   Car nullCar = repository.findCarById("M 432 KT");
   Assertions.assertThrows(NullPointerException.class, ()->{
       if (nullCar == null){
           throw new NullPointerException();
       }
   });
}

上面的代碼段采用了之前的老辦法。查找捷克牌照1A9 4321對(duì)應(yīng)的汽車(chē),檢查該車(chē)是否存在。輸入俄羅斯車(chē)牌找不到對(duì)應(yīng)的汽車(chē),因?yàn)閭}(cāng)庫(kù)中只有捷克車(chē)。結(jié)果為 null 可能會(huì)拋出 NullPointerException。

接下來(lái)用Java Optional。第一步,獲得 Optional 實(shí)例,從存儲(chǔ)庫(kù)中使用指定方法返回 Optional:

@Test
void getCarByIdWithOptional(){
   Optional<Car> tesla = repository.findCarByIdWithOptional("1A9 4321");
   tesla.ifPresent(System.out::println);
}

這時(shí)調(diào)用findCarByIdWithOptional方法打印車(chē)輛信息(如果有的話)。運(yùn)行程序,得到以下結(jié)果:

Car tesla with license id 1A9 4321 and of color red

但是,如果代碼中沒(méi)有特定方法該怎么辦?這種情況可以從方法返回可能包含 null 的 Optional,稱為nullable。

Optional<Car> nothing = Optional.ofNullable(repository.findCarById("5T1 0965"));
Assertions.assertThrows(NoSuchElementException.class, ()->{
   Car car = nothing.orElseThrow(()->new NoSuchElementException());
});

上面這段代碼段中,我們發(fā)現(xiàn)了另一種方法。通過(guò) findCarById 創(chuàng)建 Optional,如果未找到汽車(chē)可以返回 null。沒(méi)有找到車(chē)牌號(hào)5T1 0965汽車(chē)時(shí),可以用 orElseThrow 手動(dòng)拋出 NoSuchElementException。另一種情況,如果請(qǐng)求的數(shù)據(jù)不在倉(cāng)庫(kù)中,可以用orElse返回默認(rèn)值:

Car audi = repository.findCarByIdWithOptional("8E4 4311")
           .orElse(new Car("audi", "1W3 4212", "yellow"));
  if (audi.getColor().equalsIgnoreCase("silver")){
    System.out.println("We have silver audi in garage!");
  } else {
    System.out.println("Sorry, there is no silver audi, but we called you a taxi");
}

好的,車(chē)庫(kù)里沒(méi)有找到銀色奧迪,只好打車(chē)了!

使用 Vavr Option

Vavr OptionOption提供了另一種解決辦法。首先,在項(xiàng)目中添加依賴,(使用 Maven)安裝 Vavr:

<dependency>
  <groupId>io.vavr</groupId>
  <artifactId>vavr</artifactId>
  <version>0.10.2</version>
</dependency>

簡(jiǎn)而言之,Vavr 提供了類(lèi)似的 API 新建 Option 實(shí)例。可以從 nullable 新建 Option 實(shí)例,像下面這樣:

Option<Car> nothing = Option.of(repository.findCarById("T 543 KK"));

也可以用 none 靜態(tài)方法創(chuàng)建一個(gè)empty容器:

Option<Car> nullable = Option.none();

此外,還有一種方法可以用 Java Optional 新建 Option??聪旅孢@段代碼:

Option<Car> result = Option.ofOptional(repository.findCarByIdWithOptional("5C9 9984"));

使用 Vavr Option,可以使用與 Optional相同的 API 來(lái)完成上述任務(wù)。例如,設(shè)置默認(rèn)值:

Option<Car> result = Option.ofOptional(repository.findCarByIdWithOptional("5C9 9984"));
Car skoda = result.getOrElse(new Car("skoda", "5E2 4232", "pink"));
System.out.println(skoda);

或者,請(qǐng)求的數(shù)據(jù)不存在時(shí)可以拋出異常:

Option<Car> nullable = Option.none();
Assertions.assertThrows(NoSuchElementException.class, ()->{
nullable.getOrElseThrow(()->new NoSuchElementException());
});

另外,當(dāng)數(shù)據(jù)不可用時(shí),可以執(zhí)行以下操作:

nullable.onEmpty(()->{
///runnable
});

如何根據(jù)數(shù)據(jù)是否存在來(lái)執(zhí)行相應(yīng)操作,類(lèi)似 Optional 中 ifPresent?有幾種實(shí)現(xiàn)方式。與 Optional 中 isPresent 類(lèi)似,在 Option 中對(duì)應(yīng)的方法稱為 isDefined:

if (result.isDefined()){
// 實(shí)現(xiàn)功能
}

然而,使用 Option能擺脫 if-else。是否可以用Optional相同的方式完成?使用 peek 操作:

result.peek(val -> System.out.println(val)).onEmpty(() -> System.out.println("Result is missed"));

此外,Vavr Option還提供了一些其他非常有用的方法,在函數(shù)式編程上比Optional類(lèi)效果更好。因此,建議您花一些時(shí)間來(lái)探索 Vavr Option javadocs嘗試使用這些API。我會(huì)持續(xù)跟進(jìn)一些類(lèi)似 map、narrow、isLazy 和 when 這樣有趣的功能。

感謝各位的閱讀,以上就是“如何使用Java Optional類(lèi)”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)如何使用Java Optional類(lèi)這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

網(wǎng)頁(yè)標(biāo)題:如何使用JavaOptional類(lèi)-創(chuàng)新互聯(lián)
URL地址:http://www.rwnh.cn/article38/hdppp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站網(wǎng)站制作、定制網(wǎng)站響應(yīng)式網(wǎng)站、微信公眾號(hào)、關(guān)鍵詞優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運(yùn)營(yíng)
义乌市| 丽江市| 那坡县| 从化市| 宁化县| 西宁市| 绥化市| 邮箱| 当雄县| 昔阳县| 郧西县| 馆陶县| 乌兰浩特市| 舒城县| 英德市| 东宁县| 皋兰县| 驻马店市| 阜南县| 嘉义市| 凌云县| 怀仁县| 佛山市| 遵义市| 涡阳县| 建瓯市| 七台河市| 东城区| 汾阳市| 华池县| 栖霞市| 阜平县| 大洼县| 文成县| 孝感市| 温宿县| 绥棱县| 安丘市| 侯马市| 江源县| 兴宁市|