Java中两个List <String>的有效交集?

问题很简单:

我有两个列表

List<String> columnsOld = DBUtils.GetColumns(db, TableName); List<String> columnsNew = DBUtils.GetColumns(db, TableName); 

我需要得到这些交集。 有一个快速的方法来实现这一点?

你可以使用retainAll方法:

 columnsOld.retainAll (columnsNew); 

由于retainAll不会触及参数集合,所以这会更快:

 List<String> columnsOld = DBUtils.GetColumns(db, TableName); List<String> columnsNew = DBUtils.GetColumns(db, TableName); for(int i = columnsNew.size() - 1; i > -1; --i){ String str = columnsNew.get(i); if(!columnsOld.remove(str)) columnsNew.remove(str); } 

该交点将是列新左边的值。 删除已经比较的值fom columnsOld将减less所需的比较次数。

使用番石榴:

Sets.intersection(Sets.newHashSet(setA), Sets.newHashSet(setB))

谷歌番石榴图书馆

怎么样

 private List<String> intersect(List<String> A, List<String> B) { List<String> rtnList = new LinkedList<>(); for(String dto : A) { if(B.contains(dto)) { rtnList.add(dto); } } return rtnList; } 

有一个很好的方法可以在一行代码中执行此操作,并且可以使用两个不同于containsAll方法afaik所不能实现的相同types的列表:

 columnsOld.stream().filter(c -> columnsNew.contains(c)).collect(Collectors.toList()); 

不同types的列表的一个例子。 如果你在foo和bar之间有一个真实的话,你可以从foo得到一个bar-object而不是你可以修改你的stream:

 List<foo> fooList = new ArrayList<>(Arrays.asList(new foo(), new foo())); List<bar> barList = new ArrayList<>(Arrays.asList(new bar(), new bar())); fooList.stream().filter(f -> barList.contains(f.getBar()).collect(Collectors.toList()); 

使用retainAll如果不在意事件发生,否则使用N.intersection

 a = N.asList(12, 16, 16, 17, 19); b = N.asList(16, 19, 107); a.retainAll(b); // [16, 16, 19] N.println(a); a = N.asList(12, 16, 16, 17, 19); b = N.asList(16, 19, 107); a = N.intersect(a, b); N.println(a); // [16, 19] 

N是AbacusUtil中的一个实用工具类

如果你把一个集合中的第二个列表说成HashSet。 只要遍历第一个列表检查集合上的存在和删除如果不存在,你的第一个列表将最终有你需要的交集。 这将比保留所有或包含在列表上快。 这里的重点是使用一个集合而不是列表。 查找是O(1)。 firstList.retainAll(新的HashSet(secondList))也将工作。