我有两个 ArrayList<Integer>
,内容如下:
原始列表: 12, 16, 17, 19, 101
选中列表: 16, 19, 107, 108, 109
我想对这两个列表进行差异处理,最终得到两个列表:
添加: 108, 109, 107
删除: 12, 17, 101
原始列表和选中列表的长度可能不同,其中一个可能比另一个长或短。
我有两个 ArrayList<Integer>
,内容如下:
原始列表: 12, 16, 17, 19, 101
选中列表: 16, 19, 107, 108, 109
我想对这两个列表进行差异处理,最终得到两个列表:
添加: 108, 109, 107
删除: 12, 17, 101
原始列表和选中列表的长度可能不同,其中一个可能比另一个长或短。
作为替代方案,您可以使用来自Apache commons库的CollectionUtils。它具有适用于您情况的静态intersection、union和subtract方法。
List<Integer> original = Arrays.asList(12,16,17,19,101);
List<Integer> selected = Arrays.asList(16,19,107,108,109);
ArrayList<Integer> add = new ArrayList<Integer>(selected);
add.removeAll(original);
System.out.println("Add: " + add);
ArrayList<Integer> remove = new ArrayList<Integer>(original);
remove.removeAll(selected);
System.out.println("Remove: " + remove);
输出:
Add: [107, 108, 109]
Remove: [12, 17, 101]
使用Collection的removeAll方法。请参见javadocs。
removeAll
会删除每个值的所有出现次数 - 因此,如果'16'在selected
中出现两次,它仍然不会出现在最终的add
中。因此,如果您需要检测重复项(例如在列表中查找缺失、意外和重复项),则不适用。 - simon.watts交集: original.retainAll(selected)
。
执行后,原始集合将只包含两个集合中都存在的元素。如果有任何更改,则返回true。
警告:对于大型集合,此方法非常缓慢。
Set
https://docs.oracle.com/javase/7/docs/api/java/util/Set.html#retainAll(java.util.Collection)。 - ACV对于交集和并集操作,自然的集合类型是Set而不是List,使用Set更加高效。
List<Integer> listA = Lists.newArrayList(12,16,17,19,101);
List<Integer> listB = Lists.newArrayList(16,19,107,108,109);
Set<Integer> intersection = Sets.intersection(Sets.newHashSet(listA), Sets.newHashSet(listB));
listA.removeAll(intersection);
listB.removeAll(intersection);
Set<?>
。你可以传递例如Set<String>
,编译器不会抱怨。 - user829755 List<Integer> original;
List<Integer> selected;
List<Integer> add = new ArrayList<Integer>(selected);
add.removeAll(original);
List<Integer> remove = new ArrayList<Integer>(original);
remove.removeAll(selected);
在处理重复元素的边界情况时要小心。 应该尊重基数吗? 例如,如果我最初有5,6
,之后是5,5,6
,那么加法应该是5
吗? 使用Set
更好,因为它们没有重复项(而且contains()
查找速度更快,因为它们按其包含的数据进行索引)。
如果您想获取列表的交集,可以使用此方法。
List<Address> resultsIntersectionSet( List<Set<Address>> inputListOfLists )
{
Set<Address> intersection = new HashSet<>();
if ( !inputListOfLists.isEmpty() )
intersection = inputListOfLists.get( 0 );
for ( Set<Address> filterResultList : inputListOfLists )
{
intersection.retainAll( filterResultList );
}
return new ArrayList<>( intersection );
}
现在有一个新的库可用underscore-java。它可以对列表和数组进行差异和交集操作。实时示例。
代码示例:
List<Integer> original = Arrays.asList(12, 16, 17, 19, 101);
List<Integer> selected = Arrays.asList(16, 19, 107, 108, 109);
List<Integer> add = U.difference(selected, U.intersection(original, selected));
List<Integer> remove = U.difference(original, selected);
package LAB8Pack;
import java.util.HashSet;
import java.util.Iterator;
import java.lang.StringBuilder;
public class HashSetDemo {
public static void main(String[] args) {
HashSet<String> round = new HashSet<String> ();
HashSet<String> green = new HashSet<String> ();
// Add elements to 'round' and 'green' sets
//----------------------------------------------------
round.add("peas");
green.add("peas");
round.add("watermelon");
green.add("watermelon");
round.add("basketball");
green.add("chameleon");
round.add("chameleon");
green.add("grass");
round.add("eyes");
green.add("book");
// Create 'setUnion' and 'setInter'
// ---------------------------------------------------
HashSet<String> setUnion = new HashSet<String>();
// Use this to find the intersection
HashSet<String> SETINTER = new HashSet<String>();
HashSet<String> setInter1 = new HashSet<String>(round);
HashSet<String> setInter2 = new HashSet<String>(green);
// Add all the elements to one set
setUnion.addAll(round);
setUnion.addAll(green);
SETINTER.addAll(setUnion);
// Create an intersection
setInter1.removeAll(green); // Get unique items in round
setInter2.removeAll(round); // Get unique items in green
SETINTER.removeAll(setInter2); // Remove items that are unique to green
SETINTER.removeAll(setInter1); // Remove items that are unique to round
//----------------------------------------------------
// DISPLAY RESULTS
// ===================================================
System.out.println("Content of set round");
System.out.println("-----------------------");
System.out.println(OutputSet(round));
System.out.println("Content of set green");
System.out.println("-----------------------");
System.out.println(OutputSet(green));
System.out.println("Content of set Union");
System.out.println("-----------------------");
System.out.println(OutputSet(setUnion));
System.out.println("Content of set Intersection");
System.out.println("-----------------------");
System.out.println(OutputSet(SETINTER));
}
// METHODS
// =======================================================
static StringBuilder OutputSet (HashSet<String> args) {
Iterator iterator = args.iterator();
StringBuilder sB = new StringBuilder ();
while (iterator.hasNext()) {
sB.append(iterator.next() + " \n");
}
return sB;
}
}
public static <T, C extends Collection<T>> C findIntersection(C newCollection,
Collection<T>... collections) {
boolean first = true;
for (Collection<T> collection : collections) {
if (first) {
newCollection.addAll(collection);
first = false;
} else {
newCollection.retainAll(collection);
}
}
return newCollection;
}
使用方法 -
public static void main(String[] args) {
List<Integer> l1 = List.of(1, 3, 5, 7, 9, 11, 13);
List<Integer> l2 = List.of(1, 2, 3, 5, 8, 13);
List<Integer> l3 = List.of(2, 3, 5, 7, 11, 13);
Set<Integer> intersection = findIntersection(new HashSet<>(), l1, l2, l3);
System.out.println(intersection);
}
108,109
” 应该翻译为 “添加:108,109
”,而问题的意思是是否应该将其改为“添加:107,108,109
”? - Asaph16,19
。 - Mark Peters