如何使用Java 8 Stream优化集合同时匹配两个条件的校验代码
解法1:全量遍历收集状态(兼容串行/并行流)
仅遍历一次集合,通过collect累积两个角色的存在标记:
// 下标0对应ROLE_OLD存在标记,下标1对应ROLE_NEW存在标记 boolean[] roleFlags = listOfRelations.stream() .collect( () -> new boolean[2], (flags, relation) -> { String role = relation.getRole(); if (Constants.ROLE_OLD.equalsIgnoreCase(role)) flags[0] = true; if (Constants.ROLE_NEW.equalsIgnoreCase(role)) flags[1] = true; }, (flags1, flags2) -> { flags1[0] |= flags2[0]; flags1[1] |= flags2[1]; } ); if (roleFlags[0] && roleFlags[1]) { System.out.println("Success"); } else { throw new RuntimeException("缺少对应角色权限"); }
解法2:提前短路终止遍历(性能最优)
利用anyMatch的短路特性,只要两个角色都找到就立刻终止遍历,不需要遍历完所有元素,适合大集合场景:
import java.util.concurrent.atomic.AtomicBoolean; // ... AtomicBoolean hasOldRole = new AtomicBoolean(false); AtomicBoolean hasNewRole = new AtomicBoolean(false); boolean hasBothRoles = listOfRelations.stream() .peek(relation -> { String role = relation.getRole(); if (Constants.ROLE_OLD.equalsIgnoreCase(role)) hasOldRole.set(true); if (Constants.ROLE_NEW.equalsIgnoreCase(role)) hasNewRole.set(true); }) .anyMatch(relation -> hasOldRole.get() && hasNewRole.get()); if (hasBothRoles) { System.out.println("Success"); } else { throw new RuntimeException("缺少对应角色权限"); }
两种方案都只遍历一次集合,性能远高于两次调用anyMatch的写法。
内容的提问来源于stack exchange,提问作者Rohit
相关产品推荐
相关产品推荐

