Java 9对可选的补充
哇,人們對Java 9的Stream API增添了 真正的興趣。 想要更多? 讓我們看一下……
可選的
可選::流
這不需要任何解釋:
Stream<T> stream();想到的第一個詞是: 終于 ! 最后,我們可以輕松地從可選值流變?yōu)楫?dāng)前值流!
給定一個Optional findCustomer(String customerId)我們必須執(zhí)行以下操作:
public Stream<Customer> findCustomers(Collection<String> customerIds) {return customerIds.stream().map(this::findCustomer)// now we have a Stream<Optional<Customer>>.filter(Optional::isPresent).map(Optional::get); }或這個:
public Stream<Customer> findCustomers(Collection<String> customerIds) {return customerIds.stream().map(this::findCustomer).flatMap(customer -> customer.isPresent()? Stream.of(customer.get()): Stream.empty()); }我們當(dāng)然可以將其推入實(shí)用程序方法中(我希望您這樣做了),但是它仍然不是最佳方法。
現(xiàn)在,讓Optional實(shí)際實(shí)現(xiàn)Stream會很有趣,但是
因此,剩下的唯一選擇是添加一個返回零或一個元素流的方法。 這樣,我們又有兩個選擇來實(shí)現(xiàn)期望的結(jié)果:
public Stream<Customer> findCustomers(Collection<String> customerIds) {return customerIds.stream().map(this::findCustomer).flatMap(Optional::stream) }public Stream<Customer> findCustomers(Collection<String> customerIds) {return customerIds.stream().flatMap(id -> findCustomer(id).stream()); }很難說我喜歡哪個更好-都有優(yōu)點(diǎn)和缺點(diǎn)-但這是另一篇文章的討論。 兩者看起來都比我們之前要做的要好。
現(xiàn)在,我們可以對Optional進(jìn)行延遲操作。
很難說我喜歡哪個更好-都有優(yōu)點(diǎn)和缺點(diǎn)-但這是另一篇文章的討論。 兩者看起來都比我們之前要做的要好。
現(xiàn)在,我們可以對Optional進(jìn)行延遲操作。
另一個小細(xì)節(jié):如果愿意,我們現(xiàn)在可以更輕松地從Optional上的急切操作轉(zhuǎn)移到Stream上的惰性操作。
我想我還沒有用例,但是記住這一點(diǎn)很好。
Leo Leung在CC-BY 2.0下發(fā)布。
可選::或
最后讓我思考的另一個補(bǔ)充! 您多久使用一次Optional并想表達(dá)“使用此選項(xiàng); 除非它是空的,否則在這種情況下我要使用另一個”? 很快我們就可以做到:
Optional<T> or(Supplier<Optional<T>> supplier);假設(shè)我們需要一些客戶數(shù)據(jù),這些數(shù)據(jù)通常是從遠(yuǎn)程服務(wù)獲得的。 但是因?yàn)樵L問它很昂貴并且非常聰明,所以我們有一個本地緩存。 實(shí)際上有兩個,一個在內(nèi)存上,一個在磁盤上。 (我可以看到你畏縮。放松,這只是一個例子。)
這是我們的本地API:
public interface Customers {Optional<Customer> findInMemory(String customerId);Optional<Customer> findOnDisk(String customerId);Optional<Customer> findRemotely(String customerId);}在Java 8中將這些調(diào)用鏈接起來很麻煩(如果您不相信我,請嘗試一下)。 但是使用Optional::or成為小菜一碟:
public Optional<Customer> findCustomer(String customerId) {return customers.findInMemory(customerId).or(() -> customers.findOnDisk(customerId)).or(() -> customers.findRemotely(customerId)); }那不是很酷嗎? 沒有它,我們怎么生活? 勉強(qiáng)可以告訴你。 只是勉強(qiáng)。
可選的:: ifPresentOrElse
對于最后一個,我不太滿意:
void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction);您可以使用它來覆蓋isPresent -if的兩個分支:
public void logLogin(String customerId) {findCustomer(customerId).ifPresentOrElse(this::logLogin,() -> logUnknownLogin(customerId)); }logLogin超載并且還帶了一個客戶,然后記錄了其登錄名。 同樣, logUnknownLogin記錄未知客戶的ID。
現(xiàn)在,我為什么不喜歡它? 因?yàn)樗仁刮彝瑫r執(zhí)行這兩項(xiàng)操作,并且使我無法再進(jìn)行進(jìn)一步的鏈接。 我本來會更愿意這樣做:
Optional<T> ifPresent(Consumer<? super T> action);Optional<T> ifEmpty(Runnable action);上面的情況看起來類似,但更好:
public void logLogin(String customerId) {findCustomer(customerId).ifPresent(this::logLogin).ifEmpty(() -> logUnknownLogin(customerId)); }首先,我發(fā)現(xiàn)它更具可讀性。 其次,它允許我只擁有ifEmpty分支(如果我愿意的話)(而不會因空lambda而使我的代碼混亂)。 最后,它允許我進(jìn)一步鏈接這些呼叫。 要繼續(xù)上面的示例:
public Optional<Customer> findCustomer(String customerId) {return customers.findInMemory(customerId).ifEmpty(() -> logCustomerNotInMemory(customerId)).or(() -> customers.findOnDisk(customerId)).ifEmpty(() -> logCustomerNotOnDisk(customerId)).or(() -> customers.findRemotely(customerId)).ifEmpty(() -> logCustomerNotOnRemote(customerId)).ifPresent(ignored -> logFoundCustomer(customerId)); }剩下的問題如下:將返回類型添加到方法(在這種情況下為Optional::ifPresent )是否是不兼容的更改? 不太明顯,但我目前懶得去調(diào)查。 你知道嗎?
反射
把它們加起來:
- 使用Optional::stream將Optional映射到Stream 。
- 使用Optional::or將空的Optional替換為返回另一個Optional的調(diào)用結(jié)果。
- 使用Optional::ifPresentOrElse可以同時執(zhí)行isPresent-if兩個分支。
很酷!
你怎么看? 我敢肯定那里有人仍然會錯過他最喜歡的手術(shù)。 告訴我怎么回事兒!
翻譯自: https://www.javacodegeeks.com/2016/06/java-9-additions-optional.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的Java 9对可选的补充的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 飞机安卓版下载(飞机安卓版)
- 下一篇: linux命令删除文件(linux命令