retainAll方法用于求两个集合的交集,修改调用集合使其仅保留与指定集合共有的元素,基于equals方法判断元素是否相同,会改变原集合内容并返回是否发生修改。

Java集合中的
retainAll
retainAll
java.util.Collection
ArrayList
HashSet
LinkedList
方法的签名是
boolean retainAll(Collection<?> c)
c
retainAll
c
boolean
true
false
工作原理和注意事项:
立即学习“Java免费学习笔记(深入)”;
retainAll
c.contains(element)
contains
false
这里有几个关键点需要注意:
equals()
equals()
equals()
hashCode()
retainAll
retainAll
c.contains(element)
retainAll
c
HashSet
contains
O(1)
retainAll
c
ArrayList
contains
O(n)
retainAll
O(n*m)
n
m
c
UnsupportedOperationException
remove
Collections.unmodifiableList()
NullPointerException
c
null
null
c
null
TreeSet
c
contains
null
代码示例:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class RetainAllDemo {
public static void main(String[] args) {
// 场景一:基本交集操作
List<String> myShoppingList = new ArrayList<>(Arrays.asList("Milk", "Bread", "Eggs", "Coffee", "Sugar"));
List<String> friendsShoppingList = new ArrayList<>(Arrays.asList("Bread", "Juice", "Eggs", "Milk", "Cheese"));
System.out.println("我的购物清单 (原始): " + myShoppingList);
System.out.println("朋友的购物清单: " + friendsShoppingList);
// 找出我们都需要买的东西
boolean changed = myShoppingList.retainAll(friendsShoppingList);
System.out.println("我们共同需要的物品 (我的清单更新后): " + myShoppingList); // [Milk, Bread, Eggs]
System.out.println("我的清单是否改变了? " + changed); // true
// 场景二:利用 Set 优化性能
List<Integer> allProducts = new ArrayList<>(Arrays.asList(101, 102, 103, 104, 105, 106, 107));
Set<Integer> availableProductsInStock = new HashSet<>(Arrays.asList(103, 105, 108, 109));
System.out.println("\n所有产品ID: " + allProducts);
System.out.println("库存中可用的产品ID: " + availableProductsInStock);
// 找出当前订单中,库存里也有的产品
boolean stockFiltered = allProducts.retainAll(availableProductsInStock);
System.out.println("订单中且有库存的产品ID: " + allProducts); // [103, 105]
System.out.println("产品列表是否因库存过滤而改变? " + stockFiltered); // true
// 场景三:没有共同元素
List<String> listA = new ArrayList<>(Arrays.asList("Alpha", "Beta"));
List<String> listB = new ArrayList<>(Arrays.asList("Gamma", "Delta"));
System.out.println("\nList A: " + listA);
System.out.println("List B: " + listB);
boolean noCommon = listA.retainAll(listB);
System.out.println("List A (无共同元素后): " + listA); // []
System.out.println("List A 是否改变? " + noCommon); // true (因为它清空了)
}
}retainAll
removeAll
这是一个非常常见的问题,也是理解集合操作的关键。
retainAll
removeAll
Collection
retainAll(Collection<?> c)
c
A = A ∩ B
removeAll(Collection<?> c)
c
A = A \ B
A
B
举个例子,你有一个朋友列表
myFriends
blackList
myFriends.retainAll(mutualFriends)
myFriends
mutualFriends
myFriends.removeAll(blackList)
myFriends
blackList
性能考量:
性能问题是使用
retainAll
removeAll
c
contains()
参数集合 c
HashSet
LinkedHashSet
c
HashSet
LinkedHashSet
contains()
O(1)
retainAll
removeAll
O(n)
n
contains
ArrayList
LinkedList
c
ArrayList
LinkedList
contains()
O(m)
m
c
retainAll
removeAll
O(n * m)
n
m
TreeSet
TreeSet
contains()
O(log m)
c
TreeSet
retainAll
removeAll
O(n * log m)
HashSet
ArrayList
优化策略: 当你的参数集合
c
ArrayList
Set
HashSet
retainAll
removeAll
List<String> largeList = new ArrayList<>(...); List<String> filterList = new ArrayList<>(...); // 假设这个列表很大 // 优化前 (潜在的 O(n*m)) // largeList.retainAll(filterList); // 优化后 (O(n) + O(m) for Set creation) Set<String> filterSet = new HashSet<>(filterList); // O(m) largeList.retainAll(filterSet); // O(n)
这种方式,即使加上创建
HashSet
O(n*m)
HashSet
retainAll
null
retainAll
null
retainAll
equals()
hashCode()
1. null
Java 集合对
null
equals()
ArrayList
HashSet
null
null
c
null
null
null
c
null
null
c
null
null
retainAll
TreeSet
null
TreeSet
null
compareTo()
null
null
A
A.retainAll(B)
B
TreeSet
B
null
A
null
A
null
B
TreeSet
Comparator
null
null
retainAll
NullPointerException
c
null
equals
c
contains
null
null
举个例子:
List<String> listWithNull = new ArrayList<>(Arrays.asList("A", null, "B"));
Set<String> setWithoutNull = new HashSet<>(Arrays.asList("A", "C"));
List<String> listWithNull2 = new ArrayList<>(Arrays.asList("A", null, "B"));
Set<String> setWithNull = new HashSet<>(Arrays.asList("A", null, "D"));
listWithNull.retainAll(setWithoutNull);
System.out.println("List with null after retaining set without null: " + listWithNull); // [A] (null 被移除了)
listWithNull2.retainAll(setWithNull);
System.out.println("List with null after retaining set with null: " + listWithNull2); // [A, null] (null 被保留了)2. 自定义对象处理:
这是
retainAll
retainAll
equals()
未重写 equals()
hashCode()
equals()
hashCode()
Object
Object
equals()
==
retainAll
class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 没有重写 equals() 和 hashCode()
@Override
public String toString() {
return "Person{" + "name='" + name + '\'' + ", age=" + age + '}';
}
}
List<Person> group1 = new ArrayList<>();
group1.add(new Person("Alice", 30));
group1.add(new Person("Bob", 25));
List<Person> group2 = new ArrayList<>();
group2.add(new Person("Alice", 30)); // 这是一个新的实例,内存地址不同
group2.add(new Person("Charlie", 35));
group1.retainAll(group2);
System.out.println("自定义对象 (未重写 equals) 后的 group1: " + group1); // [] (因为没有一个对象在内存地址上是相同的)以上就是Java集合中retainAll方法使用方法的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号