joo工作流_让我们用jOOλ在Java 8中流式传输地图

joo工作流

我想找到一种简单的方法来用Java 8流式传输Map 。猜猜是什么? 没有!

为了方便起见,我期望的是以下方法:

public interface Map<K, V> {

    default Stream<Entry<K, V>> stream() {
        return entrySet().stream();
    }    
}

但是没有这样的方法。 可能不存在这种方法的原因可能多种多样,例如:

  • 没有选择keySet()values()作为流源的entrySet() “明确”首选项
  • Map并不是真正的收藏。 这甚至不是一个可Iterable
  • 那不是设计目标
  • EG没有足够的时间

好吧,对于Map进行改型以提供entrySet().stream()并最终实现Iterable<Entry<K, V>> ,这是一个非常令人信服的理由。 那就是我们现在有了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()方法的强烈驱动,这对于使Map.Entry在整个collection API中成为更重要的类型是一个很好的例子(我们更喜欢Tuple2类型,课程)。

让我们继续这种思路。 还有Iterable.forEach()

public interface Iterable<T> {
    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }
}

尽管有细微的差别,但Map.forEach()Iterable.forEach()直观地迭代了各自收集模型的“项”。

  • Iterable.forEach()期望Consumer获得单个值
  • Map.forEach()期望BiConsumer两个值:键和值( 不是 Map.Entry !)

这样考虑:

这使得这两种方法在“鸭子输入意义上”不兼容,这使得两种类型的差异更大

mm!

用jOOλ改善地图

我们发现这很古怪且违反直觉。 实际上, forEach()并不是Map遍历和转换的唯一用例。 我们希望有一个Stream<Entry<K, V>>甚至更好的是Stream<Tuple2<T1, T2>> 。 因此,我们在jOOλ中实现了该功能 ,这是我们为jOOQ的集成测试开发的库。 使用jOOλ,您现在可以将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()
);

您能用它做什么? 如何创建一个新的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)
);

以上两种都将产生:

{a=1, b=2, c=3}

仅作记录,以下是使用标准JDK API交换键和值的方法:

System.out.println(
  map.entrySet()
     .stream()
     .collect(Collectors.toMap(
         Map.Entry::getValue, 
         Map.Entry::getKey
     ))
);

可以做到,但是标准Java API每天的冗长性使得事情很难读/写。

翻译自: https://www.javacodegeeks.com/2014/10/lets-stream-a-map-in-java-8-with-jooλ.html

joo工作流

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值