大數據量情況下高效比較兩個list


  比如,對兩個list<object>進行去重,合並操作時,一般的寫法為兩個for循環刪掉一個list中重復的,然后再合並。

  如果數據量在千條級別,這個速度還是比較快的。但如果數據量超過20W+(比如大批量的導入數據並對數據進行處理)時,則這塊代碼執行時間會比較長,非常影響用戶體驗和程序功能。這時我們可以用差集(Except)來處理重復數據。

  下面MSDN上的代碼示例演示了如何使用 Except<TSource>(IEnumerable<TSource>, IEnumerable<TSource>) 方法來比較兩個數字序列,並返回僅在第一個序列中出現的元素。

 double[] numbers1 = { 2.0, 2.1, 2.2, 2.3, 2.4, 2.5 };
 double[] numbers2 = { 2.2 };

  IEnumerable<double> onlyInFirstSet = numbers1.Except(numbers2);

  foreach (double number in onlyInFirstSet)
         outputBlock.Text += number + "\n";

      /*
       This code produces the following output:

       2
       2.1
       2.3
       2.4
       2.5
      */

  

  需要注意的是A.Except(B)與B.Except(A)結果是不一樣的。

  A.Except(B):

       

  B.Except(A):

  

  

  如果希望比較某種自定義數據類型對象的序列,則必須在您的類中實現 IEqualityComparer<T> 泛型接口。 下面的代碼演示了如何在自定義數據類型中實現此接口並提供 GetHashCode 和 Equals 方法。

 

  假設有需求是:在oldlist中過濾掉和list有相同ContractNo值的數據。

public class AssetPoolDataComparer : IEqualityComparer<AssetPoolData>
    {
        public bool Equals(AssetPoolData x, AssetPoolData y)
        {
            if (Object.ReferenceEquals(x, y)) return true;
         //設置比較條件為兩個ContractNo相同
            return x != null && y != null && x.ContractNo.Equals(y.ContractNo);
        }

        public int GetHashCode(AssetPoolData obj)
        {
            int hashContractNo = obj.ContractNo == null ? 0 : obj.ContractNo.GetHashCode();
            //主鍵ID
            int hashProductID = obj.Id.GetHashCode();

            return hashContractNo ^ hashProductID;
        }
    }


var exceptList = oldlist.Except(list, new AssetPoolDataComparer()).ToList();

 

  修改完代碼,測試前后代碼塊運行時間,效果還是非常可觀的。

By QJL

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM