让我们用jOOλ在Java 8中流式传输地图
我想找到一種簡單的方法來用Java 8流式傳輸Map 。猜猜是什么? 沒有!
為了方便起見,我期望的是以下方法:
但是沒有這種方法。 不應(yīng)使用這種方法的原因可能多種多樣,例如:
- 沒有選擇keySet()或values()作為流源的entrySet() “明確”首選項
- Map并不是真正的收藏。 它甚至都不是可Iterable
- 那不是設(shè)計目標(biāo)
- EG沒有足夠的時間
好吧,對于Map進(jìn)行改型以提供entrySet().stream()并最終實現(xiàn)Iterable<Entry<K, V>> ,這是一個非常令人信服的理由。 那就是我們現(xiàn)在有了Map.forEach()的事實:
default void forEach(BiConsumer<? super K, ? super V> action) {Objects.requireNonNull(action);for (Map.Entry<K, V> entry : entrySet()) {K k;V v;try {k = entry.getKey();v = entry.getValue();} catch(IllegalStateException ise) {// this usually means the entry is no longer in the map.throw new ConcurrentModificationException(ise);}action.accept(k, v);} }在這種情況下, forEach()接受BiConsumer ,該BiConsumer實際上消耗了映射中的條目。 如果您搜索JDK源代碼,則Map.forEach()之外的BiConsumer類型的引用實際上很少,也許還有幾個CompletableFuture方法和幾個流收集方法。
因此,幾乎可以假定BiConsumer受到此forEach()方法的強(qiáng)烈驅(qū)動,這對于使Map.Entry在整個collection API中成為更重要的類型是一個很好的情況(我們更傾向于使用Tuple2類型,課程)。
讓我們繼續(xù)這種思路。 還有Iterable.forEach() :
public interface Iterable<T> {default void forEach(Consumer<? super T> action) {Objects.requireNonNull(action);for (T t : this) {action.accept(t);}} }盡管有細(xì)微的差別,但Map.forEach()和Iterable.forEach()直觀地迭代了各自收集模型的“條目”。
- Iterable.forEach()期望Consumer獲得單個值
- Map.forEach()期望BiConsumer兩個值:鍵和值( 不是 Map.Entry !)
這樣考慮:
這使得這兩種方法在“鴨子鍵入意義上”不兼容,這使得這兩種類型更加不同
mm!
用jOOλ改善地圖
我們發(fā)現(xiàn)這很古怪且違反直覺。 實際上, forEach()并不是Map遍歷和轉(zhuǎn)換的唯一用例。 我們希望有一個Stream<Entry<K, V>>甚至更好的是Stream<Tuple2<T1, T2>> 。 因此,我們在jOOλ中實現(xiàn)了該功能 ,這是我們?yōu)閖OOQ的集成測試開發(fā)的庫。 使用jOOλ,您現(xiàn)在可以將Map封裝為Seq類型(“ Seq”表示順序流,即具有更多功能特征的流):
Map<Integer, String> map = new LinkedHashMap<>(); map.put(1, "a"); map.put(2, "b"); map.put(3, "c");assertEquals(Arrays.asList(tuple(1, "a"), tuple(2, "b"), tuple(3, "c")),Seq.seq(map).toList() );你能用它做什么? 如何創(chuàng)建一個新的Map ,一次性交換鍵和值:
System.out.println(Seq.seq(map).map(Tuple2::swap).toMap(Tuple2::v1, Tuple2::v2) );System.out.println(Seq.seq(map).toMap(Tuple2::v2, Tuple2::v1) );以上兩種都會產(chǎn)生:
{a=1, b=2, c=3}僅作記錄,以下是使用標(biāo)準(zhǔn)JDK API交換鍵和值的方法:
System.out.println(map.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey)) );可以做到,但是每天標(biāo)準(zhǔn)Java API的冗長性使事情變得很難讀/寫。
翻譯自: https://www.javacodegeeks.com/2014/10/lets-stream-a-map-in-java-8-with-jooλ.html
總結(jié)
以上是生活随笔為你收集整理的让我们用jOOλ在Java 8中流式传输地图的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 易展路由器有线连接怎么操作易路路由器如何
- 下一篇: 致电以验证您的JavaFX UI的响应能