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

Java - How to Remove Duplicates in ArrayList Based on Multiple Properties

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

private String mdl;
private String ndc;
private String gpi;
private String labelName;
private int seqNo;
private String vendorName;

mdl、ndc、gpi、seqNo共同构成了一条唯一的记录。我想在检查这 4 个属性的数组列表中查找重复项,然后如果列表中已存在具有相同 4 个属性的记录,则从列表中删除该记录。

.equals().hashCode() 应该被覆盖以说明您的密钥:mdl、ndc。 gpi, 序列号在这个网站上有无数的指南可以做到这一点,但是像:

@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 方法中隐藏该逻辑要好得多。