能否在JDK8中用单条Stream表达式实现双条件优先级查询?
优化方案:单条Stream实现优先级查询
可以用Stream.concat将两个筛选流合并,优先从id匹配的流中取结果,完美贴合你的需求,代码如下:
public Student getStudent(String id, String name) { try { List<Student> students = studentDao.getStudent(); return Stream.concat( students.stream().filter(s -> id.equals(s.getId())), students.stream().filter(s -> name.equals(s.getName())) ) .findFirst() .orElse(null); } catch (Exception ex) { return null; } }
逻辑说明
- 优先级保证:
Stream.concat会先处理第一个流(id匹配的学生),findFirst()会优先从这个流中获取元素,只有当第一个流为空时,才会去第二个流(name匹配)中查找。 - 性能等价原代码:如果存在id匹配的学生,会直接返回第一个匹配项,不会遍历第二个流;若id无匹配,才会遍历查找name匹配项,和原代码的遍历次数一致。
- 空集合处理:当
students为空时,合并后的流也为空,findFirst().orElse(null)会返回null,和原逻辑一致。 - 异常处理:保留原有的try-catch逻辑,异常时返回null。
如果你想避免两次遍历集合(极端场景下),也可以用自定义排序的方式,但排序会遍历所有符合条件的元素,性能略逊于concat方案,示例如下:
public Student getStudent(String id, String name) { try { List<Student> students = studentDao.getStudent(); return students.stream() .filter(s -> id.equals(s.getId()) || name.equals(s.getName())) .sorted((s1, s2) -> { boolean s1IdMatch = id.equals(s1.getId()); boolean s2IdMatch = id.equals(s2.getId()); // id匹配的排前面 return Boolean.compare(s2IdMatch, s1IdMatch); }) .findFirst() .orElse(null); } catch (Exception ex) { return null; } }
推荐使用第一种concat方案,更贴合原代码的执行逻辑,性能更优。
内容的提问来源于stack exchange,提问作者Rebecca
相关产品推荐
相关产品推荐

