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

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

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

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

求差集

/**
 * 差集(基于API解法) 適用于小數(shù)據(jù)量
 * 求List1中有的但是List2中沒有的元素
 * 時間復(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中沒有的元素
 * 空間換時間降低時間復(fù)雜度
 * 時間復(fù)雜度O(Max(list1.size(),list2.size()))
 */
public static List<String> subList1(List<String> list1, List<String> list2) {
    //空間換時間 降低時間復(fù)雜度
    Map<String, String> tempMap = new HashMap<>();
    for(String str:list2){
        tempMap.put(str,str);
    }
    //LinkedList 頻繁添加刪除 也可以ArrayList容量初始化為List1.size(),防止數(shù)據(jù)量過大時頻繁擴容以及數(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> 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中都有的元素
 * 時間復(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中都有的元素
 * 時間復(fù)雜度O(Max(list1.size(),list2.size()))
 */
public static List<String> intersectList1(List<String> list1, List<String> list2){
    //空間換時間 降低時間復(fù)雜度
    Map<String, String> tempMap = new HashMap<>();
    for(String str:list2){
        tempMap.put(str,str);
    }
    //LinkedList 頻繁添加刪除 也可以ArrayList容量初始化為List1.size(),防止數(shù)據(jù)量過大時頻繁擴容以及數(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ù)組擴容 數(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ù)元素
 * 時間復(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;
}

實際業(yè)務(wù)場景

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

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

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

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

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

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

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

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

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

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

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

/**
 * 渠道授權(quán)新提交關(guān)聯(lián)授權(quán)產(chǎn)品 與 歷史已審批授權(quán)信息對比處理標注授權(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)品為空(基本不存在此場景)
    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<>();
    //空間換時間 降低時間復(fù)雜度
    //說明:list中不會存在重復(fù)(ID相同)的授權(quán)產(chǎn)品 否則此toMap收集會拋出異常
    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)){//重寫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中兩個List之間的比較方法的文章就介紹到這了,更多相關(guān)Java中List比較內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

最新評論

咸宁市| 商城县| 漳州市| 利津县| 庆元县| 保康县| 长沙县| 罗田县| 鄯善县| 甘南县| 崇州市| 民和| 仁化县| 马鞍山市| 且末县| 淮阳县| 祥云县| 稷山县| 黑河市| 泌阳县| 阿拉尔市| 黎川县| 和田市| 邢台市| 穆棱市| 江西省| 石阡县| 日土县| 遵化市| 安图县| 襄汾县| 贡山| 龙泉市| 香格里拉县| 白城市| 宝应县| 咸宁市| 沂源县| 桦甸市| 肃北| 泾阳县|