我在Java上获得多个列表的交集时遇到了麻烦。我正在做的是这样的: 我得到(比方说)3个整数列表:
清单1:[2,2,2,2,5,5]
清单2:[2,2,103]
列表3:[2,491]
我使用其余每个列表将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]
答案 0 :(得分:6)
这种方法怎么样:
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)));
}
答案 1 :(得分:2)
使用多集数据结构可以更轻松地解决此问题。例如,如果您使用番石榴Multiset
,则可以使用Multisets.retainOccurrences()
答案 2 :(得分:2)
我会使用某种Set
,也许是HashSet
。他们不会添加重复元素,并且他们使用retainAll
方法。
Set<Integer> uniqueNums = new HashSet<Integer>(list1);
uniqueNums.retainAll(list2);
uniqueNums.retainAll(list3);
以下是Set
的{{3}}。
答案 3 :(得分:0)
您需要一个名为bag或multiset的数据结构,而不是列表。例如,Apache commons集合库包括一个:
答案 4 :(得分:0)
如你所说,retainAll
你会得到错误的答案。我建议您使用HashMap
保留integer/count
对并扫描彼此列表并缩小map
范围。
map
。list1
min(# of intg in other_list, map.get(intg))
并使用该值更新map
。map
将是所有列表的交集。答案 5 :(得分:0)
这是一个你喜欢的,它是递归的。
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);
}