[英]Get intersection of several Lists using retainAll in Java
我很難找到Java上幾個列表的交集。 我正在做的是:我得到(讓我們說)3個整數列表:
清單1:[2,2,2,2,5,5]
清單2:[2,2,103]
清單3:[2,431]
我正在使用每個剩余列表將retainAll應用於第一個:
list1.retainAll(list2);
list1.retainAll(list3);
我得到了這個結果:
list1:[2,2,2,2]
但我希望得到這個:
list1:[2]
...因為所有列表共享的唯一元素是一個 2而不是四個 2。
我知道這可能是retainAll函數的預期行為,但我需要得到上面提到的結果。
有幫助嗎?
編輯:使用HashSet禁止重復也不會有效。 在這種情況下,例如:
清單1:[2,2,2,2,5,5]
清單2:[2,2,103]
清單3:[2,2,2,431]
我需要得到一個結果:
清單1:[2,2](因為所有列表至少有一對2)
代替
清單1:[2]
這個方法怎么樣:
public static <T> Collection <T> intersect (Collection <? extends T> a, Collection <? extends T> b)
{
Collection <T> result = new ArrayList <T> ();
for (T t: a)
{
if (b.remove (t)) result.add (t);
}
return result;
}
public static void main (String [] args)
{
List <Integer> list1 = new ArrayList <Integer> (Arrays.<Integer>asList (2, 2, 2, 2, 5, 5));
List <Integer> list2 = new ArrayList <Integer> (Arrays.<Integer>asList (2, 2, 103));
List <Integer> list3 = new ArrayList <Integer> (Arrays.<Integer>asList (2, 431));
System.out.println (intersect (list1, intersect (list2, list3)));
}
使用多集數據結構可以更輕松地解決此問題。 例如,如果你使用guava的Multiset
,你可以使用Multisets.retainOccurrences()
我會使用某種Set
,也許是HashSet
。 它們不會添加重復元素,並且它們具有retainAll
方法。
Set<Integer> uniqueNums = new HashSet<Integer>(list1);
uniqueNums.retainAll(list2);
uniqueNums.retainAll(list3);
這是Set
的javadocs 。
您需要一個名為bag或multiset的數據結構,而不是列表。 例如,Apache commons集合庫包括一個:
有了retainAll
你會得到錯誤的答案。 我建議你使用HashMap
保持integer/count
對並掃描彼此列表並縮小你的map
。
list1
的值填充map
。 min(# of intg in other_list, map.get(intg))
並使用該值更新map
。 map
將是所有列表的交集。 這是一個你喜歡的,它是遞歸的。
public static <T> List<T> intersect(List<T> c1, List<T> c2) {
List<T> inter = new ArrayList<>(c1);
inter.retainAll(c2);
return inter;
}
public static <T> List<T> intersect(List<T> first, List<T>... rest) {
if (rest.length == 0)
return first;
List<T> second = rest[0];
first = intersect(first,second);
rest = Arrays.copyOfRange(rest, 1, rest.length);
return intersect(first, rest);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.