在java中假设我有2个列表
List<Object1> list1
List<Object2> list2
object1.getName(); returns a String
object2.getName(); return a String
有没有办法比较名称并获得两个列表
的区别这些2个对象是在第三方库中定义的,我不能覆盖等于和比较方法
我赞成googles Guava或commons集合库
但Sets.symmetricDifference(Set1, Set2)
要求传入2,
甚至我juse Sets.newHashSet(lis1)和Sets.newHashSet(lis2)来创建两个集合
但他们仍然在集合中有不同类型的对象。
或在公共CollectionUtils.disjunction(lis1, list2)
中,列表仍然必须包含相同的对象类型
没有做2个昂贵的for循环,还有其他方法吗?
答案 0 :(得分:1)
首先,我们将构建两个映射,每个映射一个映射,将名称映射到对象。然后我们迭代键集之间的差异,处理具有该名称的任何类型的对象。这些地图让我们可以避免扫描列表,查找具有该名称的对象。 (在使用Map而不是Multimap时,我依赖于每个列表中的the asker's comment on another answer,名称是唯一的。如果您仍在使用Java 7,请将方法引用替换为Function实现。)
Map<String, Object1> map1 = Maps.uniqueIndex(list1, Object1::getName);
Map<String, Object2> map2 = Maps.uniqueIndex(list2, Object1::getName);
for (String name : Sets.difference(map1.keySet(), map2.keySet()))
processObject1(map1.get(name));
for (String name : Sets.difference(map2.keySet(), map1.keySet()))
processObject2(map2.get(name));
如果您只想在一个列表中构建列表或对象集,processObject1
和processObject2
只需将对象添加到集合中即可。
uniqueIndex
的迭代顺序是输入可迭代的顺序,difference
返回一个与第一个参数具有相同迭代顺序的SetView,因此您可以按照它们出现的顺序处理对象。输入列表,如果该顺序与您的问题相关。
Java 8流提供基本相同的功能:
Map<String, Object1> map1 = list1.stream().collect(Collectors.toMap(Function.identity(), Object1::getName));
Map<String, Object2> map2 = list2.stream().collect(Collectors.toMap(Function.identity(), Object2::getName));
map1.keySet().stream().filter(n -> !map2.keySet().contains(n)).map(map1::get).forEachOrdered(o1 -> processObject1(o1));
map2.keySet().stream().filter(n -> !map1.keySet().contains(n)).map(map2::get).forEachOrdered(o2 -> processObject1(o2));
如果您只想收集对象,可以再次使用forEachOrdered
替换collect(Collectors.toList())
来电。
答案 1 :(得分:0)
使用番石榴,试试这个。它适用于我 - &gt;
Multisets.difference(multiset1,multiset2);
如何将ArrayList转换为Multiset。
List x = new ArrayList();
x.add(3);.....
Multiset newX = HashMultiset.create();
newX.addAll(x);
答案 2 :(得分:0)
首先,您必须将列表转换为基于字符串的列表:
private static final class FromObject1ToName implements Function<Object1, String> {
@Override
public String apply(Object1 input) {
return input.name;
}
}
必须对Object2进行相同的转换
然后转换输入列表:
Collection<String> transformed = Collections2.transform(list1, new FromObject1ToName());
// list1是Object1上的List
然后创建multiset:
Multiset<String> multiset1 = HashMultiset.create();
multiset1.addAll(transformed);
然后只需:
Multisets.difference(multiset1, multiset2) // multiset1 is from Object1 and multiset2 is from Object2
这将为您提供差异以及差异的次数
如果您需要知道只是差异,那么执行相同的转换,然后在Set adn中加载字符串Collection,然后执行Sets.symmetricDifference