代码之家  ›  专栏  ›  技术社区  ›  NuCradle

如何在Java中比较对象列表及其属性

  •  -1
  • NuCradle  · 技术社区  · 6 年前

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

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

    假设我们有两个 A s:

    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 .

    请注意,我们还比较了 B 这是给你的 A. 两个列表中都有,所以如果有匹配的 A. 是的,但他们的 B 是的,我们应该能够将其添加到 现有列表 是的 A. 是的 bList .

    同样,如果我们检测到一个项目已从 newList ,我们应该从 现有列表 .

    注意,这不仅仅是比较两个对象,而是在对象图的深处找到增量,并更新或添加新的和/或现有的部分。以下是示例:

    package collection.delta.model;
    
    import java.util.List;
    import java.util.Objects;
    
    import org.apache.commons.lang3.StringUtils;
    
    package collection.delta.model;
    
    import java.util.List;
    import java.util.Objects;
    
    import org.apache.commons.collections4.CollectionUtils;
    import org.apache.commons.lang3.StringUtils;
    
    public class A {
        private String aName;
    
        private List<B> bList;
    
        public String getaName() {
            return aName;
        }
    
        public void setaName(String aName) {
            this.aName = aName;
        }
    
        public List<B> getbList() {
            return bList;
        }
    
        public void setbList(List<B> bList) {
            this.bList = bList;
        }
    
        public A(String name, List<B> bList) {
            this.aName = name;
            this.bList = bList;
        }
    
        @Override
        public boolean equals(Object o) {
            if (o == null) {
                return false;
            }
    
            if (o == this) {
                return true;
            }
    
            if (!(o instanceof A)) {
                return false;
            }
    
            A b = (A) o;
            return StringUtils.isNotBlank(aName) && StringUtils.equalsAnyIgnoreCase(b.getaName(), aName)
                    && CollectionUtils.disjunction(this.getbList(), b.getbList()).isEmpty();
        }
    
        @Override
        public int hashCode() {
            if (StringUtils.isBlank(aName)) {
                return 31;
            }
    
            return Objects.hashCode(aName);
        }   
    
    package collection.delta.model;
    
    import java.util.Objects;
    
    import org.apache.commons.lang3.StringUtils;
    
    public class B {
        private String bName;
    
        public String getbName() {
            return bName;
        }
    
        public void setbName(String bName) {
            this.bName = bName;
        }
    
        public B(String name) {
            this.bName = name;
        }
    
        @Override
        public boolean equals(Object o) {
            if (o == null) {
                return false;
            }
    
            if (o == this) {
                return true;
            }
    
            if (!(o instanceof B)) {
                return false;
            }
    
            B b = (B) o;
            return StringUtils.isNotBlank(bName) && StringUtils.equalsAnyIgnoreCase(b.getbName(), bName);
        }
    
        @Override
        public int hashCode() {
            if (StringUtils.isBlank(bName)) {
                return 31;
            }
    
            return Objects.hashCode(bName);
        }
    }
    
    package collection.delta;
    
    import java.util.ArrayList;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Set;
    import java.util.function.Predicate;
    import java.util.stream.Collectors;
    
    import org.apache.commons.collections4.CollectionUtils;
    import org.apache.commons.lang3.StringUtils;
    
    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_B2"));
            bListNewA2.add(new B("originalA2_B3"));
            bListNewA2.add(new B("originalA2_B4"));
    
            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 = CollectionUtils.disjunction(originalA, newA).stream().collect(Collectors.toList());
            for (A a : newA) {
                for (A aResult : result) {
                    if (StringUtils.equalsAnyIgnoreCase(a.getaName(), aResult.getaName())) {
                        originalA.add(aResult);
                    }
                }
            }
    
            System.out.println("");
        }
    
    }
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   Andreas dfa    6 年前

    第一步:实施 equals() hashCode 两个班都有。

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

    第3步:使用一个或多个 Set 方法 addAll , removeAll ,和/或 retainAll 执行集合操作,如并集、交集和差集。

        2
  •  0
  •   surendrapanday 9swampy    6 年前

    如果你关心顺序,那么就使用equals方法:

    list1.equals(list2);
    

    从javadoc:

    将指定的对象与此列表进行相等性比较。退换商品 当且仅当指定对象也是列表时为true,两个列表 具有相同的大小,以及两个元素中所有对应的元素对 名单是平等的。(如果(e1==null,则两个元素e1和e2相等。)? e2==null:e1。等于(e2)换句话说,两个列表被定义为 如果它们以相同的顺序包含相同的元素,则表示相等。这 定义确保equals方法在多个应用程序中正常工作 列表接口的不同实现。

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

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

    这种方法的一个局限性是,它不仅忽略了顺序,而且忽略了重复元素的频率。例如,如果列表1是[“A”、“B”、“A”],而列表2是[“A”、“B”、“B”],集合方法会认为它们是相等的。

    如果你需要对订单不敏感,但对重复的频率敏感,你可以:

    对两个列表(或副本)进行排序,然后再进行比较 或者将所有元素复制到多集。

        3
  •  0
  •   NuCradle    6 年前

    这是有效的:

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