日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

Java使用者的延期执行

發(fā)布時(shí)間:2023/12/3 java 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java使用者的延期执行 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在前面的博客文章(“ 延遲執(zhí)行Java的供應(yīng)商 “),我引用礁HORSTMANN的陳述書中‘ 的Java SE8為真的很急關(guān)于lambda表達(dá)式’,‘所有的lambda表達(dá)式的點(diǎn)被推遲執(zhí)行 ?!?Horstmann在最后一年為Dobb博士的雜志寫了一篇名為“ Java 8中的Lambda表達(dá)式 ”的文章,其中他使用不同的術(shù)語寫了類似的聲明,“ Lambda表達(dá)式是可以傳遞的代碼塊,因此可以之后執(zhí)行一次,一次或多次?!?

在該較早的文章中 ,我研究了JDK中的lambda表達(dá)式如何與標(biāo)準(zhǔn)功能接口Supplier一起使用,以在“僅在必要時(shí)提供”單個(gè)值且未傳遞任何參數(shù)的情況下支持延遲執(zhí)行。 在本文中,我重點(diǎn)介紹JDK提供的示例,這些示例使用Consumer標(biāo)準(zhǔn)功能接口“僅在必要時(shí)”“使用”或“處理”特定代碼塊。 Supplier接受任何參數(shù)并僅返回一個(gè)響應(yīng),而Consumer接受一個(gè)或多個(gè)參數(shù)并且不返回響應(yīng)。 在Supplier上調(diào)用的方法是get()方法,并且是Consumer的accept(T)方法。 根據(jù)定義, Consumer預(yù)計(jì)將有“副作用”,因?yàn)樗跋摹彼峁┑拇a塊。

java.util.function軟件包中提供了許多Consumer風(fēng)格的標(biāo)準(zhǔn)功能接口。 這些都不返回結(jié)果(這就是為什么他們是消費(fèi)者!),但是它們接受的參數(shù)的數(shù)量和類型不同(但是它們都接受至少一個(gè)參數(shù))。 這些在這里列出:

  • 消費(fèi)者 –接受單個(gè)論點(diǎn)的一般Consumer ,將成為本文大部分示例的關(guān)注中心。
  • BiConsumer –接受兩個(gè)參數(shù),而不是一個(gè)參數(shù)(“ 消費(fèi)者的兩類專業(yè)化”)
  • DoubleConsumer –適用于原始double的特殊消費(fèi)者
  • IntConsumer –原始int的專門消費(fèi)者
  • LongConsumer –適用于原始long的專業(yè)消費(fèi)者
  • ObjDoubleConsumer –接受兩個(gè)參數(shù)的專用消費(fèi)者 ,第一個(gè)為Object類型,第二個(gè)為double類型
  • ObjIntConsumer –接受兩個(gè)參數(shù)的專用消費(fèi)者 ,第一個(gè)參數(shù)為Object類型,第二個(gè)參數(shù)為int類型
  • ObjLongConsumer –接受兩個(gè)參數(shù)的專用消費(fèi)者,第一個(gè)參數(shù)為Object類型,第二個(gè)參數(shù)為long類型

本文的其余部分將研究Consumer和相關(guān)類的JDK使用的子集,以幫助演示它們?nèi)绾我约昂螘r(shí)有用。

偷看流元素流

在博客文章“ 使用Stream.peek窺視Java Streams內(nèi)部 ”中,我討論了可用于查看流中流動(dòng)元素的中間操作 Stream.peek(Consumer) 。 這對于了解各種流操作對其各自的流元素所做的操作非常有用。 一種常見的實(shí)現(xiàn)方法是讓提供給peek方法的Consumer是對System.out的調(diào)用。 println將當(dāng)前處理的流元素打印到標(biāo)準(zhǔn)輸出(或記錄該元素或?qū)⑵浯蛴〉綐?biāo)準(zhǔn)錯(cuò)誤)。 Javadoc文檔中為Stream.peek(Consumer)方法提供了一個(gè)示例:

Stream.of("one", "two", "three", "four").filter(e -> e.length() > 3).peek(e -> System.out.println("Filtered value: " + e)).map(String::toUpperCase).peek(e -> System.out.println("Mapped value: " + e)).collect(Collectors.toList());

由于println(-)方法的各種重載版本都接受參數(shù),但不返回任何內(nèi)容,因此它們完全符合“ Consumer”的概念。

在迭代流元素上指定操作

盡管Stream.peek(Consumer)是一個(gè)中間操作,但Stream提供了另外兩個(gè)接受Consumer方法,它們都是終端操作 ,并且都是“針對每個(gè)”方法。 方法Stream.forEach(Consumer)是一種對流的元素以“顯式不確定性”的方式執(zhí)行由提供的Consumer指定的操作的方法。 如果該流具有遇到順序,則Stream.forEachOrdered(Consumer)方法將以所提供的Consumer以流的“ 遇到順序 ”執(zhí)行指定的操作。 在這兩種方法的情況下,基于Consumer的“動(dòng)作”應(yīng)為“ 不干擾” 。 兩種方法都在下面演示。

