Java - 如何基于多个属性删除 ArrayList 中的重复项



我想根据多个属性从数组列表中删除重复记录。这是一个示例域对象类:

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;
    }
}

我宁愿做这样的事情,而不是覆盖hashCodeequals方法,这些方法在默认状态下的另一个逻辑中可能是必需的......此外,明确显示您如何使用适当的方法(如generateUniqueKey(断言唯一性比将逻辑隐藏在某些hashCode方法中要好得多,在可读性和可维护性方面要好得多。

最新更新