最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中兩個(gè)List之間的比較方法(差集、交集和并集)

 更新時(shí)間:2022年06月16日 09:20:17   作者:程序猿不源  
在業(yè)務(wù)的開(kāi)發(fā)過(guò)程中會(huì)經(jīng)常用到兩個(gè)List集合相互取值的情況,下面這篇文章主要給大家介紹了關(guān)于Java中兩個(gè)List之間的比較方法,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下

實(shí)現(xiàn)比較兩個(gè)List之間的差異,包括獲取兩List的差集,交集,并集(不去重&去重)的API解法和優(yōu)化解法的解決方案。

求差集

/**
 * 差集(基于API解法) 適用于小數(shù)據(jù)量
 * 求List1中有的但是List2中沒(méi)有的元素
 * 時(shí)間復(fù)雜度 O(list1.size() * list2.size())
 */
public static List<String> subList(List<String> list1, List<String> list2) {
    list1.removeAll(list2);
    return list1;
}
 
/**
 * 差集(基于常規(guī)解法)優(yōu)化解法1 適用于中等數(shù)據(jù)量
 * 求List1中有的但是List2中沒(méi)有的元素
 * 空間換時(shí)間降低時(shí)間復(fù)雜度
 * 時(shí)間復(fù)雜度O(Max(list1.size(),list2.size()))
 */
public static List<String> subList1(List<String> list1, List<String> list2) {
    //空間換時(shí)間 降低時(shí)間復(fù)雜度
    Map<String, String> tempMap = new HashMap<>();
    for(String str:list2){
        tempMap.put(str,str);
    }
    //LinkedList 頻繁添加刪除 也可以ArrayList容量初始化為L(zhǎng)ist1.size(),防止數(shù)據(jù)量過(guò)大時(shí)頻繁擴(kuò)容以及數(shù)組復(fù)制
    List<String> resList = new LinkedList<>();
    for(String str:list1){
        if(!tempMap.containsKey(str)){
            resList.add(str);
        }
    }
    return resList;
}
 
/**
 * 差集(基于java8新特性)優(yōu)化解法2 適用于大數(shù)據(jù)量
 * 求List1中有的但是List2中沒(méi)有的元素
 */
public static List<String> subList2(List<String> list1, List<String> list2) {
    Map<String, String> tempMap = list2.parallelStream().collect(Collectors.toMap(Function.identity(), Function.identity(), (oldData, newData) -> newData));
    return list1.parallelStream().filter(str->{
        return !tempMap.containsKey(str);
    }).collect(Collectors.toList());
}

求交集

/**
 * 交集(基于API解法) 適用于小數(shù)據(jù)量
 * 求List1和List2中都有的元素
 * 時(shí)間復(fù)雜度 O(list1.size() * list2.size())
 */
public static List<String> intersectList(List<String> list1, List<String> list2){
    list1.retainAll(list2);
    return list1;
}
/**
 * 交集(基于常規(guī)解法) 優(yōu)化解法1  適用于中等數(shù)據(jù)量
 * 求List1和List2中都有的元素
 * 時(shí)間復(fù)雜度O(Max(list1.size(),list2.size()))
 */
public static List<String> intersectList1(List<String> list1, List<String> list2){
    //空間換時(shí)間 降低時(shí)間復(fù)雜度
    Map<String, String> tempMap = new HashMap<>();
    for(String str:list2){
        tempMap.put(str,str);
    }
    //LinkedList 頻繁添加刪除 也可以ArrayList容量初始化為L(zhǎng)ist1.size(),防止數(shù)據(jù)量過(guò)大時(shí)頻繁擴(kuò)容以及數(shù)組復(fù)制
    List<String> resList = new LinkedList<>();
    for(String str:list1){
        if(tempMap.containsKey(str)){
            resList.add(str);
        }
    }
    return resList;
}
/**
 * 交集(基于java8新特性)優(yōu)化解法2 適用于大數(shù)據(jù)量
 * 求List1和List2中都有的元素
 */
public static List<String> intersectList2(List<String> list1, List<String> list2){
    Map<String, String> tempMap = list2.parallelStream().collect(Collectors.toMap(Function.identity(), Function.identity(), (oldData, newData) -> newData));
    return list1.parallelStream().filter(str->{
        return tempMap.containsKey(str);
    }).collect(Collectors.toList());
}

求并集(不去重)

/**
 * 并集(不去重)
 * 合并list1和list2 不考慮去除重復(fù)元素
 * 數(shù)組擴(kuò)容 數(shù)組copy
 * @param list1
 * @param list2
 * @return
 */
public static List<String> mergeList(List<String> list1, List<String> list2){
    list1.addAll(list2);
    return list1;
}

求并集(去重)

/**
 * 并集(去重) 基于API解法
 * 合并list1和list2 去除重復(fù)元素
 * 時(shí)間復(fù)雜度主要取決于removeAll 取差集 O(list1.size() * list2.size())
 */
public static List<String> distinctMergeList(List<String> list1, List<String> list2){
    //第一步 先求出list1與list2的差集
    list1.removeAll(list2);
    //第二部 再合并list1和list2
    list1.addAll(list2);
    return list1;
}
/**
 * 并集(去重) 基于Java8新特性 適用于大數(shù)據(jù)量
 * 合并list1和list2 去除重復(fù)元素
 */
public static List<String> distinctMergeList1(List<String> list1, List<String> list2){
    //第一步 先求出list1與list2的差集
    list1 = subList2(list1,list2);
    //第二部 再合并list1和list2
    list1.addAll(list2);
    return list1;
}

實(shí)際業(yè)務(wù)場(chǎng)景

根據(jù)客戶(hù)需求,業(yè)務(wù)提交審核需要很直觀的看到此次提交的數(shù)據(jù)關(guān)聯(lián)產(chǎn)品的狀態(tài)變更。

第一種情況:新增的渠道授權(quán)關(guān)聯(lián)的產(chǎn)品,所有的授權(quán)產(chǎn)品均為新增;

第二種情況:已審核通過(guò)的渠道授權(quán)重新提交授權(quán)審核的,要直觀的標(biāo)記出此次提交審核渠道關(guān)聯(lián)授權(quán)產(chǎn)品新增了那些,刪除了那些,更改了那些等信息;

第三種情況:作廢渠道提交的審核要標(biāo)注出所有的關(guān)聯(lián)授權(quán)產(chǎn)品為刪除狀態(tài)。

授權(quán)關(guān)聯(lián)產(chǎn)品為申請(qǐng)表單中一對(duì)多關(guān)聯(lián)表,前端展示根據(jù)數(shù)據(jù)的不同狀態(tài)展示不同的樣式:

  • 新增授權(quán)產(chǎn)品顯示為紅色
  • 刪除授權(quán)產(chǎn)品顯示為刪除線(xiàn)樣式(中劃線(xiàn) )
  • 更新授權(quán)產(chǎn)品顯示標(biāo)注紅色*號(hào)

建立關(guān)聯(lián)產(chǎn)品Vo

首先模擬建立一個(gè)產(chǎn)品的實(shí)體,此處只簡(jiǎn)單列入幾個(gè)屬性,在比較所關(guān)聯(lián)產(chǎn)品信息是否是變更狀態(tài)的時(shí)候根據(jù)實(shí)際業(yè)務(wù)需要需重寫(xiě) hashCode 和 equals 方法。

class ProductVo{
    private String id;
    private String name;
    //其他屬性不在列入
    //數(shù)據(jù)狀態(tài)(新增:insert; 更新:update; 刪除:delete)
    private String status;
    //get set 省略
    //如有必要重寫(xiě)hashCode equals
}

業(yè)務(wù)代碼實(shí)現(xiàn)

業(yè)務(wù)實(shí)現(xiàn)主要通過(guò) 空間換時(shí)間 方式降低時(shí)間復(fù)雜度,先把List轉(zhuǎn)為Map,利用map的 get 和 containsKey 方法理想情況下O(1)的時(shí)間復(fù)雜度降低嵌套的兩次List遍歷。

