Java Stream多过滤阶段如何按失败原因抛出不同自定义异常
解决方案
完全可以在单个Stream流中完成该逻辑,这里提供两种常用实现方案:
方案1:基于collectingAndThen实现(写法简洁)
利用Collectors.collectingAndThen在首次过滤完成后直接校验是否存在符合年龄要求的人员,不需要额外声明外部变量:
Person firstOlderThan18AndWithPet = people.values().stream() .filter(person -> person.getAge() >= 18) .collect(Collectors.collectingAndThen(Collectors.toList(), adultList -> { if (adultList.isEmpty()) { throw new AgeException(); } return adultList.stream(); })) .filter(Person::hasPet) .findFirst() .orElseThrow(NoPetException::new);
- 优缺点:写法简洁易读,缺点是需要收集所有符合年龄要求的人员,如果符合年龄要求的人员量级极大,会有额外的内存开销,适合中小数据量场景。
方案2:基于标记变量实现(性能更高)
通过原子布尔变量标记是否存在符合年龄要求的人员,依托Stream短路求值特性,找到第一个符合要求的对象就停止遍历,适合大数据量场景:
AtomicBoolean existAdult = new AtomicBoolean(false); Person firstOlderThan18AndWithPet = people.values().stream() .peek(person -> { if (person.getAge() >= 18) { existAdult.set(true); } }) .filter(person -> person.getAge() >= 18 && person.hasPet()) .findFirst() .orElseThrow(() -> existAdult.get() ? new NoPetException() : new AgeException());
- 优缺点:性能更高,不需要全量收集符合年龄要求的人员,仅需要额外声明一个标记变量,适合绝大多数生产场景。
内容的提问来源于stack exchange,提问作者TiMESPLiNTER
相关产品推荐
相关产品推荐

