集合工具-SetUtil
# 📚 介绍
SetUtil 是 Hutool 核心模块中的集合(Set)专用操作工具类,它提供了丰富的集合操作方法,包括集合创建、转换、操作、运算和比较等功能,为 Java 开发者提供了便捷的集合操作解决方案。
# 设计理念
- 简化创建:提供多种方式创建集合
- 丰富操作:涵盖集合的各种常用操作
- 高效性能:底层实现经过优化,性能优异
- 易用性强:提供简洁的 API,一行代码即可完成复杂的集合操作
- 线程安全:所有工具类都是线程安全的,可以在多线程环境下安全使用
# 🔧 核心方法详解
# 1. 集合创建
# of(T... values)
功能:创建一个包含指定元素的集合
参数:
values:要包含在集合中的元素
返回值:包含指定元素的集合
示例:
// 创建包含指定元素的集合
Set<String> set = SetUtil.of("a", "b", "c");
Console.log(set); // [a, b, c]
// 创建包含单个元素的集合
Set<Integer> singleSet = SetUtil.of(1);
Console.log(singleSet); // [1]
// 创建空集合
Set<String> emptySet = SetUtil.of();
Console.log(emptySet); // []
# newHashSet(Collection<? extends T> collection)
功能:创建一个包含指定集合元素的 HashSet
参数:
collection:要包含在新集合中的元素
返回值:包含指定元素的 HashSet
示例:
List<String> list = Arrays.asList("a", "b", "c");
// 创建 HashSet
Set<String> hashSet = SetUtil.newHashSet(list);
Console.log(hashSet); // [a, b, c]
# newLinkedHashSet(Collection<? extends T> collection)
功能:创建一个包含指定集合元素的 LinkedHashSet(保留插入顺序)
参数:
collection:要包含在新集合中的元素
返回值:包含指定元素的 LinkedHashSet
示例:
List<String> list = Arrays.asList("c", "a", "b");
// 创建 LinkedHashSet(保留插入顺序)
Set<String> linkedHashSet = SetUtil.newLinkedHashSet(list);
Console.log(linkedHashSet); // [c, a, b]
# newTreeSet(Collection<? extends T> collection)
功能:创建一个包含指定集合元素的 TreeSet(自然排序)
参数:
collection:要包含在新集合中的元素
返回值:包含指定元素的 TreeSet
示例:
List<String> list = Arrays.asList("c", "a", "b");
// 创建 TreeSet(自然排序)
Set<String> treeSet = SetUtil.newTreeSet(list);
Console.log(treeSet); // [a, b, c]
# 2. 集合转换
# toSet(Collection<? extends T> collection)
功能:将集合转换为 Set
参数:
collection:要转换的集合
返回值:转换后的 Set
示例:
List<String> list = Arrays.asList("a", "b", "c", "a");
// 转换为 Set(自动去重)
Set<String> set = SetUtil.toSet(list);
Console.log(set); // [a, b, c]
# toSet(Iterator<? extends T> iterator)
功能:将迭代器转换为 Set
参数:
iterator:要转换的迭代器
返回值:转换后的 Set
示例:
Iterator<String> iterator = Arrays.asList("a", "b", "c", "a").iterator();
// 转换为 Set
Set<String> set = SetUtil.toSet(iterator);
Console.log(set); // [a, b, c]
# 3. 集合运算
# union(Set<? extends T>... sets)
功能:计算多个集合的并集
参数:
sets:要计算并集的集合
返回值:并集集合
示例:
Set<String> set1 = SetUtil.of("a", "b", "c");
Set<String> set2 = SetUtil.of("b", "c", "d");
Set<String> set3 = SetUtil.of("c", "d", "e");
// 计算并集
Set<String> unionSet = SetUtil.union(set1, set2, set3);
Console.log(unionSet); // [a, b, c, d, e]
# intersection(Set<? extends T>... sets)
功能:计算多个集合的交集
参数:
sets:要计算交集的集合
返回值:交集集合
示例:
Set<String> set1 = SetUtil.of("a", "b", "c");
Set<String> set2 = SetUtil.of("b", "c", "d");
Set<String> set3 = SetUtil.of("c", "d", "e");
// 计算交集
Set<String> intersectionSet = SetUtil.intersection(set1, set2, set3);
Console.log(intersectionSet); // [c]
# subtract(Set<? extends T> set1, Set<? extends T> set2)
功能:计算两个集合的差集(set1 - set2)
参数:
set1:第一个集合set2:第二个集合
返回值:差集集合
示例:
Set<String> set1 = SetUtil.of("a", "b", "c");
Set<String> set2 = SetUtil.of("b", "c", "d");
// 计算差集
Set<String> subtractSet = SetUtil.subtract(set1, set2);
Console.log(subtractSet); // [a]
# symmetricDifference(Set<? extends T> set1, Set<? extends T> set2)
功能:计算两个集合的对称差集((set1 ∪ set2) - (set1 ∩ set2))
参数:
set1:第一个集合set2:第二个集合
返回值:对称差集集合
示例:
Set<String> set1 = SetUtil.of("a", "b", "c");
Set<String> set2 = SetUtil.of("b", "c", "d");
// 计算对称差集
Set<String> symmetricDiffSet = SetUtil.symmetricDifference(set1, set2);
Console.log(symmetricDiffSet); // [a, d]
# 4. 集合操作
# addAll(Set set, T... values)
功能:向集合中添加多个元素
参数:
set:要添加元素的集合values:要添加的元素
返回值:添加元素后的集合
示例:
Set<String> set = SetUtil.of("a", "b");
// 添加多个元素
SetUtil.addAll(set, "c", "d", "e");
Console.log(set); // [a, b, c, d, e]
# removeAll(Set set, T... values)
功能:从集合中移除多个元素
参数:
set:要移除元素的集合values:要移除的元素
返回值:移除元素后的集合
示例:
Set<String> set = SetUtil.of("a", "b", "c", "d", "e");
// 移除多个元素
SetUtil.removeAll(set, "b", "d");
Console.log(set); // [a, c, e]
# 5. 集合比较
# equals(Set<?> set1, Set<?> set2)
功能:比较两个集合是否相等
参数:
set1:第一个集合set2:第二个集合
返回值:如果两个集合相等则返回 true,否则返回 false
示例:
Set<String> set1 = SetUtil.of("a", "b", "c");
Set<String> set2 = SetUtil.of("c", "b", "a");
Set<String> set3 = SetUtil.of("a", "c", "d");
// 比较集合
boolean equals1 = SetUtil.equals(set1, set2);
boolean equals2 = SetUtil.equals(set1, set3);
Console.log(equals1); // true(Set 是无序的,所以 [a,b,c] 和 [c,b,a] 相等)
Console.log(equals2); // false
# isSubset(Set<? extends T> subset, Set<? extends T> superset)
功能:判断一个集合是否是另一个集合的子集
参数:
subset:子集superset:超集
返回值:如果 subset 是 superset 的子集则返回 true,否则返回 false
示例:
Set<String> set1 = SetUtil.of("a", "b");
Set<String> set2 = SetUtil.of("a", "b", "c");
// 判断子集关系
boolean isSubset = SetUtil.isSubset(set1, set2);
Console.log(isSubset); // true
# isSuperset(Set<? extends T> superset, Set<? extends T> subset)
功能:判断一个集合是否是另一个集合的超集
参数:
superset:超集subset:子集
返回值:如果 superset 是 subset 的超集则返回 true,否则返回 false
示例:
Set<String> set1 = SetUtil.of("a", "b", "c");
Set<String> set2 = SetUtil.of("a", "b");
// 判断超集关系
boolean isSuperset = SetUtil.isSuperset(set1, set2);
Console.log(isSuperset); // true
# 🚀 综合示例
# 示例1:集合运算综合应用
public void setOperationTest() {
// 创建三个集合
Set<String> set1 = SetUtil.of("apple", "banana", "orange", "grape");
Set<String> set2 = SetUtil.of("banana", "orange", "watermelon", "peach");
Set<String> set3 = SetUtil.of("orange", "peach", "strawberry", "kiwi");
Console.log("集合1:" + set1); // [apple, banana, orange, grape]
Console.log("集合2:" + set2); // [banana, orange, watermelon, peach]
Console.log("集合3:" + set3); // [orange, peach, strawberry, kiwi]
// 计算并集
Set<String> unionSet = SetUtil.union(set1, set2, set3);
Console.log("\n并集:" + unionSet);
// 计算交集
Set<String> intersectionSet = SetUtil.intersection(set1, set2, set3);
Console.log("交集:" + intersectionSet);
// 计算差集
Set<String> subtractSet = SetUtil.subtract(set1, set2);
Console.log("集合1 - 集合2:" + subtractSet);
// 计算对称差集
Set<String> symmetricDiffSet = SetUtil.symmetricDifference(set1, set2);
Console.log("集合1 和 集合2 的对称差集:" + symmetricDiffSet);
// 判断子集关系
Set<String> subset = SetUtil.of("apple", "banana");
boolean isSubset = SetUtil.isSubset(subset, set1);
Console.log("\n[" + subset + "] 是集合1的子集:" + isSubset);
// 判断超集关系
boolean isSuperset = SetUtil.isSuperset(set1, subset);
Console.log("集合1 是 [" + subset + "] 的超集:" + isSuperset);
}
# 示例2:集合在标签系统中的应用
public class TagSystem {
private final Map<String, Set<String>> userTags = new HashMap<>();
/**
* 给用户添加标签
* @param userId 用户ID
* @param tags 要添加的标签
*/
public void addTags(String userId, String... tags) {
// 获取用户当前标签,如果不存在则创建新集合
Set<String> userCurrentTags = userTags.computeIfAbsent(userId, k -> SetUtil.newHashSet());
// 添加标签
SetUtil.addAll(userCurrentTags, tags);
}
/**
* 从用户移除标签
* @param userId 用户ID
* @param tags 要移除的标签
*/
public void removeTags(String userId, String... tags) {
Set<String> userCurrentTags = userTags.get(userId);
if (userCurrentTags != null) {
// 移除标签
SetUtil.removeAll(userCurrentTags, tags);
// 如果标签为空,移除用户记录
if (userCurrentTags.isEmpty()) {
userTags.remove(userId);
}
}
}
/**
* 获取用户标签
* @param userId 用户ID
* @return 用户标签集合
*/
public Set<String> getUserTags(String userId) {
Set<String> tags = userTags.get(userId);
return tags != null ? tags : SetUtil.newHashSet();
}
/**
* 查找拥有指定标签的所有用户
* @param tags 要查找的标签
* @return 拥有指定标签的用户ID集合
*/
public Set<String> findUsersByTags(String... tags) {
Set<String> targetTags = SetUtil.of(tags);
Set<String> matchedUsers = SetUtil.newHashSet();
// 遍历所有用户标签
for (Map.Entry<String, Set<String>> entry : userTags.entrySet()) {
String userId = entry.getKey();
Set<String> userCurrentTags = entry.getValue();
// 判断用户是否拥有所有指定标签
if (SetUtil.isSubset(targetTags, userCurrentTags)) {
matchedUsers.add(userId);
}
}
return matchedUsers;
}
}
// 使用示例
public void tagSystemTest() {
TagSystem tagSystem = new TagSystem();
// 添加用户标签
tagSystem.addTags("user1", "Java", "Python", "Web");
tagSystem.addTags("user2", "Java", "Spring", "Backend");
tagSystem.addTags("user3", "Python", "DataScience", "MachineLearning");
tagSystem.addTags("user4", "Java", "Python", "DevOps");
// 获取用户标签
Console.log("user1的标签:" + tagSystem.getUserTags("user1"));
Console.log("user2的标签:" + tagSystem.getUserTags("user2"));
// 移除用户标签
tagSystem.removeTags("user1", "Web");
Console.log("移除Web标签后,user1的标签:" + tagSystem.getUserTags("user1"));
// 查找拥有指定标签的用户
Set<String> javaUsers = tagSystem.findUsersByTags("Java");
Console.log("\n拥有Java标签的用户:" + javaUsers);
Set<String> javaPythonUsers = tagSystem.findUsersByTags("Java", "Python");
Console.log("拥有Java和Python标签的用户:" + javaPythonUsers);
}
# 🎯 设计优势
- 简化创建:提供了多种便捷的集合创建方式,包括直接创建、从集合创建等
- 丰富操作:涵盖了集合的各种常用操作,包括创建、转换、运算、操作和比较等
- 高效性能:底层实现经过优化,性能优异,特别是对于大规模集合
- 易用性强:提供了简洁的 API,一行代码即可完成复杂的集合操作
- 线程安全:所有方法都是线程安全的,可以在多线程环境下安全使用
- 兼容性好:兼容 Java 各种版本,支持各种集合实现
# 📌 注意事项
- 集合类型:不同的集合创建方法返回不同类型的集合,使用时注意选择合适的类型
- 空值处理:大部分方法都进行了空值处理,但在使用时仍需注意
- 线程安全:虽然 SetUtil 本身是线程安全的,但集合对象的线程安全性取决于具体的集合实现
- 性能考虑:对于大规模集合,某些操作可能会影响性能,建议根据实际情况选择合适的方法
- 集合无序性:Set 是无序的,遍历时不能保证元素顺序(LinkedHashSet 除外)
# 🚀 总结
SetUtil 是一个功能强大、使用便捷的集合操作工具类,为 Java 开发者提供了丰富的集合操作解决方案。它简化了集合的创建、转换、运算、操作和比较等操作,提高了开发效率。
无论是简单的集合创建,还是复杂的集合运算,SetUtil 都能轻松应对。通过合理使用 SetUtil,可以简化集合操作的开发工作,提高开发效率,同时保证操作的准确性和性能。
SetUtil 是 Hutool 集合模块中的重要组成部分,与其他集合工具类一起,构成了完整的集合操作解决方案,为 Java 开发者提供了丰富的集合操作工具。