/**
 * 渠道授權(quán)新提交關(guān)聯(lián)授權(quán)產(chǎn)品 與 歷史已審批授權(quán)信息對(duì)比處理標(biāo)注授權(quán)產(chǎn)品的狀態(tài)信息<br/>
 * 前端可以根據(jù)不同的數(shù)據(jù)狀態(tài)顯示不同的樣式<br/>
 * 用于審核人員直接看到此次提交審核新增了那些授權(quán),取消了那些授權(quán),更改了那些授權(quán)
 * @param oldList  原始關(guān)聯(lián)授權(quán)產(chǎn)品列表
 * @param newList  提交關(guān)聯(lián)授權(quán)產(chǎn)品列表
 * @return
 */
public List<ProductVo> productStatusHandle(List<ProductVo> oldList,List<ProductVo> newList){
    //原始關(guān)聯(lián)授權(quán)產(chǎn)品為空 并且 新關(guān)聯(lián)授權(quán)產(chǎn)品為空(基本不存在此場(chǎng)景)
    if((oldList == null || oldList.isEmpty()) && (newList == null || newList.isEmpty())){
        return Collections.emptyList();
    }
    //原始關(guān)聯(lián)授權(quán)產(chǎn)品為空 則提交關(guān)聯(lián)授權(quán)產(chǎn)品全部為新增
    if(oldList == null || oldList.isEmpty()){
        return newList.stream().map(vo->{
            vo.setStatus("insert");
            return vo;
        }).collect(Collectors.toList());
    }
    //提交關(guān)聯(lián)授權(quán)產(chǎn)品為空 則刪除之前所有的產(chǎn)品授權(quán)
    if(newList == null || newList.isEmpty()){
        return oldList.stream().map(vo->{
            vo.setStatus("delete");
            return vo;
        }).collect(Collectors.toList());
    }
    //原始關(guān)聯(lián)授權(quán)產(chǎn)品與此次提交關(guān)聯(lián)授權(quán)產(chǎn)品均不為空
    List<ProductVo> resList = new LinkedList<>();
    //空間換時(shí)間 降低時(shí)間復(fù)雜度
    //說(shuō)明:list中不會(huì)存在重復(fù)(ID相同)的授權(quán)產(chǎn)品 否則此toMap收集會(huì)拋出異常
    Map<String, ProductVo> oldMap = oldList.stream().collect(Collectors.toMap(ProductVo::getId, Function.identity()));
    Map<String, ProductVo> newMap = newList.stream().collect(Collectors.toMap(ProductVo::getId, Function.identity()));
    for(ProductVo vo:newList){
        ProductVo productVo = oldMap.get(vo.getId());
        //提交關(guān)聯(lián)授權(quán)產(chǎn)品在原始關(guān)聯(lián)授權(quán)產(chǎn)品
        if(productVo != null){
            if(!vo.equals(productVo)){//重寫(xiě)hashCode與equals自定義規(guī)則 用于判定是否數(shù)據(jù)更新
                vo.setStatus("update");
            }
        }else{//提交審核數(shù)據(jù)不在舊數(shù)據(jù)之列
            vo.setStatus("insert");
        }
        resList.add(vo);
    }
    //原始關(guān)聯(lián)授權(quán)產(chǎn)品是否存在已取消的情況
    for(ProductVo vo:oldList){
        if(!newMap.containsKey(vo.getId())){
            vo.setStatus("delete");
            resList.add(vo);
        }
    }
    return resList;
}

總結(jié)

