如何递归调用findMatch?IFL流匹配方法递归及索引越界问题
修复IFL的findMatch方法及空列表异常问题
让我们一步步解决你遇到的两个核心问题:递归逻辑冗余错误和空列表导致的索引越界异常。
问题1:findMatch方法的递归逻辑冗余且错误
你的findMatch方法else块中重复调用了this.tail.get().findMatch(predicate),这会导致两个问题:
- 每次调用
tail.get()都会生成一个全新的IFL实例(因为IFL.of会基于子列表创建新对象),造成不必要的对象开销; - 两次执行递归查询,不仅效率低下,还可能引发意外行为(比如如果tail的生成存在副作用)。
问题2:空列表未处理导致IndexOutOfBoundsException
IFL.of方法没有处理空列表的终止条件,当遍历到最后一个元素的子列表(空列表)时,调用list.get(0)必然抛出IndexOutOfBoundsException。
修复后的完整代码
import java.util.function.Predicate; import java.util.Optional; import java.util.List; import java.util.NoSuchElementException; import java.util.Arrays; import java.util.function.Supplier; class IFL<T> { Supplier<T> head; Supplier<IFL<T>> tail; IFL(Supplier<T> head, Supplier<IFL<T>> tail) { this.head = head; this.tail = tail; } static <T> IFL<T> of(List<? extends T> list) { if (list.isEmpty()) { // 返回终止型空IFL,直接返回空结果避免递归 return new IFL<T>(() -> { throw new NoSuchElementException("Empty IFL"); }, () -> IFL.of(list)) { @Override Optional<T> findMatch(Predicate<? super T> predicate) { return Optional.empty(); } }; } return new IFL<T>(() -> list.get(0), () -> IFL.of(list.subList(1, list.size()))); } Optional<T> findMatch(Predicate<? super T> predicate) { T currentHead = head.get(); if (predicate.test(currentHead)) { return Optional.of(currentHead); } // 仅获取一次tail实例,避免重复创建和递归调用 IFL<T> tailList = tail.get(); return tailList.findMatch(predicate); } }
关键修复点说明
优化findMatch递归逻辑:
- 缓存当前head的值,避免重复调用
head.get(); - 只调用一次
tail.get()获取后续流实例,直接递归调用其findMatch方法,去除冗余的存在性判断和重复递归。
- 缓存当前head的值,避免重复调用
处理空列表终止条件:
- 在
IFL.of中新增空列表判断,返回一个重写了findMatch方法的特殊IFL实例,直接返回Optional.empty(),避免继续递归和调用空列表的get(0)方法。
- 在
测试验证
针对你的输入示例:
// 初始化列表 IFL<String> list = IFL.of(Arrays.asList("three", "little", "pigs")); // 查找长度为6的元素 → 返回Optional[little] list.findMatch(str -> str.length() == 6); // 查找长度小于4的元素 → 无符合条件元素,返回Optional.empty(),不再抛出异常 list.findMatch(str -> str.length() < 4);
内容的提问来源于stack exchange,提问作者zulu
相关产品推荐
相关产品推荐

