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

时间:2019-07-11 23:34:06

标签: java arrays list arraylist comparator

我想基于多个属性从arraylist中删除重复的记录。这是一个示例域对象类:

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

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

2 个答案:

答案 0 :(得分: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。它将使您的代码更高效(没有重复项的情况下更少的内存使用),并且无需在以后搜索重复项。

答案 1 :(得分:1)

您可以尝试执行以下操作;

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方法中要好得多,就可读性和可维护性而言。