【问题标题】:How to Compare a List of Objects and Their Properties, then Update the Original List in Java如何比较对象列表及其属性,然后在 Java 中更新原始列表
【发布时间】:2019-03-01 01:09:27
【问题描述】:

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

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 存在增量s,我们应该可以将其添加到existingList's A's bList

同样,如果我们检测到某个项目已从 newList 中删除,我们应该将其从 existingList 中删除。

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

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

}

【问题讨论】:

  • @surendrapanday 这个问题不仅仅是两个对象的比较。在了解问题之前,请不要将其标记为重复或否决。
  • 只是让你知道我没有对你投反对票,但我发现了很多与此相关的其他问题;别人对你投了反对票,我不知道是谁做的。

标签: java list collections comparison delta


【解决方案1】:

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

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

第 3 步:使用 addAllremoveAll 和/或 retainAll 中的一个或多个 Set 方法来执行集合运算,例如并集、交集和差集。

【讨论】:

    【解决方案2】:

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

    list1.equals(list2);
    

    来自 javadoc:

    比较指定对象与此列表是否相等。退货 当且仅当指定的对象也是一个列表时才为真,这两个列表 具有相同的大小,并且两者中所有对应的元素对 列表是相等的。 (两个元素 e1 和 e2 相等 if (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 方法会认为它们是相等的。

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

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

    【讨论】:

      【解决方案3】:

      这行得通:

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

      【讨论】:

        猜你喜欢
        • 2020-04-30
        • 1970-01-01
        • 2020-04-10
        • 2022-06-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多