Java Stream中checkMethod作为filter参数的执行流程疑问
解惑:为什么checkMethod只调用一次?
不是整个列表一次性传入checkMethod,这是Java流API和lambda闭包的正常工作逻辑,拆解说明:
1. checkMethod的核心作用:生成带状态的Predicate
当你写filter(checkMethod(Person::getName))时,checkMethod(Person::getName)会先执行一次,它的任务不是处理元素,而是创建并返回一个Predicate实例:
- 内部初始化了一个
ConcurrentHashMap.newKeySet()集合(用来记录已经出现过的姓名) - 返回的lambda表达式
t -> seen.add(keyExtractor.apply(t)),才是真正用来过滤元素的逻辑
2. filter操作复用同一个Predicate处理每个元素
流的filter方法拿到这个Predicate实例后,会对流中的每个元素单独执行Predicate的test方法(也就是上面的lambda):
- 每次执行时,先通过
keyExtractor.apply(t)获取当前Person的姓名 - 调用
seen.add(...):如果姓名未在集合中,add返回true,元素被保留;如果已存在,返回false,元素被过滤 - 所有元素共享同一个
seen集合——因为它是在checkMethod创建Predicate时初始化的,属于这个Predicate的闭包状态,会被所有元素的过滤逻辑复用
举个对应你代码的例子
你的列表里有test1和test2两个Person:
- 处理第一个元素
test1:seen为空,add返回true,计入统计 - 处理第二个元素
test2:seen中只有test1,add返回true,计入统计 - 最终输出count为2
如果列表里新增一个new Person("test1"),处理第三个元素时add会返回false,不会被计入统计,最终count仍是2。
内容的提问来源于stack exchange,提问作者Lolly
相关产品推荐
相关产品推荐

