Java中取多个集合的交集——retainAll()
Java中取多个集合的交集
集合 Collection 接⼝中定义了 retainAll()⽅法
retainAll()
Retains only the elements in this set that are contained in the specified collection (optional operation). In other words, removes from this set all of its elements that are not contained in the specified collection. If the specified collection is also a set, this operation effectively modifies this set so that its value is the intersection of the two sets.
简单来说,该⽅法⽬的是取当前集合及参数指定集合的⼀个交集,并修改当前集合,仅保留交集元素。
下图是集合类框架的⼀个架构图:
通过这个架构图,可以在⼤脑中对集合这块的类有个清晰的定位。
抽象类 AbstractCollection 中对 retainAll() ⽅法进⾏了实现。
使⽤Set集合的 retainAll() ⽅法,其实就是调⽤了AbstractCollection中的 retainAll()⽅法。
其底层其实使⽤的 contains() ⽅法进⾏判断元素是否存在集合中。对于当前集合中的元素进⾏遍历,判断每个元素是否存在于参数集合中,若不存在则从当前集合中移除该元素,最终保留的就是两个集合共有的元素。
public boolean retainAll(Collection<?> c){
boolean modified =false;
Iterator<E> it =iterator();
while(it.hasNext()){
if(!c.())){
modified =true;
}
}
return modified;
}
对于 ArrayList 类,对 retainAll() ⽅法进⾏了重写。其中的核⼼思路是⼀样的。
public boolean retainAll(Collection<?> c){
return batchRemove(c,true);
}
private boolean batchRemove(Collection<?> c,boolean complement){
final Object[] elementData =this.elementData;
int r =0, w =0;
boolean modified =false;
try{
for(; r < size; r++)
ains(elementData[r])== complement)
elementData[w++]= elementData[r];
}finally{
// Preserve behavioral compatibility with AbstractCollection,
// even ains() throws.
if(r != size){
System.arraycopy(elementData, r,
elementData, w,
size - r);
w += size - r;
}
if(w != size){
// clear to let GC do its work
for(int i = w; i < size; i++)
resultset 遍历elementData[i]=null;
modCount += size - w;
size = w;
modified =true;
}
}
return modified;
}
对于多个集合取交集(不确定集合的个数)
思路:创建⼀个新的 List 集合,将⽬标集合都放⼊新创建的 List 集合中,若有条件过滤,可使⽤stream流进⾏条件筛选(⽐如去掉空集合),最终得到结果 List 集合。 然后遍历该集合,使⽤集合中的第⼀个集合⼀次和后续的每个集合取交集,即可得到所有集合的交集。
Set set1 =new HashSet();
Set set2 =new HashSet();
Set set3 =new HashSet();
set1.add("1");
set2.add("1");
set2.add("2");
set3.add("1");
List<Set> setList =new ArrayList<>();
setList.add(set1);
setList.add(set2);
setList.add(set3);
//List<Set> resultSetList = setList.stream().filter(Objects::nonNull).List());
Set resultSet = (0);
resultSetList.forEach(item ->{
});
//resultSet 结果仅包含 1
再复杂的东西都是由简单的东西组成的,只因量变达到质变。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论