如何实现通用的对象填充方法
先上代码:
User对象
public class UserDTO {
private int userId;
private String userName;
private int orgId;
private OrgDTO orgDTO;
}
Org对象
public Class OrgDTO {
private int orgId;
private String orgName;
}
工具类方法
public static <S, K, T> void oneToOne(List<S> sourceList, List<T> detailList, SafeFunction<S, K> sourceKey, SafeFunction<T, K> detailKey) {
Map<K, T> detailMap = detailList.stream().collect(Collectors.toMap(detailKey, Function.identity()));
for (S s : sourceList) {
K key = sourceKey.apply(s);
T detail = detailMap.get(key);
if (detail != null) {
// TODO How to call s.setDetail() ?
}
}
}
参数说明:
sourceList: 待填充数组
detailList: 填充物数组
sourceKey: sourceList与detailList的关联键
detailKey: detailList的关联键转换函数
好吧,以上参数说明比较难懂(我也不知道要怎么描述)……
举个场景例子:
有一个UserDTO
和OrgDTO
,假设他们在数据表的关系是1对1,很多时候我们需要根据UserDTO
里面的orgId
查询对应的OrgDTO
,然后根据orgId
把OrgDTO
填充进UserDTO
里面。
传统的代码写法如下:
public void fillOrgDTO(List<UserDTO> userDTOs) {
Set<Integer> orgIds = userDTOs.stream().map(UserDTO::getOrgId).collect(Collectors.toSet());
List<OrgDTO> orgDTOs = orgDAO.findByIds(orgIds);
Map<Integer, OrgDTO> orgId2OrgDTOMap = orgDTOs.stream().collect(Collectors.toMap(OrgDTO::getOrgId, Function.identity()));
for (UserDTO userDTO : userDTOs) {
Integer orgId = userDTO.getOrgId();
OrgDTO orgDTO = orgId2OrgDTOMap.get(orgId);
if (orgDTO != null) {
userDTO.setOrgDTO(orgDTO);
}
}
}
我的想法是,有没有办法把以上这段代码抽象成一个通用的方法,这样就不用每次都写类似的代码。
然后就试着写出了oneToOne
这个方法,不过去到TODO那里就不知道怎么写了。
理论上用反射可以做到(需要变更方法签名),但我不想用反射,因为不论从性能还是维护角度来看,反射都不是一个很好的选择。
之前也了解过Java8的Consumer
和BiConsumer
,但试了一下好像也没法实现我的需求,可能是我理解得不够。
所以,在此提出这个问题,看看大家有没有好的解决方案?
PS:方法签名可以变更,代码可任意修改,UserDTO、OrgDTO可以实现任意接口。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先建议尽量用JDK functional interfaces,如果可以。下面是代码:
其次,是一个设计的问题:因为
sourceKeyExtractor
,detailKeyExactor
离它操作的对象源比较远,可能会混淆或至少要记得一个对应关系,如果重构一下,把sourceKeyExtractor
移到前面一点,这样就一清二楚每个keyExtractor
操作的对象源。