第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何實現(xiàn)通用的對象填充方法

如何實現(xiàn)通用的對象填充方法

幕布斯6054654 2019-03-01 10:41:19
先上代碼: 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)任意接口。
查看完整描述

1 回答

?
慕容森

TA貢獻1853條經(jīng)驗 獲得超18個贊

首先建議盡量用JDK functional interfaces,如果可以。下面是代碼:

public <S, T, K> void oneToOne(List<S> sourceList, List<T> detailList, Function<S, K> sourceKeyExtractor, Function<T, K> detailKeyExactor,
        BiConsumer<S, T> action) {
    // Make sure the keys in detail list are unique.
    Map<K, T> detailMap = detailList.stream().collect(Collectors.toMap(detailKeyExactor, Function.identity()));
    sourceList.stream().forEach(s -> action.accept(s, detailMap.getOrDefault(sourceKeyExtractor.apply(s), null)));
}

@Test
public void test_oneToOne() {
    List<UserDTO> userList = null; // TODO
    List<OrgDTO> orgList = null; // TODO
    oneToOne(userList, orgList, s -> s.getOrgId(), t -> t.getOrgId(), (s, t) -> s.setOrgDTO(t));
}

其次,是一個設(shè)計的問題:因為 sourceKeyExtractor, detailKeyExactor離它操作的對象源比較遠,可能會混淆或至少要記得一個對應(yīng)關(guān)系,如果重構(gòu)一下,把sourceKeyExtractor移到前面一點,這樣就一清二楚每個keyExtractor操作的對象源。

public <S, T, K> void oneToOne(List<S> sourceList, Function<S, K> sourceKeyExtractor, List<T> detailList, Function<T, K> detailKeyExactor,
        BiConsumer<S, T> action) {
    // Make sure the keys in detail list are unique.
    Map<K, T> detailMap = detailList.stream().collect(Collectors.toMap(detailKeyExactor, Function.identity()));
    sourceList.stream().forEach(s -> action.accept(s, detailMap.getOrDefault(sourceKeyExtractor.apply(s), null)));
}
查看完整回答
反對 回復(fù) 2019-03-01
  • 1 回答
  • 0 關(guān)注
  • 524 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號