两个 List的高效交集在Java中?
问题很简单:
我有两个列表
List<String> columnsOld = DBUtils.GetColumns(db, TableName);
List<String> columnsNew = DBUtils.GetColumns(db, TableName);
,我需要获得它们的交集。有没有一种快速的方法可以实现这一目标?
Question is simple:
I have two List
List<String> columnsOld = DBUtils.GetColumns(db, TableName);
List<String> columnsNew = DBUtils.GetColumns(db, TableName);
And I need to get the intersection of these. Is there a quick way to achieve this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
您可以使用
retainAll
方法:You can use
retainAll
method:使用 Google 的 Guava 库:
注意: 这就是很多比天真地与两个列表进行交集更有效:它是 O(n+m),而 列表版本的 O(n×m) 。对于两百万个项目的列表,这就是数百万次操作和数万亿次操作之间的区别。
Using Google's Guava library:
Note: This is much more efficient than naively doing the intersection with two lists: it's O(n+m), versus O(n×m) for the list version. With two million-item lists it's the difference between millions of operations and trillions of operations.
由于 keepAll 不会触及参数集合,因此速度会更快:
交集将是 columnsNew 中留下的值。从旧列中删除已比较的值将减少所需的比较次数。
Since retainAll won't touch the argument collection, this would be faster:
The intersection will be the values left in columnsNew. Removing already compared values fom columnsOld will reduce the number of comparisons needed.
怎么样
How about
如果不关心出现的情况,则使用retainAll,否则使用N.intersection
N 是 abacus-common< 中的一个实用程序类< /a>
using retainAll if don't care occurrences, otherwise using N.intersection
N is an utility class in abacus-common
对于流,有一种很好的方法,它可以在一行代码中完成此操作,并且您可以使用两个不同类型的列表,这对于 containsAll 方法来说是不可能的,据我所知:
不同类型列表的示例。如果 foo 和 bar 之间存在关系,并且可以从 foo 获取 bar 对象,那么您可以修改流:
There is a nice way with streams which can do this in one line of code and you can two lists which are not from the same type which is not possible with the containsAll method afaik:
An example for lists with different types. If you have a realtion between foo and bar and you can get a bar-object from foo than you can modify your stream:
如果将第二个列表放入一个集合中,例如 HashSet。只需迭代第一个列表,检查集合中是否存在,如果不存在则删除,您的第一个列表最终将具有您需要的交集。
它比列表中的retainAll或contains要快得多。
这里强调的是使用集合而不是列表。查找的时间复杂度为 O(1)。
firstList.retainAll(new HashSet(secondList))也将起作用。
If you put the second list in a set say HashSet. And just iterate over the first list checking for presence on the set and removing if not present, your first list will eventually have the intersection you need.
It will be way faster than retainAll or contains on a list.
The emphasis here is to use a set instead of list. Lookups are O(1).
firstList.retainAll (new HashSet (secondList)) will also work.
使用 org.apache.commons.collections4.ListUtils#intersection
use org.apache.commons.collections4.ListUtils#intersection
使用 Java 8 Stream API(和 Java 9 List.of())您可以执行以下操作:
With Java 8 Stream API (and Java 9 List.of()) you can do following: