合并两个 java 中的对象列表 8

2022-09-01 07:48:02

我有一个Java类,有20个属性及其相应的getter和setter。另外,我有两个对象列表:和.Parent(attrib1, attrib2 .. attrib20)Parentlist1list2

现在我想合并两个列表,并避免基于 和 的重复对象。attrib1attrib2

使用 Java 8:

List<Parent> result = Stream.concat(list1.stream(), list2.stream())
                .distinct()
                .collect(Collectors.toList());   

但是我必须在哪个位置指定属性?我应该重写和方法吗?hashCodeequals


答案 1

如果要实现 和 ,则执行该操作的地方是在类。在该类中添加如下方法:equalshashCodeParent

    @Override
    public int hashCode() {
        return Objects.hash(getAttrib1(), getAttrib2(), getAttrib3(),
            // …
                            getAttrib19(), getAttrib20());
    }

    @Override
    public boolean equals(Object obj) {
        if(this==obj) return true;
        if(!(obj instanceof Parent)) return false;
        Parent p=(Parent) obj;
        return Objects.equals(getAttrib1(), p.getAttrib1())
            && Objects.equals(getAttrib2(), p.getAttrib2())
            && Objects.equals(getAttrib3(), p.getAttrib3())
            // …
            && Objects.equals(getAttrib19(), p.getAttrib19())
            && Objects.equals(getAttrib20(), p.getAttrib20());
    }

如果你这样做了,调用一个意志会自动做正确的事情。distinct()Stream<Parent>


如果您不想(或不能)更改类,则没有相等的委派机制,但您可以诉诸排序,因为它具有委派机制:Parent

Comparator<Parent> c=Comparator.comparing(Parent::getAttrib1)
        .thenComparing(Parent::getAttrib2)
        .thenComparing(Parent::getAttrib3)
        // …
        .thenComparing(Parent::getAttrib19)
        .thenComparing(Parent::getAttrib20);

这将根据属性定义订单。它要求属性本身的类型具有可比性。如果你有这样的定义,你可以用它来实现 一个 的等价物,基于这个:distinct()Comparator

List<Parent> result = Stream.concat(list1.stream(), list2.stream())
        .filter(new TreeSet<>(c)::add)
        .collect(Collectors.toList());

还有一个线程安全变体,以防您想将其用于并行流:

List<Parent> result = Stream.concat(list1.stream(), list2.stream())
        .filter(new ConcurrentSkipListSet<>(c)::add)
        .collect(Collectors.toList());

答案 2

例如:

public class Parent {

    public int no;
    public String name;

    @Override
    public int hashCode() {
        return (no << 4) ^ name.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof Parent))
            return false;
        Parent o = (Parent)obj;
        return this.no == o.no && this.name.equals(o.name);
    }
}

推荐