我想根据多个属性从数组列表中删除重复记录。这是一个示例域对象类:
private String mdl;
private String ndc;
private String gpi;
private String labelName;
private int seqNo;
private String vendorName;
mdl,ndc,gpi和seqNo共同构成了一个独特的记录。我想在 arraylist 中查找重复项,该数组列表检查这 4 个属性,然后如果列表中已存在具有相同 4 个属性的记录,则从列表中删除该记录。
覆盖.equals()
和.hashCode()
以考虑您的密钥:mdl,ndc。 gpi,seqNo。在这个网站上有无数的指南可以做到这一点,但像这样:
@Override
public boolean equals(Object obj) {
if(obj != null && obj instanceof MyClass) {
MyClass o = (MyClass)obj;
return mdl.equals(o.mdl) && ndc.equals(o.ndc) &&
gpi.equals(o.gpi) && seqNo == o.seqNo;
}
return false;
}
@Override
public int hashCode() {
return Objects.hash(mdl, ndc, gpi, seqNo);
}
如果这是一个问题,可能会有更有效的方法来实现它们。
然后,您可以使用以下命令将列表转换为集合:
Set<MyClass> set = new HashSet<>(list);
生成的set
不会有任何重复项,如果需要,您现在可以将列表替换为list = new ArrayList<>(set);
的新值。
如果要维护原始列表中项的顺序,请实例化LinkedHashSet
而不是HashSet
。
与您的直接问题无关,如果您想首先避免重复,也许可以考虑使用 Set
而不是 List
。它将使您的代码更高效(更少的内存使用量,没有重复项(,并消除之后搜索重复项的需要。
您可以尝试执行以下操作;
List<Obj> list = ...; // list contains multiple objects
Collection<Obj> nonDuplicateCollection = list.stream()
.collect(Collectors.toMap(Obj::generateUniqueKey, Function.identity(), (a, b) -> a))
.values();
(a, b) -> a
,表示当两个对象相同时,最终地图将包含前一个对象,后一个对象将被丢弃,如果需要后一个对象,您可以更改此行为。
Obj
在哪里;
public static class Obj {
private String mdl;
private String ndc;
private String gpi;
private String labelName;
private int seqNo;
private String vendorName;
// other getter/setters
public String generateUniqueKey() {
return mdl + ndc + gpi + seqNo;
}
}
我宁愿做这样的事情,而不是覆盖hashCode
或equals
方法,这些方法在默认状态下的另一个逻辑中可能是必需的......此外,明确显示您如何使用适当的方法(如generateUniqueKey
(断言唯一性比将逻辑隐藏在某些hashCode
方法中要好得多,在可读性和可维护性方面要好得多。