簡體   English   中英

如何有效地比較兩個產品列表

[英]How to efficiently compare two lists of Products

我正在嘗試編寫一種方法,以有效的方式檢查 2 個產品列表是否相等。

List<Product> firstList = getProductsListFromSomewhere();
List<Product> secondList = getProductsListFromSomewhereElse();

public boolean areListsEqual(List<Product> firstList, List<Product> secondList) {
    ...
}

約束和條件

  • 同一產品可以在列表中出現多次。 前任。 (產品 A、產品 B、產品 A、產品 C)
    如果我使用 HashSet 來存儲第一個列表的內容,然后解析第二個列表以檢查每個 Product 是否在集合中,這可能代表一個問題,因為我不能在 HashSet 中放置重復項。
  • 如果這兩個列表包含相同的產品並且出現的次數相同但它們的順序不相關,則它們被認為是相等的。
    例如,這兩個列表
    (產品 A、產品 B、產品 A、產品 C)
    (產品 C,產品 A,產品 A,產品 B)
    被認為是相等的。

    但是那兩個
    (產品 A、產品 B、產品 A、產品 C)
    (產品 A、產品 B、產品 C)
    被認為是不同的
  • object 產品定義如下(注意它的代碼是自動生成的,所以我不能在它的類中編寫方法equalshashcode

     class Product { private String name; private Integer quantity; private List<Discount> discountsList; //some other field not needed for the comparison }
  • 如果兩個產品具有相同的名稱、相同的數量和相同的折扣列表,則它們被認為是相等的

  • 同樣對於折扣比較列表,元素的順序不相關

  • 折扣是這樣定義的(在這種情況下 class 是自動生成的,我不能編寫方法equalshashcode

     class Discount { String code; //some other field not needed for the comparison }
  • 如果兩個折扣具有相同的代碼,則它們被視為相等

要求和偏好

  • 比較必須有效(我想我必須使用某種散列)

  • 代碼應該盡可能干凈(我寧願避免使用反射之類的東西來解析結構等)

  • 如果可能的話,我寧願不使用外部庫

我的(無效:()方法
我開始寫一個可能的解決方案的草稿,但我發現我的方法有不同的障礙,我不知道我是否應該以某種方式對其進行改進或完全重新考慮它。
我的想法是在 class 中擴展 Product class 應該執行比較:

List<Product> firstList = getProductsListFromSomewhere();
List<Product> secondList = getProductsListFromSomewhereElse();

public boolean areListsEqual(List<Product> firstList, List<Product> secondList) {
    ...
}  

private class ComparableProduct extends Product {

  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj == null) {
      return false;
    }
    if (getClass() != obj.getClass()) {
      return false;
    }
    final ComparableProduct other = (ComparableProduct)obj;
    if (!Objects.equals(this.name, other.name)) {
      return false;
    }
    if (!Objects.equals(this.quantity, other.quantity)) {
      return false;
    }
    if (!Objects.equals(this.discountList, other.discountList)) {
      return false;
    }
    return true;
  }

  @Override
  public int hashCode() {
    int hash = 3;
    hash = 79 * hash + Objects.hashCode(this.name);
    hash = 79 * hash + Objects.hashCode(this.quantity);
    hash = 79 * hash + Objects.hashCode(this.discountList);
    return hash;
  }
}

這種方法顯然不起作用,因為在沒有定義 equals 和 hashCode 方法的情況下比較了 Discount object 但我無法擴展 Discount,因為 Product object 中定義的 discountList 屬於 Discount 類型,因此我無法使用最終創建的 ComparableDiscount。
此外,一旦定義了散列機制,我不確切知道使用什么是最好的方法/數據結構,以檢查兩個列表是否相等

你能幫我以最好的方式完成這部分代碼嗎?

最簡單的方法是編寫一個 function,它接受一個Product並生成它的唯一字符串表示。 確保如果您認為兩個相同,則必須取出相同的字符串。 (例如對折扣代碼進行排序。)

現在您可以將Product對象List轉換為字符串List 您現在可以相當輕松地比較其中兩個列表。

如果這些可能很大,一個提示是實際使用描述的 MD5 hash 而不是描述本身。 那些會更短,碰撞的幾率很低。

如果要實際識別差異,則應將表示產品的字符串的 map 存儲到產品 object。 這樣,一旦您知道哪些字符串在一個列表中而不在另一個列表中,那么您可以在返回它們之前將字符串轉換回對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM