我正在尝试编写一种方法,该方法可以高效地检查两个产品列表是否相等。
List<Product> firstList = getProductsListFromSomewhere();
List<Product> secondList = getProductsListFromSomewhereElse();
public boolean areListsEqual(List<Product> firstList, List<Product> secondList) {
...
}
约束条件
对象Product的定义如下(请注意,它的代码是自动生成的,因此我不能在其类内编写方法 equals 和 hashcode )>
class Product {
private String name;
private Integer quantity;
private List<Discount> discountsList;
//some other field not needed for the comparison
}
如果两个产品具有相同的名称,相同的数量和相同的折扣列表
,则视为相等对于折扣比较列表,元素的顺序也不相关
像这样定义折扣(同样在这种情况下,该类是自动生成的,我无法编写方法 equals 和 hashcode )
class Discount {
String code;
//some other field not needed for the comparison
}
如果两个折扣具有相同的代码,则被视为相等
要求和偏好
比较必须高效(我想我必须使用某种哈希)
代码应尽可能简洁(我宁愿避免使用诸如反射之类的东西来解析结构等)
如果可能的话,我宁愿不使用外部库
我的方法(无效:()有效
我开始写一个可能的解决方案的草稿,但是我发现我的方法遇到了不同的障碍,我不知道是否应该以某种方式改进它或完全重新考虑它。
我的想法是扩展Product类在应该执行比较的类中:
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对象,但是由于在Product对象中定义的DiscountList是Discount类型,所以我无法扩展Discount,所以我不能使用ComparableDiscount最终创建。
此外,一旦定义了哈希机制,我就不知道确切地使用什么最佳方法/数据结构,以检查两个列表是否相等
您能帮我以最好的方式完成这部分代码吗?
答案 0 :(得分:0)
最简单的方法是编写一个接受Product
并生成其唯一字符串表示形式的函数。确保如果您认为两个相同,则必须得到相同的字符串。 (例如,对折扣代码进行排序。)
现在,您可以将List
个对象中的一个Product
转换为一个List
个字符串。现在,您可以轻松比较其中两个列表。
如果这些建议可能很大,一个技巧是实际使用描述的MD5哈希而不是描述本身。这些将更短,并且发生碰撞的几率在天文学上较低。
如果要真正识别差异,则应将代表产品的字符串映射存储到产品对象。这样,一旦您知道一个列表中有哪些字符串,而又不知道其他列表中的字符串,则可以在返回它们之前将它们变回对象。