Efficient intersection of two List in Java

2019-01-09 02:09发布

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?

7条回答
放荡不羁爱自由
2楼-- · 2019-01-09 02:33

You can use retainAll method:

columnsOld.retainAll (columnsNew);
查看更多
相关推荐>>
3楼-- · 2019-01-09 02:34

Using Guava:

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

Google Guava Library

查看更多
成全新的幸福
4楼-- · 2019-01-09 02:34

using retainAll if don't care occurrences, otherwise using 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 is an utility class in AbacusUtil

查看更多
小情绪 Triste *
5楼-- · 2019-01-09 02:42

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:

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

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:

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());
查看更多
Fickle 薄情
6楼-- · 2019-01-09 02:52

How about

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;
}
查看更多
我欲成王,谁敢阻挡
7楼-- · 2019-01-09 02:52

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.

查看更多
登录 后发表回答