规范化不同对象的 lambda 操作



在下面的代码中,您可以看到具有不同对象的多个映射发生的常见lambda操作。我想知道我是否可以在调用时定义一个执行相同操作的通用函数。

Map<Int, Object1> map1.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getDisplayName()))
Map<Int, Object2> map2.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getDisplayName()))
Map<Int, Object3> map2.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getDisplayName()))

在上面,对象 1、对象 2 和对象 3 属于不同的类型(类(。

假设所有对象 obj1、obj2、obj3 都具有共同的属性 displayName。

在没有反射的情况下,您能做的最好的事情就是传递一个 lambda 来获取属性:

public <K, T1, T2> Map<K, T2> mapValues(Map<K, T1> source, Function<T1, T2> function) {
return source.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> function.apply(e.getValue())));
}
// use
mapValues(map1, Object1::getDisplayName)
mapValues(map2, Object2::getDisplayName)

(Kotlin 在标准库中具有此方法的等效项(

通过反思,你可以做到

public <K, T> Map<K, String> mapDisplayName(Map<K, T> source, Class<T> clazz) {
Method m = clazz.getMethod("getDisplayName");
return source.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> (String) m.invoke(e.getValue())));
}
// use
mapValues(map1, Object1.class)
mapValues(map2, Object2.class)

但它不太安全,在换取时不太有用......没有那么方便。

最新更新