首先,我们将构建两个映射,每个映射对应一个映射名称。然后我们遍历键集之间的差异,处理任何类型的对象都有这个名字。这些地图让我们避免在列表中扫描,寻找具有该名称的对象。 (在使用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())
,如果你只是想收集的对象。
你的名单有多大? – 2014-09-10 15:22:24
为什么for循环比任何其他解决方案都贵?除非你正在做一些非常聪明的并行执行,否则你将不得不精确地检查和转换每个对象一次。 – 2014-09-10 22:12:41
不是真的杰夫,试着比较两个对象列表,通常最终做两次for循环与另一个for循环。 n * n + n * n。但是,基于这些列表创建地图是n + n + n + n。我问这个问题,因为我徘徊有没有比4xns更好的解决方案 – 2014-09-11 08:59:24