如何比较对象及其属性的列表,然后更新Java中的原始列表

时间:2019-03-01 01:09:27

标签: java list collections comparison delta

我有一个具有列表属性的对象,例如

public class A {
  private String aName;
  private List<B> bList;
}

public class B {
  private String bName;
}

让我们假设我们有两个A的列表:

List<A> existingList = new ArrayList<A>();
// populate it with a list of A's which in turn, each has its own list of B's

List<A> newList = new ArrayList<A>();
// populate it with possibly some new A's and/or, an existing A which its property B has new items

考虑到这一点,我想知道比较这两个A列表并将这两个列表的增量添加到existingList的最快方法。

请注意,我们还将两个列表中的BA的列表进行比较,因此,如果存在匹配的A,但存在增量的B中,我们应该可以将其添加到existingList的{​​{1}}的{​​{1}}中。

同样,如果我们检测到某项内容已从A中删除,则应将其从bList中删除。

注意,这不只是要比较两个对象,而是要在对象图中深处找到增量,并更新或添加新的和/或现有的零件。这是示例示例:

newList

3 个答案:

答案 0 :(得分:0)

第1步:为两个类都实现equals()hashCode

第2步:将列表转换为集合。

第3步:使用Set方法addAllremoveAll和/或retainAll中的一个或多个来执行诸如并集,交集和差之类的集合操作

答案 1 :(得分:0)

如果您关心顺序,则只需使用equals方法:

list1.equals(list2);

来自javadoc:

  

将指定的对象与此列表进行比较以确保相等。退货   当且仅当指定对象也是列表时,才返回true   具有相同的大小,并且两个中的所有对应元素对   名单是平等的。 (两个元素e1和e2相等,如果(e1 == null?   e2 == null:e1.equals(e2))。换句话说,两个列表被定义为   如果它们包含相同顺序的相同元素,则相等。这个   定义可确保equals方法可跨   List接口的不同实现。

如果要独立于顺序进行检查,可以将所有元素复制到Sets并在结果Sets上使用equals

public static <T> boolean listEqualsIgnoreOrder(List<T> list1, List<T> list2) {
    return new HashSet<>(list1).equals(new HashSet<>(list2));
}

此方法的局限性在于它不仅忽略顺序,而且忽略重复元素的频率。例如,如果list1为[“ A”,“ B”,“ A”],而list2为[“ A”,“ B”,“ B”],则Set方法将认为它们相等。

如果您对订单不敏感,但对重复的频率敏感,则可以:

在比较它们之前对两个列表(或副本)进行排序 或将所有元素复制到多集。

答案 2 :(得分:0)

这有效:

package collection.delta;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import collection.delta.model.A;
import collection.delta.model.B;

public class App {
    public static void main( String[] args ) {

        List<A> originalA = new ArrayList<A>();
        List<A> newA = new ArrayList<A>();

        List<B> bListOriginalA1 = new ArrayList<B>();
        bListOriginalA1.add(new B("originalA1_B1"));
        bListOriginalA1.add(new B("originalA1_B2"));
        bListOriginalA1.add(new B("originalA1_B3"));
        bListOriginalA1.add(new B("originalA1_B4"));

        A originalA1 = new A("originalA1", bListOriginalA1);

        List<B> bListOriginalA2 = new ArrayList<B>();
        bListOriginalA2.add(new B("originalA2_B1"));
        bListOriginalA2.add(new B("originalA2_B2"));
        bListOriginalA2.add(new B("originalA2_B3"));
        bListOriginalA2.add(new B("originalA2_B4"));

        A originalA2 = new A("originalA2", bListOriginalA2);

        List<B> bListOriginalA3 = new ArrayList<B>();
        bListOriginalA3.add(new B("originalA3_B1"));
        bListOriginalA3.add(new B("originalA3_B2"));
        bListOriginalA3.add(new B("originalA3_B3"));
        bListOriginalA3.add(new B("originalA3_B4"));

        A originalA3 = new A("originalA3", bListOriginalA3);

        originalA.add(originalA1);
        originalA.add(originalA2);
        originalA.add(originalA3);


        List<B> bListNewA1 = new ArrayList<B>();
        bListNewA1.add(new B("originalA1_B1"));
        bListNewA1.add(new B("originalA1_B2"));
        bListNewA1.add(new B("originalA1_B3"));
        bListNewA1.add(new B("originalA1_B4"));

        A newA1 = new A("originalA1", bListNewA1);

        List<B> bListNewA2 = new ArrayList<B>();
        bListNewA2.add(new B("originalA2_B1"));
        bListNewA2.add(new B("originalA2_B3"));
        bListNewA2.add(new B("originalA2_B4"));
        bListNewA2.add(new B("originalA2_B2"));

        A newA2 = new A("originalA2", bListNewA2);

        List<B> bListNewA3 = new ArrayList<B>();
        bListNewA3.add(new B("originalA3_B1"));
        bListNewA3.add(new B("originalA3_B2"));
        bListNewA3.add(new B("originalA3_B5"));
        bListNewA3.add(new B("originalA3_B4"));

        A newA3 = new A("originalA3", bListNewA3);

        List<B> bListNewA4 = new ArrayList<B>();
        bListNewA4.add(new B("A4_B1"));
        bListNewA4.add(new B("A4_B2"));
        bListNewA4.add(new B("A4_B3"));
        bListNewA4.add(new B("A4_B4"));

        A newA4 = new A("originalA4", bListNewA4);

        newA.add(newA1);
        newA.add(newA2);
        newA.add(newA3);
        newA.add(newA4);

        List<A> result = newA.stream()
                .filter(not(new HashSet<A>(originalA)::contains))
                .collect(Collectors.toList());

        A tempA = null;
        B tempB = null;
        List<B> bList = null;
        for (A a : result) {
            if (!containsName(originalA, a.getaName())) {
                originalA.add(a);
            } else {
                tempA = getAIfPresent(originalA, a.getaName());

                if (tempA != null) {

                    bList = a.getbList().stream()
                            .filter(not(new HashSet<B>(tempA.getbList())::contains))
                            .collect(Collectors.toList());

                    if (bList != null) {
                        tempA.getbList().addAll(bList);
                    }
                }
            }
        }

        System.out.println("");
    }

    public static <T> Predicate<T> not(Predicate<T> predicate) {
        return predicate.negate();
    }

    public static boolean containsName(final List<A> list, final String name){
        return list.stream().map(A::getaName).filter(name::equals).findFirst().isPresent();
    }

    public static A getAIfPresent(final List<A> list, final String name) {
        return list.stream().filter(x -> x.getaName().equalsIgnoreCase(name)).findFirst().orElse(null);
    }

}