独眼巨人反应组织了Java 8库的寒武纪爆发
什么是獨眼巨人反應?
Lambda表達式和默認方法在Java 8中的出現預示了Java語言十年來最大的結構性變化。 在此基礎上構建了一些新的很酷的API,例如Stream, Optional, CompletableFuture最終Java開發人員可以以更實用的樣式進行編碼。 盡管這是非常受歡迎的,但對于許多增強功能而言,還遠遠不夠。
Stream, Optional, CompletableFuture都共享相同的抽象結構并遵循相同的規則。 但是,API并未就通用方法名稱達成共識,沒關系提供通用接口。 例如, Stream#map / Optional#map變為CompletableFuture#thenApply 。 此外,通常在集合中缺少添加到Stream & Optional的功能。 List#map在哪里?
JDK Stream實現的性能很好,完全是懶惰的,并且設計得很好,可以擴展,但是只提供了一個有限的潛在運算符子集(也許受數據并行性的約束)。 將具有順序Stream擴展(稱為Seq )的步進庫(例如jOOλ)插入到無效空間中。 Seq添加了許多其他的Streaming運算符。 通常,jOOλ添加了許多缺失的功能特征,例如元組。
cyclops-react的核心目標以及添加諸如FutureStreams之類的原始功能,是提供一種將JDK API和第三方功能庫結合在一起的機制。 Java 8推出后,出現了寒武紀的酷庫爆炸式增長。像Javaslang和Project Reactor這樣的庫。 首先, cyclops -react通過擴展JDK并利用jOOλ , pCollections和Agrona之類的其他庫來做到 這 一點 。 這些庫又在可能的情況下擴展了JDK接口,以添加諸如持久性集合之類的功能,并等待免費的Many Producer Single Consumer Queue。
除了重用和擴展JDK接口之外,我們的目標是通過利用第三方標準(例如反應流API)和在沒有設置標準的情況下構建我們自己的抽象,使開發人員可以輕松地與外部庫集成。 我們目前關注的集成庫是Google的Guava,RxJava,Functional Java,Project Reactor和Javaslang 。 我們已經創建了用于包裝諸如Stream, Optional & CompletableFuture類的類型的抽象-以前不存在接口,或者以前不可能存在接口。 我們之所以選擇這些目標,是因為我們在微服務體系結構的生產中使用了Cyclops-react,并且能夠利用正確的技術解決問題并將其與我們的其余代碼庫順利集成是至關重要的。
cyclops-react是一個功能豐富的大型項目,此外還具有許多集成模塊 。 在下面的文章中,我將介紹一些可用的功能,其特定目的是展示cyclops-react如何幫助將JDK上的所有點連接起來,并進入Java 8開源社區的步伐。
擴展JDK
可能的話,cyclops-react擴展了JDK API。 例如, ReactiveSeq添加了用于處理錯誤,異步處理的功能,并且進行了更多擴展,從而擴展了JDK Stream和jOOλ的Seq。 cyclops-react Collection擴展而不是創建新的collection實現,而是實現并擴展了適當的JDK接口。 然后, LazyFutureStream -react LazyFutureStream擴展了ReactiveSeq ,并允許在期貨流上進行聚合操作,就好像它是一個簡單的Stream一樣(這對于異步和LazyFutureStream地處理大量典型的Java I / O操作非常有用)。
ListX擴展了List ,但添加了渴望執行的運算符
ListX<Integer> tenTimes = ListX.of(1,2,3,4).map(i->i*10);cyclops-react增加了許多運算符供用戶探索。 例如,我們可以同時在多個集合中應用函數
反應流API充當數據的生產者(發布者)和消費者(訂戶)之間的天然橋梁。 所有獨眼巨人反應數據類型都從反應流中實現Publisher接口,并且還提供了可以轉換為任何獨眼巨人反應類型的Subscriber實現。 這使得與其他基于反應流的庫(例如Project Reactor)的直接集成變得簡單。
例如,我們可以從任何獨眼巨人發布者(例如SortedSetX懶惰地填充Reactor Flux,或者從Reactor類型中填充獨眼巨人反應類型。
Flux<Integer> stream = Flux.from(SortedSetX.of(1,2,3,4,5,6,7,8)); //Flux[1,2,3,4,5,6,7,8]ListX<Character> list = ListX.fromPublisher(Flux.just("a","b","c"));Reactor Flux和Mono類型可以直接與cyclops-react For理解一起使用(每個受支持的庫在它們的集成模塊中也都有它們自己的本機For理解類集)。
// import static com.aol.cyclops.control.For.*;Publishers.each2(Flux.just(1,2,3), i -> ReactiveSeq.range(i,5),Tuple::tuple).printOut();/* (1, 1) (1, 2) (1, 3) (1, 4) (2, 2) (2, 3) (2, 4) (3, 3) (3, 4) */For理解是一種通過級聯對適當方法的調用來管理帶有flatMap和map方法的類型上的嵌套迭代的方法。 在獨眼巨人反應中,嵌套語句可以訪問先前語句的元素,因此For理解而言,這是管理現有行為的非常有用的方法。 例如,為了確保對可能返回空值的現有方法findId和loadData的調用(如果提供了空參數,則將引發NPE),我們可以利用For理解,僅當返回帶有值的Optional時,該表達式才能安全地執行loadData來自findId()
List<Data> data = For.optional(findId()).optional(this::loadData); //loadData is only called if findId() returns a value類似地,可以使用諸如Try之類的類型來處理來自findId或loadData的異常結果,使用Futures來異步執行鏈接的方法,依此類推。
建立跨庫抽象
Java 8將Monads引入了Java( Stream, Optional, CompletableFuture ),但沒有提供有助于重用的通用接口,實際上, CompletableFuture使用的方法名稱與Optional & Stream用于同一功能的方法名稱明顯不同。 因此map成為thenApply , flatMap thenCompose成為flatMap thenCompose 。 在Java 8世界中,單子已成為一種越來越普遍的模式,但是通常沒有辦法在它們之間進行抽象。 在Cyclops-react中,我們沒有嘗試定義代表monad的接口,而是構建了一組包裝器接口和許多自定義適配器,以使跨Java 8的主要功能樣式庫中的不同實例適應這些包裝器。 包裝器擴展了AnyM ( AnyM縮寫,并且有兩個子接口– AnyMValue表示解析為單個值的任何AnyMValue類型(例如Optional或CompletableFuture )或AnyMSeq最終解析為一個值序列(例如Stream)或列表)。 獨眼巨人擴展包裝器提供了一種機制,用于包裝來自RxJava,Guava,Reactor,FunctionalJava和Javaslang的類型。
//We can wrap any type from Reactor, RxJava, //FunctionalJava, Javaslang, Guava AnyMSeq<Integer> wrapped = Fj.list(List.list(1,2,3,4,5));//And manipulate it AnyMSeq<Integer> timesTen = wrapped.map(i->i*10);cyclops-react提供了一組通用接口,這些包裝器(和其他cyclops-react類型)都繼承自這些接口,從而使開發人員可以編寫更多通用的可重用代碼。 AnyM擴展了反應流發布者,這意味著您可以使任何Javaslang,Guava,FunctionalJava或RxJava類型成為具有Cyclops-react的反應流發布者。
AnyMSeq<Integer> wrapped = Javaslang.traversable(List.of(1,2,3,4,5));//The wrapped type is a reactive-streams publisher Flux<Integer> fromJavaslang = Flux.from(wrapped);wrapped.forEachWithError(System.out::println,System.out::err);此外,來自Cyclops反應的反應性功能直接在AnyM類型上提供。 這意味著,例如,我們可以安排從Javaslang或FunctionalJava流中發出數據的時間–延遲或異步執行reduce操作。
AnyMSeq<Integer> wrapped = Javaslang.traversable(Stream.of(1,2,3,4,5));CompletableFuture<Integer> asyncResult = wrapped.futureOperations(Executors.newFixedThreadPool(1)).reduce(50, (acc, next) -> acc + next); //CompletableFuture[1550]AnyMSeq<Integer> wrapped = FJ.list(list.list(1,2,3,4,5));Eval<Integer> lazyResult = wrapped.map(i -> i * 10).lazyOperations().reduce(50, (acc,next) -> acc + next); //Eval[15500]HotStream<Integer> emitting = wrapped.schedule("0 * * * * ?", Executors.newScheduledThreadPool(1));emitting.connect().debounce(1,TimeUnit.DAYS).forEachWithError(this::logSuccess,this::logFailure);在cyclops-react和新的更廣泛的Java 8生態系統中,都有很多值得探索的地方,希望您自己玩樂,學習Java 8并擴展Java 8的邊界,這將是一次有趣的冒險!
翻譯自: https://www.javacodegeeks.com/2016/05/cyclops-react-organises-cambrian-explosion-java-8-libraries.html
總結
以上是生活随笔為你收集整理的独眼巨人反应组织了Java 8库的寒武纪爆发的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ddos怎么办(ddos如何关闭ip)
- 下一篇: 广东企业备案查询系统(广东企业备案)