Java中的retainAll()函数笔记
public boolean retainAll(Collection C)
参数:集合C包含需要在列表中保留的元素
返回值:如果由于调用而导致列表更改,则该方法返回true,否则返回false。
ArrayList的Collection A.retainAll(Collection B)方法的用途:
1、保留当前Collection B实例中与Collection A重复的元素并作为参数传递给Collection A。
下边举两个例子来展示如何使用retain All函数:
1:把Collection B中的重复元素传递给Collection A
import java.util.ArrayList;
public class GFG {
public static void main(String[] args)
{
// 创建一个空的 array list
ArrayList<String> bags = new ArrayList<String>();
// 向bag中添加值
bags.add("pen");
bags.add("pencil");
bags.add("paper");
// 创建另外一个 array list
ArrayList<String> boxes = new ArrayList<String>();
// 向boxes添加值
boxes.add("pen");
boxes.add("paper");
boxes.add("books");
boxes.add("rubber");
// 未使用retainAll方法的bag和boxes
System.out.println("Bags Contains :" + bags);
System.out.println("Boxes Contains :" + boxes);
// 使用retainAll方法
boxes.retainAll(bags);
// 展示使用之后的值
System.out.println("\nAfter Applying retainAll()"+
" method to Boxes\n");
System.out.println("Bags Contains :" + bags);
System.out.println("Boxes Contains :" + boxes);
}
}
out put:
Bags Contains :[pen, pencil, paper]
Boxes Contains :[pen, paper, books, rubber]
After Applying retainAll() method to Boxes
Bags Contains :[pen, pencil, paper]
Boxes Contains :[pen, paper]
二、retainAll函数对数组中重复元素的处理
当你需要了解一个数组nums A和nums B中重复的元素时,比如:
nums1 = [1,2,2,1], nums2 = [2,2]。他们中的重复元素为:ans = [2]。
nums1 = [4,9,5], nums2 = [9,4,9,8,4]。他们中的重复元素为:ans = [9,4]。
简单的暴力方法可以将nums1中的所有元素放入名为int [] arr1的若干桶里,这样arr[i]代表数组nums1中值为i数字的个数,用此办法将nums2放入int[] arr2中,再对比两者的桶值,当arr1[i]=arr2[i]时,表明两数组中值为i的数字都存在,此时将i记入int[] ans中,遍历完所有桶即可返回所有重复数字。但这样的思路存在两个问题,首先时间复杂度和空间复杂度都很大,另外返回的ans数组很可能是[0,3,8,1,0,9,4,66,21,0,664,0,4,6],这里的0有两种可能,第一可能是input的两数组nums1和nums2都存在0元素,第二更可能是这个位置没有重复元素,所以数组初始化为0;如何判断?如何取出非0元素?所以换一种思路。
先将nums1与nums2转换为Set集合,再使用Set中的方法操作
1、使用java retainAll()函数
当你需要了解Collection A和Collection B中重复的元素时,使用Collection A.retainAll(Collection B)后,此时Collection A被改写为仅包含Collection A和Collection B交集的元素,剩余未写入部分为0;此时要返回Collection A和Collection B交集的元素,只要找到改写后的Collection A中元素即可:
set1.retainAll(set2);
int[] output =new int[set1.size()];
int idx =0;
for(int s:set1){
output[idx++]=s;
}
这样做的时间复杂度和空间复杂度要比直接使用set1.contains(elements of set2)好很多
2、使用Collection A.contains(elements of Collection B)
如果要使用contains函数,就必须先找到Collection A和Collection B中size更小的那个,遍历长度小的Collection可以降低时间复杂度。
public class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
HashSet<Integer> set1 = new HashSet<>();
HashSet<Integer> set2 = new HashSet<>();
for (int element:nums1){
set1.add(element);
}
for (int element:nums2){
set2.add(element);
}
if(set1.size()>set2.size()){
return set_intersection(set2,set1);
}else {
return set_intersection(set1,set2);
}
}
private int[] set_intersection(HashSet<Integer> set1,HashSet<Integer> set2){
int[] ans = new int[set1.size()];
int index = 0;
for(int element:set1){
if(set2.contains(element)){
ans[index]=element;
index++;
}
}
return Arrays.copyOf(ans,index);
}
}