Stream过滤器:实例方法引用与静态方法引用执行结果不同
Stream过滤中实例方法与静态方法结果差异的原因分析
问题场景
原本使用Lambda表达式实现Stream过滤逻辑:
permissionsType.getGranteeCapabilities().stream() .filter(g -> g.getCapabilities() != null && g.getCapabilities().getCapability() != null)
将过滤逻辑提取为实例方法后,无论输入内容如何,过滤结果始终为false:
public boolean isPermissionWithCapabilities(Capabilities g) { return g.getCapabilities() != null && g.getCapabilities().getCapability() != null; } permissionsType.getGranteeCapabilities().stream() .filter(object::isPermissionWithCapabilities)
但将该方法改为静态方法后,过滤结果恢复正确:
public static boolean isPermissionWithCapabilities(Capabilities g) { return g.getCapabilities() != null && g.getCapabilities().getCapability() != null; } permissionsType.getGranteeCapabilities().stream() .filter(DashboardUserPermissionService::isPermissionWithCapabilities)
核心原因:实例方法引用的调用逻辑错误
问题出在你对实例方法引用的使用方式上:
- 当你写
object::isPermissionWithCapabilities时,Stream会把流中的每个Capabilities元素当作方法的调用者,而不是方法的参数。实际执行的逻辑是g.isPermissionWithCapabilities(null),而非你预期的object.isPermissionWithCapabilities(g)。 - 方法内部的
g.getCapabilities()实际上是在调用流元素自身的方法,但传入的参数是null,这直接导致判断逻辑完全偏离预期,最终始终返回false。
而静态方法引用DashboardUserPermissionService::isPermissionWithCapabilities的逻辑和最初的Lambda完全一致:Stream会把流中的每个元素作为参数传入静态方法,自然能得到正确结果。
修正方案
方案1:调整实例方法定义与引用方式
如果坚持要用实例方法,需要修改方法定义(去掉参数,直接判断当前实例属性),同时调整方法引用:
// 调整实例方法,无需接收参数 public boolean isPermissionWithCapabilities() { return this.getCapabilities() != null && this.getCapabilities().getCapability() != null; } // 此时使用类名::方法名的引用方式 permissionsType.getGranteeCapabilities().stream() .filter(Capabilities::isPermissionWithCapabilities)
方案2:保留静态方法(推荐)
静态方法的引用逻辑完全匹配你最初的Lambda表达式,无需额外调整,是最贴合你业务场景的方案。
内容的提问来源于stack exchange,提问作者PavlMits
相关产品推荐
相关产品推荐

