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

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

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

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

幕布斯6054654 2019-03-01 10:41:19
先上代碼: User對(duì)象 public class UserDTO { private int userId; private String userName; private int orgId; private OrgDTO orgDTO; } Org對(duì)象 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ù)說明比較難懂(我也不知道要怎么描述)…… 舉個(gè)場(chǎng)景例子:有一個(gè)UserDTO和OrgDTO,假設(shè)他們?cè)跀?shù)據(jù)表的關(guān)系是1對(duì)1,很多時(shí)候我們需要根據(jù)UserDTO里面的orgId查詢對(duì)應(yīng)的OrgDTO,然后根據(jù)orgId把OrgDTO填充進(jìn)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); } } } 我的想法是,有沒有辦法把以上這段代碼抽象成一個(gè)通用的方法,這樣就不用每次都寫類似的代碼。 然后就試著寫出了oneToOne這個(gè)方法,不過去到TODO那里就不知道怎么寫了。 理論上用反射可以做到(需要變更方法簽名),但我不想用反射,因?yàn)椴徽搹男阅苓€是維護(hù)角度來看,反射都不是一個(gè)很好的選擇。 之前也了解過Java8的Consumer和BiConsumer,但試了一下好像也沒法實(shí)現(xiàn)我的需求,可能是我理解得不夠。 所以,在此提出這個(gè)問題,看看大家有沒有好的解決方案? PS:方法簽名可以變更,代碼可任意修改,UserDTO、OrgDTO可以實(shí)現(xiàn)任意接口。
查看完整描述

1 回答

?
慕容森

TA貢獻(xiàn)1853條經(jīng)驗(yàn) 獲得超18個(gè)贊

首先建議盡量用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));
}

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

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)));
}
查看完整回答
反對(duì) 回復(fù) 2019-03-01
  • 1 回答
  • 0 關(guān)注
  • 519 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

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