使用java流将列表转换为映射
我在代码中重复了以下模式:使用java流将列表转换为映射,java,java-stream,Java,Java Stream,我在代码中重复了以下模式: 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, doTrans
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()));
}
}
X类
{
V点变换(T){
返回null;//伪实现
}
映射变换(列表项){
return item.stream().map(x->newAbstractMap.SimpleEntry(x,doTransform(x)).collect(toMap(x->x.getKey(),x->x.getValue());
}
}
需要使用AbstractMap.SimpleEntry是混乱和笨拙的。LINQ对匿名类型的使用更加优雅
有没有一种更简单的方法可以使用流来实现这一点
提前发送Thx。您可以在值映射器中调用
doTransform
:
Map<T, V> transform(List<T> item) {
return item.stream().collect(toMap(x -> x, x -> doTransform(x)));
}
映射变换(列表项){
return item.stream().collect(toMap(x->x,x->doTransform(x));
}
您可以在值映射器中调用doTransform
:
Map<T, V> transform(List<T> item) {
return item.stream().collect(toMap(x -> x, x -> doTransform(x)));
}
映射变换(列表项){
return item.stream().collect(toMap(x->x,x->doTransform(x));
}
不幸的是,Java没有完全等同于C#的匿名类型
在这种特定情况下,您不需要@Jorn Vernee建议的中间map
操作。相反,您可以在toMap
收集器中执行键和值提取
然而,当你认为你需要C#的匿名类型时,你可以考虑:
Arrays.asList(…)
,List.of(…)
(可能并不总是您想要的,具体取决于您的用例)AbstractMap.SimpleEntry
也就是说,您当前的示例可以简化为:
Map<T, V> transform(List<T> items) {
return items.stream().collect(toMap(Function.identity(),this::doTransform));
}
映射变换(列表项){
return items.stream().collect(toMap(Function.identity(),this::doTransform));
}
不幸的是,Java没有完全等同于C#的匿名类型
在这种特定情况下,您不需要@Jorn Vernee建议的中间map
操作。相反,您可以在toMap
收集器中执行键和值提取
然而,当你认为你需要C#的匿名类型时,你可以考虑:
Arrays.asList(…)
,List.of(…)
(可能并不总是您想要的,具体取决于您的用例)AbstractMap.SimpleEntry
也就是说,您当前的示例可以简化为:
Map<T, V> transform(List<T> items) {
return items.stream().collect(toMap(Function.identity(),this::doTransform));
}
映射变换(列表项){
return items.stream().collect(toMap(Function.identity(),this::doTransform));
}
在此特定示例中,根本不需要执行中间存储:
Map<T, V> transform(List<T> item) {
return item.stream().collect(toMap(x -> x, x -> doTransform(x)));
}
但效率较低。它是一个内部类,捕获对周围this
的引用,也捕获x
,因此您有两个字段,t
和用于捕获x
的合成字段
后者可以通过使用一种方法来规避,例如
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));
}
映射变换(列表项){
returnitem.stream()
.map(x->new Object(){T getKey(){return x;}V V=doTransform(x);})
.collect(toMap(x->x.getKey(),x->x.v));
}
但这并没有增加可读性
唯一真正的匿名类型是为lambda表达式生成的类型,可用于通过高阶函数存储信息:
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);
}
映射变换(列表项){
returnitem.stream()
.map(x->capture(x,doTransform(x)))
.collect(HashMap::new,(m,f)->f.accept(m::put),HashMap::putAll);
}
公共静态消费者捕获(A、B){
返回f->f.接受(a,b);
}
但是,如果您在更复杂的场景中尝试这种方法,您很快就会发现Java类型系统的局限性(它仍然不是函数式编程语言)。在这个特定示例中,根本不需要执行中间存储:
Map<T, V> transform(List<T> item) {
return item.stream().collect(toMap(x -> x, x -> doTransform(x)));
}
但效率较低。它是一个内部类,捕获对周围this
的引用,也捕获x
,因此您有两个字段,t
和用于捕获x
的合成字段
后者可以通过使用一种方法来规避,例如
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));
}
映射变换(列表项){
returnitem.stream()
.map(x->new Object(){T getKey(){return x;}V V=doTransform(x);})
.collect(toMap(x->x.getKey(),x->x.v));
}
但这并没有增加可读性
唯一真正的匿名类型是为lambda表达式生成的类型,可用于通过高阶函数存储信息:
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);
}
映射变换(列表项){
returnitem.stream()
.map(x->capture(x,doTransform(x)))
.collect(HashMap::new,(m,f)->f.accept(m::put),HashMap::putAll);
}
公共静态消费者捕获(A、B){
返回f->f.接受(a,b);
}
但是如果您在更复杂的场景中尝试这种方法,您很快就会发现Java类型系统的局限性(它仍然不是函数式编程语言)。Nice!,我的回答可能有点懒;)还有自Java 9以来的
Map.entry()
factory方法,它稍微短一点。很好!,我的回答可能有点懒;)还有自Java9以来的Map.entry()
factory方法,它稍微短一点。