繁体   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