闽公网安备 35020302035485号
.传统集合处理需手动实现判空、筛选、去重等操作,步骤繁琐且易出问题。
.判空需重复编写if (list == null || list.isEmpty()),多集合判空时代码堆积严重。
.去重需创建Set并循环添加元素,自定义对象还需重写equals方法,操作复杂。// 传统集合处理:筛选启用用户、去重、求交集
public List<Long> getValidUserIds(List<User> userList, List<Long> roleAuthUserIds) {
// 1. 判空用户列表,避免NPE,空则返回空集合
if (userList == null || userList.isEmpty()) {
return Collections.emptyList();
}
// 堆代码 duidaima.com
// 2. 判空权限ID列表,避免NPE,空则返回空集合
if (roleAuthUserIds == null || roleAuthUserIds.isEmpty()) {
return Collections.emptyList();
}
// 3. 创建列表存储启用的用户
List<User> activeUsers = new ArrayList<>();
// 4. 循环遍历用户列表,筛选启用的非空用户
for (User user : userList) {
if (user != null && user.isActive()) {
activeUsers.add(user);
}
}
// 5. 创建Set存储去重后的用户ID
Set<Long> activeUserIds = new HashSet<>();
// 6. 循环提取启用用户的ID,利用Set实现去重
for (User user : activeUsers) {
activeUserIds.add(user.getId());
}
// 7. 创建列表存储最终有效的用户ID
List<Long> validIds = new ArrayList<>();
// 8. 双重循环比对,获取用户ID与权限ID的交集
for (Long id : activeUserIds) {
if (roleAuthUserIds.contains(id)) {
validIds.add(id);
}
}
// 9. 返回有效用户ID列表
return validIds;
}
代码解析:
该方法需9步完成核心逻辑,步骤繁琐且耦合度高。
.首先通过两次独立if判断实现集合判空,若遗漏任一判空,后续循环会引发NPE。
@Service
public class UserService {
// 1. 集合判空与非空校验
public void checkUserList(List<User> userList) {
// 校验集合是否为空(支持List/Set/Map/Iterator等所有集合类型)
if (CollUtil.isEmpty(userList)) {
throw new IllegalArgumentException("用户列表不能为空");
}
// 校验集合是否非空,等价于!CollUtil.isEmpty(userList),提升可读性
if (CollUtil.isNotEmpty(userList)) {
System.out.println("用户列表共" + userList.size() + "人");
}
}
// 2. 集合为空时返回默认集合
public List<User> getDefaultUserList(List<User> userList) {
// 创建默认用户列表,用于集合为空时返回
List<User> defaultUsers = Arrays.asList(new User(0L, "测试用户", true));
// 若userList为空(null或size=0),返回defaultUsers;否则返回原集合
return CollUtil.defaultIfEmpty(userList, defaultUsers);
}
// 3. 集合为null时返回不可变空集合
public List<Long> getEmptySafeUserIds(List<User> userList) {
// 将null转换为不可变空集合,非null则保持原集合
List<User> safeList = CollUtil.emptyIfNull(userList);
// 提取用户ID,即使集合为空也不会引发NPE
return CollUtil.getFieldValues(safeList, "id", Long.class );
}
}
代码解析:
checkUserList方法中,isEmpty统一处理多种集合类型的判空,无需针对List、Set单独编写判空逻辑,减少代码冗余。
isNotEmpty直接替代反向判断,避免!符号导致的可读性问题,代码更直观。@Service
public class AuthService {
// 1. 集合去重(支持简单类型与自定义对象)
public List<User> distinctUsers(List<User> userList) {
// 基于元素equals去重(自定义对象需重写equals和hashCode)
List<User> simpleDistinct = CollUtil.distinct(userList);
// 按用户ID去重,重复时保留第一个元素(无需重写equals方法)
return CollUtil.distinct(userList, User::getId, false);
}
// 2. 计算两个集合的交集(获取共同元素)
public List<Long> getCommonAuthIds(List<Long> userAuths, List<Long> roleAuths) {
// 计算交集,自动处理集合判空,返回共同元素列表
// 示例:userAuths=[1,2,3,3],roleAuths=[3,4,5],结果为[3]
return CollUtil.intersection(userAuths, roleAuths);
}
// 3. 计算并集与差集
public List<Long> getUnionAndSubtract(List<Long> userAuths, List<Long> roleAuths) {
// 计算并集:保留两个集合的所有元素,重复次数取最大值
// 示例:userAuths=[1,2,3],roleAuths=[3,4,5],结果为[1,2,3,4,5]
List<Long> unionAuths = CollUtil.union(userAuths, roleAuths);
// 计算差集:获取userAuths中有但roleAuths中没有的元素
// 示例:userAuths=[1,2,3],roleAuths=[3,4,5],结果为[1,2]
List<Long> subtractAuths = CollUtil.subtract(userAuths, roleAuths);
// 按业务需求返回差集(可根据场景切换为并集)
return subtractAuths;
}
}
代码解析:
distinct方法提供两种去重方式,满足不同场景。
基于元素equals去重时,需确保自定义对象重写equals和hashCode;按指定字段(如User::getId)去重时,无需修改对象结构,直接通过字段值判断重复,灵活性更高。@Service
public class UserQueryService {
// 1. 集合转Map(key为指定字段,value为元素)
public Map<Long, User> getUserMapByIds(List<User> userList) {
// 按用户ID作为key,User对象作为value生成Map
// 注意:若ID重复,后续元素会覆盖前面元素(需确保key唯一)
return CollUtil.fieldValueMap(userList, "id");
}
// 2. 集合转Map(key重复时value为List)
public Map<Long, List<User>> getUserListMapByIds(List<User> userList) {
// 按用户ID作为key,value为相同ID的User列表,避免重复key导致的数据覆盖
return CollUtil.toListMap(userList, "id");
}
// 3. 集合转字符串(用于前端展示)
public String getUserNamesStr(List<User> userList) {
// 提取用户列表中的“name”字段值,生成姓名列表
List<String> names = CollUtil.getFieldValues(userList, "name");
// 按“,”分隔姓名,拼接为字符串(示例结果:“张三,李四”)
return CollUtil.join(names, ",");
}
// 4. 按自定义条件筛选元素
public List<User> getActiveAdultUsers(List<User> userList) {
// 筛选非空、启用且年龄>18的用户,返回新集合(原集合不变)
return CollUtil.filter(userList, user ->
user != null && user.isActive() && user.getAge() > 18
);
}
}
代码解析:
getUserMapByIds方法中,fieldValueMap无需手动循环put元素,直接通过“id”字段生成Map,后续按ID查询用户时,可通过map.get(1L)快速获取,效率从传统循环的O(n)提升至O(1)。但需注意key唯一性,避免数据覆盖。
getUserListMapByIds方法中,toListMap解决了key重复问题,将相同ID的用户存储为List,适用于一对多场景(如同一部门下的多个用户),避免传统Map因key重复导致的数据丢失。@Service
public class ProjectApplicationService {
// 1. 用户权限校验:筛选启用用户ID、去重、求交集
public List<Long> getValidUserIds(List<User> userList, List<Long> roleAuthUserIds) {
// 第一步:筛选非空且启用的用户,排除无效数据
List<User> activeUsers = CollUtil.filter(userList, u -> u != null && u.isActive());
// 第二步:提取用户ID,并基于ID去重(避免重复用户)
List<Long> activeUserIds = CollUtil.distinct(CollUtil.getFieldValues(activeUsers, "id", Long.class ));
// 第三步:求用户ID与角色权限ID的交集,得到最终有效权限ID
return CollUtil.intersection(activeUserIds, roleAuthUserIds);
}
// 2. 购物车添加商品:避免重复添加
public void addCartItem(List<CartItem> cart, CartItem item) {
// 若商品非空且不在购物车中,则添加,返回是否添加成功
boolean isAdded = CollUtil.addIfAbsent(cart, item);
if (isAdded) {
System.out.println("商品添加成功");
} else {
System.out.println("商品已在购物车中");
}
}
// 3. 商品下单次数统计
public Map<String, Integer> countProductOrders(List<String> productIds) {
// 统计每个商品ID的出现次数,生成“商品ID-下单次数”的Map
// 示例:productIds=["P001","P002","P001"],结果为{"P001":2,"P002":1}
return CollUtil.countMap(productIds);
}
// 4. 集合分页:按页码和页大小切分数据
public List<User> getUsersByPage(List<User> userList, int pageNo, int pageSize) {
// 按页码(从1开始)和页大小切分集合,自动计算起始/结束索引
// 示例:pageNo=1,pageSize=10,返回前10条数据;pageNo=2,返回11-20条
return CollUtil.page(pageNo, pageSize, userList);
}
}
代码解析:
用户权限校验场景中,通过filter、getFieldValues、distinct、intersection的组合,将传统20多行代码压缩为3行,逻辑清晰且无冗余。筛选、去重、交集运算均通过CollUtil方法实现,无需手动循环,性能更优。购物车添加商品场景中,addIfAbsent整合了“判空+contains判断+添加”的逻辑,无需手动编写if (item != null && !cart.contains(item)),代码更简洁,且避免了contains方法的重复调用。