先上代碼:
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() ?
}
}
}
參數(shù)說明:
sourceList: 待填充數(shù)組
detailList: 填充物數(shù)組
sourceKey: sourceList與detailList的關(guān)聯(lián)鍵
detailKey: detailList的關(guān)聯(lián)鍵轉(zhuǎn)換函數(shù)
好吧,以上參數(shù)說明比較難懂(我也不知道要怎么描述)……
舉個場景例子:有一個UserDTO和OrgDTO,假設(shè)他們在數(shù)據(jù)表的關(guān)系是1對1,很多時候我們需要根據(jù)UserDTO里面的orgId查詢對應(yīng)的OrgDTO,然后根據(jù)orgId把OrgDTO填充進UserDTO里面。
傳統(tǒng)的代碼寫法如下:
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,但試了一下好像也沒法實現(xiàn)我的需求,可能是我理解得不夠。
所以,在此提出這個問題,看看大家有沒有好的解決方案?
PS:方法簽名可以變更,代碼可任意修改,UserDTO、OrgDTO可以實現(xiàn)任意接口。
如何實現(xiàn)通用的對象填充方法
幕布斯6054654
2019-03-01 10:41:19