Java中能否用Lambda实现equals()与hashCode()?和普通方法有何区别
结论
用Lambda实现的版本无法替代原生重写的equals、hashCode方法,完全不可行。
核心原因
Java中equals和hashCode是java.lang.Object类定义的实例方法,所有Java集合、通用工具逻辑依赖的都是这两个方法的重写实现,而你用Lambda写的版本本质是和原生方法同名的成员变量,和重写没有任何关系:
- 调用逻辑不兼容:你直接调用
bookA.equals(bookB)时,执行的仍然是Object类默认的地址比对逻辑,不会触发你写的Lambda代码,你必须手动写bookA.equals.apply(bookB)才能执行你写的逻辑,和原生方法调用完全不兼容。 - 标准库不识别:HashMap、HashSet、List.contains()等依赖equals、hashCode的逻辑,只会调用Object类定义的equals、hashCode方法,根本不会读取你自定义的同名成员变量,用了Lambda实现的类放到这些集合里会出现大量逻辑错误,比如属性完全相同的两个对象会被判定为不同元素。
- 额外内存开销:普通重写的方法属于类的元数据,所有实例共享一份逻辑;而Lambda实现的版本每个类实例都会持有
Function、Supplier两个额外对象,内存开销远高于普通方法实现。
两种实现的核心区别
- 本质属性不同:普通实现是类的方法成员,属于对父类方法的重写;Lambda实现是类的实例成员变量,类型为函数式接口,和父类的equals/hashCode方法无关联
- 调用方式不同:普通方法调用格式为
obj.equals(anotherObj)、obj.hashCode();Lambda实现的调用格式为obj.equals.apply(anotherObj)、obj.hashCode.get() - 适用场景不同:普通实现可以被所有Java生态的框架、工具正确识别调用;Lambda实现只适合你自己手动调用的自定义场景,无法适配通用逻辑
替代方案
如果想减少equals、hashCode的模板代码,可以选择以下更成熟的方案:
- Java 16及以上版本使用
record类,自动生成符合规范的equals、hashCode、toString方法 - 使用Lombok的
@EqualsAndHashCode注解,编译时自动生成对应方法 - 使用Apache Commons、Guava等工具库提供的EqualsBuilder、HashCodeBuilder工具类简化手写逻辑
内容的提问来源于stack exchange,提问作者createdbyjurand
相关产品推荐
相关产品推荐