Set.of("one", "two", "three", "four").stream().forEach(i -> out.println(i.toUpperCase()));Stream.of("one", "two", "three", "four").forEach(i -> out.println(i.toUpperCase()));List.of("one", "two", "three", "four").stream().forEachOrdered(i -> out.println(i.toUpperCase()));Stream.of("one", "two", "three", "four").forEachOrdered(i -> out.println(i.toUpperCase()));

上面的示例看起來非常相似。 當(dāng)使用并行流處理時(shí), forEach可能導(dǎo)致與forEachOrdered截然不同的結(jié)果的最明顯情況是。 在這種情況下,它將使大多數(shù)發(fā)送者使用forEach而不是forEachOrdered 。

在可迭代元素上指定操作

前面的代碼示例顯示了使用Stream.forEach(Consumer)方法來迭代流。 這些示例還演示了如何通過首先在這些集合上調(diào)用stream()對Set和List進(jìn)行此操作。 有方便的方法,但是,通過限定可迭代和執(zhí)行由這些集合的實(shí)現(xiàn),其接受一個(gè)Consumer ,并允許使用該集合的迭代forEach方法。 下一個(gè)代碼清單中顯示了此示例。

Set.of("one", "two", "three", "four").forEach(i -> out.println(i.toUpperCase())); List.of("one", "two", "three", "four").forEach(i -> out.println(i.toUpperCase()));

盡管在上面的示例中使用了集合,但是實(shí)現(xiàn)Iterable的所有對象通常都將支持forEach方法(或違反接口的廣告約定)。

指定映射條目迭代時(shí)的操作

盡管Java的Map接口沒有像Set和List那樣擴(kuò)展Iterable接口,但是Java Map仍然具有類似的功能,可以指定使用者“消費(fèi)” Map每個(gè)條目。 因?yàn)镸ap有兩個(gè)輸入?yún)?shù)(鍵和值),所以它的forEach方法接受BiConsumer而不是到目前為止本文中討論的Consumer 。 接下來顯示一個(gè)簡單的示例。

Map.of("Denver", "Colorado","Cheyenne", "Wyoming","Salt Lake City", "Utah","Boise", "Idaho").forEach((c, s) -> out.println(c + " is the capital of " + s));

走棧

StackWalker是JDK 9的一個(gè)受歡迎的擴(kuò)展,它提供了一種線程安全的方法來細(xì)讀堆棧跟蹤,并且是對StackTraceElement方法的重大改進(jìn)。 對于開發(fā)人員來說,使用StackWalker.walk(Function)可能更常見,但是這篇文章是關(guān)于Consumer ,因此重點(diǎn)是StackWalker.forEach(Consumer) 。 此方法類似于先前討論的Stream.forEach和Iterable.forEach方法,并在下一個(gè)代碼清單中進(jìn)行了演示。

StackWalker.getInstance().forEach(out::println);

盡管JDK對Consumer , BiConsumer以及其他類型的標(biāo)準(zhǔn)Consumer樣式功能接口有更多的JDK使用 ,但本文中我要介紹的最后一個(gè)示例來自O(shè)ptional類。

僅在存在時(shí)應(yīng)用

方法Optional.ifPresent(Consumer)和Optional.ifPresentOrElse(Consumer)推遲執(zhí)行提供的Consumer ,以便僅在Optional不是“空”(包含非null值)的情況下才調(diào)用提供的Consumer 。 這是一個(gè)簡單但功能強(qiáng)大的概念,而簡單且人為的示例說明了它們是如何工作的。

public void demonstrateOptionalIfPresent() {getMiddleName(true).ifPresent(n -> out.println("Middle Name: " + n)); }public void demonstrateOptionalIfPresentOrElse() {getMiddleName(false).ifPresentOrElse(n -> out.println("Middle Name: " + n),() -> displayMissingMiddleName()); }private Optional<String> getMiddleName(final boolean present) {return present ? Optional.of("Wayne") : Optional.empty(); }private void displayMissingMiddleName() {out.println("No middle name provided!"); }

如上面的代碼清單所示,如果Optional不為空,則Optional.ifPresent和JDK 9引入的Optional.ifPresentOrElse()僅調(diào)用提供的Consumer 。 如果Optional為空,則ifPresent方法不執(zhí)行任何操作,而ifPresentOrElse調(diào)用第二個(gè)參數(shù)( Runnable )。

接受一個(gè)或多個(gè)參數(shù)且不返回任何結(jié)果的標(biāo)準(zhǔn)Java功能接口包括一般的Consumer以及某些專門的使用者。 這些對于將執(zhí)行推遲到給定條件發(fā)生之前(例如迭代或確定存在)有用,并且在該條件發(fā)生時(shí)要應(yīng)用的行為涉及一個(gè)或多個(gè)輸入自變量,而無需提供響應(yīng)。 GitHub上提供了本文中顯示的源代碼示例。

翻譯自: https://www.javacodegeeks.com/2018/06/deferred-execution-java-consumer.html

總結(jié)

以上是生活随笔為你收集整理的Java使用者的延期执行的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。