当前位置:  开发笔记 > 编程语言 > 正文

可重用的equals和hashCode实现

如何解决《可重用的equals和hashCode实现》经验,为你挑选了1个好方法。

我正在开发一个项目,其中许多类需要适当的典型实现equalshashCode:每个类都有一组在构造时初始化的最终字段,其中包含"深度"不可变对象(null在某些情况下可以接受s)以用于散列和比较.

为了减少样板代码的数量,我考虑编写一个抽象类,提供这种行为的常见实现.

public abstract class AbstractHashable {

    /** List of fields used for comparison. */
    private final Object[] fields;

    /** Precomputed hash. */
    private final int hash;

    /**
     * Constructor to be invoked by subclasses.
     * @param fields list of fields used for comparison between objects of this
     * class, they must be in constant number for each class
     */
    protected AbstractHashable(Object... fields) {
        this.fields = fields;
        hash = 31 * getClass().hashCode() + Objects.hash(fields);
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (obj == null || !getClass().equals(obj.getClass())) {
            return false;
        }
        AbstractHashable other = (AbstractHashable) obj;
        if (fields.length != other.fields.length) {
            throw new UnsupportedOperationException(
                    "objects of same class must have the same number of fields");
        }
        for (int i=0; i

这打算像这样使用:

public class SomeObject extends AbstractHashable {

    // both Foo and Bar have no mutable state
    private final Foo foo;
    private final Bar bar;

    public SomeObject(Foo foo, Bar bar) {
        super(foo, bar);
        this.foo = Objects.requireNonNull(foo);
        this.bar = bar; // null supported
    }

    // other methods, no equals or hashCode needed

}

这基本上是这里提出的一些差异.

在我看来,这是一种简单而又好的方法,可以减少冗长,并且仍然可以有效地实现equalshashCode.但是,由于我不记得曾经见过类似的东西(除了上面连接的答案),我想具体问一下,在申请之前是否有一些观点反对这种方法(或者可能会有一些改进)它贯穿整个项目.



1> CKing..:

我已经看到这种方法存在两个问题:

    当且仅当所有字段匹配时,两个对象才被视为相等.在现实世界中并非总是如此.

    通过使你的类extendAbstractHashable,你再也不能extend从任何其他类.这是重复使用equals和支付的相当高的代价hashCode.

第一个问题可以通过向您的AbstractHashable类传递更多元数据来解决,该数据允许它识别哪些字段是可选的.例如,您可以将另一个数组传递给AbstractHashTable包含索引位置的数组,以便通过setter将其作为元素忽略.第二个问题可以通过使用Composition来解决.而不是扩展AbstractHashTable,重构它,以便它可以与其用户建立HAS-A关系而不是IS-A关系.

但是,我不记得曾经见过类似的东西(除了上面的答案),我想具体问一下是否有一些反对这种方法的观点

这种方法肯定会影响代码的可读性方面.如果你能提出一种更具可读性的方法(比如使用注释),我认为没有任何错误需要重用equalshashCode实现.

总而言之,像eclipse这样的现代IDE很容易为你生成equalshashCode实现,所以真的需要提出这种解决方案吗?我相信.

推荐阅读
跟我搞对象吧
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有