java 补充日期_Java 9对可选的补充
java 補(bǔ)充日期
哇,人們真的對Java 9對Stream API的添加感興趣。 想要更多? 讓我們看一下……
可選的
可選::流
無需解釋:
Stream<T> stream();想到的第一個(gè)詞是: 終于 ! 最后,我們可以輕松地從可選值流變?yōu)楫?dāng)前值流!
給定一個(gè)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); }或這個(gè):
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會很有趣,但是
因此,剩下的唯一選擇是添加一個(gè)返回零個(gè)或一個(gè)元素流的方法。 有了這個(gè),我們又有兩個(gè)選擇來實(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()); }很難說我喜歡哪個(gè)更好-都有優(yōu)點(diǎn)和缺點(diǎn)-但這是另一篇文章的討論。 兩者看起來都比我們之前要做的要好。
現(xiàn)在,我們可以對Optional進(jìn)行延遲操作。
很難說我喜歡哪個(gè)更好-都有優(yōu)點(diǎn)和缺點(diǎn)-但這是另一篇文章的討論。 兩者看起來都比我們之前要做的要好。
現(xiàn)在,我們可以對Optional進(jìn)行延遲操作。
另一個(gè)小細(xì)節(jié):如果愿意,我們現(xiàn)在可以更輕松地從Optional上的急切操作轉(zhuǎn)移到Stream上的惰性操作。
我想我還沒有用例,但是記住這一點(diǎn)很好。
Leo Leung在CC-BY 2.0下發(fā)布。
可選::或
最后讓我思考的另外一個(gè)補(bǔ)充! 您有多長時(shí)間使用一次Optional并想表達(dá)“使用此選項(xiàng); 除非它是空的,否則在這種情況下我要使用另一個(gè)”? 很快我們就可以做到:
Optional<T> or(Supplier<Optional<T>> supplier);假設(shè)我們需要一些客戶數(shù)據(jù),這些數(shù)據(jù)通常是從遠(yuǎn)程服務(wù)獲得的。 但是因?yàn)樵L問它很昂貴并且非常聰明,所以我們有一個(gè)本地緩存。 實(shí)際上有兩個(gè),一個(gè)在內(nèi)存上,一個(gè)在磁盤上。 (我可以看到你畏縮。放松,這只是一個(gè)例子。)
這是我們的本地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
對于最后一個(gè),我不太滿意:
void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction);您可以使用它來覆蓋isPresent -if的兩個(gè)分支:
public void logLogin(String customerId) {findCustomer(customerId).ifPresentOrElse(this::logLogin,() -> logUnknownLogin(customerId)); }logLogin超載并且還帶了一個(gè)客戶,然后記錄了其登錄名。 同樣, logUnknownLogin記錄未知客戶的ID。
現(xiàn)在,我為什么不喜歡它? 因?yàn)樗仁刮彝瑫r(shí)執(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替換為返回另一個(gè)Optional的調(diào)用結(jié)果。
- 使用Optional::ifPresentOrElse可以執(zhí)行isPresent-if兩個(gè)分支。
很酷!
你怎么看? 我敢肯定那里有人仍然會錯(cuò)過他最喜歡的手術(shù)。 告訴我怎么回事兒!
翻譯自: https://www.javacodegeeks.com/2016/06/java-9-additions-optional.html
java 補(bǔ)充日期
總結(jié)
以上是生活随笔為你收集整理的java 补充日期_Java 9对可选的补充的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 华为p20如何连接电脑数据(华为p20如
- 下一篇: dynamodb java_使用Java