到此這篇關(guān)于Java中兩個(gè)List之間的比較方法的文章就介紹到這了,更多相關(guān)Java中List比較內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解application.properties和application.yml文件的區(qū)別

    詳解application.properties和application.yml文件的區(qū)別

    這篇文章主要介紹了詳解application.properties和application.yml文件的區(qū)別,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-01-01
  • Java解壓rar文件的兩種實(shí)現(xiàn)方法

    Java解壓rar文件的兩種實(shí)現(xiàn)方法

    這篇文章主要介紹了Java解壓rar文件的兩種實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • java連接Oracle數(shù)據(jù)庫(kù)的方法解析

    java連接Oracle數(shù)據(jù)庫(kù)的方法解析

    本文主要對(duì)java連接Oracle數(shù)據(jù)庫(kù)方法進(jìn)行步驟解析,具有很好的參考價(jià)值,需要的朋友一起來(lái)看下吧
    2016-12-12
  • Spring Boot利用JSR303實(shí)現(xiàn)參數(shù)驗(yàn)證的方法實(shí)例

    Spring Boot利用JSR303實(shí)現(xiàn)參數(shù)驗(yàn)證的方法實(shí)例

    這篇文章主要給大家介紹了關(guān)于Spring Boot利用JSR303實(shí)現(xiàn)參數(shù)驗(yàn)證的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Spring Boot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • SpringBoot的@Value注解如何設(shè)置默認(rèn)值

    SpringBoot的@Value注解如何設(shè)置默認(rèn)值

    這篇文章主要介紹了SpringBoot的@Value注解如何設(shè)置默認(rèn)值問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • Java中BM(Boyer-Moore)算法的圖解與實(shí)現(xiàn)

    Java中BM(Boyer-Moore)算法的圖解與實(shí)現(xiàn)

    本文主要介紹了兩個(gè)大的部分,第一部分通過(guò)圖解的方式講解BM算法,第二部分則代碼實(shí)現(xiàn)一個(gè)簡(jiǎn)易的BM算法,感興趣的小伙伴可以學(xué)習(xí)一下
    2022-05-05
  • 解析Java中的static關(guān)鍵字

    解析Java中的static關(guān)鍵字

    static是方便在沒(méi)有創(chuàng)建對(duì)象的情況下進(jìn)行調(diào)用(方法/變量)。顯然,被static關(guān)鍵字修飾的方法或者變量不需要依賴(lài)于對(duì)象來(lái)進(jìn)行訪(fǎng)問(wèn),只要類(lèi)被加載了,就可以通過(guò)類(lèi)名去進(jìn)行訪(fǎng)問(wèn)。static可以用來(lái)修飾類(lèi)的成員方法、類(lèi)的成員變量,另外也可以編寫(xiě)static代碼塊來(lái)優(yōu)化程序性能
    2021-06-06
  • java實(shí)現(xiàn)文件重命名的方法

    java實(shí)現(xiàn)文件重命名的方法

    這篇文章主要介紹了java實(shí)現(xiàn)文件重命名的方法,涉及java針對(duì)文件的重命名操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • SpringBoot通過(guò)yml和xml文件配置日志輸出方法

    SpringBoot通過(guò)yml和xml文件配置日志輸出方法

    這篇文章主要介紹了SpringBoot通過(guò)yml和xml文件配置日志輸出方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-04-04
  • java 實(shí)現(xiàn)通過(guò) post 方式提交json參數(shù)操作

    java 實(shí)現(xiàn)通過(guò) post 方式提交json參數(shù)操作

    這篇文章主要介紹了java 實(shí)現(xiàn)通過(guò) post 方式提交json參數(shù)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-09-09

最新評(píng)論

武穴市| 遂昌县| 银川市| 涿鹿县| 秦皇岛市| 同江市| 焉耆| 开鲁县| 天柱县| 花垣县| 云林县| 三河市| 太湖县| 黄梅县| 桃源县| 高清| 吉林市| 邹平县| 天柱县| 册亨县| 贵港市| 阿克陶县| 宜章县| 金坛市| 武强县| 遵义市| 崇左市| 潜江市| 霸州市| 西充县| 沛县| 葵青区| 孙吴县| 罗平县| 黎平县| 鸡东县| 长武县| 花垣县| 筠连县| 贵德县| 荔浦县|