我有一个具有列表属性的对象,例如
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
的最快方法。
请注意,我们还将两个列表中的B
与A
的列表进行比较,因此,如果存在匹配的A
,但存在增量的B
中,我们应该可以将其添加到existingList
的{{1}}的{{1}}中。
同样,如果我们检测到某项内容已从A
中删除,则应将其从bList
中删除。
注意,这不只是要比较两个对象,而是要在对象图中深处找到增量,并更新或添加新的和/或现有的零件。这是示例示例:
newList
答案 0 :(得分:0)
第1步:为两个类都实现equals()
和hashCode
。
第2步:将列表转换为集合。
第3步:使用Set
方法addAll
,removeAll
和/或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);
}
}