function - 标准化跨不同对象的 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()))
在上面,object1、object2 和 object3 是不同的类型(类)。
假设所有对象 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)
但它不太安全,也不太有用,以换取……不是那么方便。
推荐阅读
- ios - Swift 多个上传文件或图像
- python - 在 javascript 中实例化 QWebChannel 对象时的警告
- c# - 在一个键上加入两个列表,并用 CROSS 总结总数?
- android - 多个导航主机基础布局
- angular - 进行 HTTP POST 调用时出现 500(内部服务器错误)
- movesense - Movesense HelloWorld 订阅
- node.js - 在 Bot Builder 中从 URL 解析 XML 数据
- python - 在python中对一组数据执行数学运算
- python - 无法在kivy中显示进度条
- javascript - 从现有数组创建动态数组?