首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用java streams将列表转换为映射

使用java streams将列表转换为映射
EN

Stack Overflow用户
提问于 2018-06-04 05:23:24
回答 2查看 53关注 0票数 1

我在我的代码中重复了以下模式:

代码语言:javascript
复制
class X<T, V>
{
    V doTransform(T t) {
        return null; // dummy implementation
    }

    Map<T, V> transform(List<T> item) {
        return item.stream().map(x->new AbstractMap.SimpleEntry<>(x, doTransform(x))).collect(toMap(x->x.getKey(), x->x.getValue()));
    }
}

要求使用AbstractMap.SimpleEntry是凌乱和笨拙的。Linqs对匿名类型的使用更加优雅。

有没有更简单的方法来使用streams来实现这一点?

提前进行Thx检查。

EN

回答 2

Stack Overflow用户

发布于 2018-06-04 05:26:01

您可以在值映射器中调用doTransform

代码语言:javascript
复制
Map<T, V> transform(List<T> item) {
    return item.stream().collect(toMap(x -> x, x -> doTransform(x)));
}
票数 3
EN

Stack Overflow用户

发布于 2018-06-04 17:14:48

在这个具体的例子中,根本不需要做中间存储:

代码语言:javascript
复制
Map<T, V> transform(List<T> item) {
    return item.stream().collect(toMap(x -> x, x -> doTransform(x)));
}

但是如果你需要的话,Java 9提供了一个更简单的工厂方法,

代码语言:javascript
复制
Map<T, V> transform(List<T> item) {
    return item.stream()
               .map(x -> Map.entry(x, doTransform(x)))
               .collect(toMap(x -> x.getKey(), x -> x.getValue()));
}

只要你不需要和null打交道。

您可以在这里使用匿名内部类,

代码语言:javascript
复制
Map<T, V> transform(List<T> item) {
    return item.stream()
               .map(x -> new Object(){ T t = x; V v = doTransform(x); })
               .collect(toMap(x -> x.t, x -> x.v));
}

但它的效率较低。这是一个内部类,它捕获对周围this的引用,也捕获x,所以您有两个字段,t和用于捕获x的合成字段,用于相同的事情。

后者可以通过使用一种方法来规避,例如

代码语言:javascript
复制
Map<T, V> transform(List<T> item) {
    return item.stream()
               .map(x -> new Object(){ T getKey() { return x; } V v = doTransform(x); })
               .collect(toMap(x -> x.getKey(), x -> x.v));
}

但是它并没有增加可读性。

唯一真正的匿名类型是为lambda表达式生成的类型,这些类型可以用于通过高阶函数存储信息:

代码语言:javascript
复制
Map<T, V> transform(List<T> item) {
    return item.stream()
               .map(x -> capture(x, doTransform(x)))
               .collect(HashMap::new, (m,f) -> f.accept(m::put), HashMap::putAll);
}
代码语言:javascript
复制
public static <A,B> Consumer<BiConsumer<A,B>> capture(A a, B b) {
    return f -> f.accept(a, b);
}

但是,如果您在更复杂的场景中尝试这样做,很快就会遇到Java类型系统的局限性(它仍然不是函数式编程语言)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50671112

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档