简体   繁体   English

Java覆盖等于和hashCode建议

[英]Java Overriding equals and hashCode advice

I have a thought on attempting to override equals/hashCode on a slew of objects I am creating and developing an interface/utility class for doing this using Java 1.7. 我有一个尝试覆盖我正在创建和开发的接口/实用程序类以使用Java 1.7来实现的对象上的equals / hashCode的想法。 Since I am unsure of how this approach will perform I would appreciate any feedback. 由于我不确定这种方法的执行方式,因此,我希望能得到任何反馈。 My primary concern is using autoboxing with primitive types and what kind of performance hits I will take. 我主要关心的是将自动装箱与原始类型一起使用以及对性能产生什么样的影响。

Interface: 接口:

public interface Hashable {

/**
 * Return the base offset for the {@link Object#hashCode()}, this number
 * should be unique and odd;
 * 
 * @return int
 */
public int getBaseOffset();

/**
 * Return the base offset for the class fields{@link Object#hashCode()},
 * this number should be unique and odd;
 * 
 * @return int
 */
public int getFieldOffset();

/**
 * Return an {@link Object} array of the fields to use for
 * {@link Object#equals(Object)} and {@link Object#hashCode()}
 * 
 * @return {@link Object} array
 */
public Object[] getHashFields();
}

Utility Class: 实用程序类别:

public class HashUtil {

    /**
     * This method will create a hash code based on the
     * {@link Hashable#getHashFields()}. If the object is immutable this method
     * only needs to be called once through lazy initialization, otherwise the
     * class can call out to it through the {@link Object#hashCode()} override.
     * <p>
     * <b>Example:</b>
     * 
     * <pre>
     * public int hashCode() {
     *     return HashUtil.createHash(this);
     * }
     * <p>
     * @param hashable
     *            {@link Object} implementing {@link Hashable} interface
     * @return int
     * to use for hash code
     */
    public static int createHash(Hashable hashable) {
        HashCodeBuilder builder = new HashCodeBuilder(hashable.getBaseOffset(), hashable.getFieldOffset());

        for (Object o : hashable.getHashFields()) {
            if (o != null) {
            builder.append(o);
            }
        }
        return builder.toHashCode();
    }

    /**
     * Evaluates whether two {@link Hashable} objects are equal. This method is
     * intended for use when overriding {@link Object#equals(Object)}.
     * <p>
     * <b>Example:</b>
     * 
     * <pre>
     * public boolean equals(Object o) {
     *     return HashUtil.equals(this, o);
     * }
     * <p>
     * @param h1 first {@link Hashable} to compare
     * @param h2 second {@link Hashable} to compare
     * @return true if they are equal
     */
    public static boolean equals(Hashable h1, Hashable h2) {
        if (h1.getHashFields() == null || h2.getHashFields() == null) {
            if (!(h1.getHashFields() == null && h2.getHashFields() == null)) {
            return false;
            }
            return true;
        }
        if (h1.getHashFields().length != h2.getHashFields().length) {
            return false;
        }
        EqualsBuilder builder = new EqualsBuilder();
        for (int x = 0; x < h1.getHashFields().length; x++) {
            Object o1 = h1.getHashFields()[x];
            Object o2 = h2.getHashFields()[x];
            builder.append(o1, o2);
        }
        return builder.isEquals();
    }
}

Trust me. 相信我。 Dont write you own hashing/equals logic. 不要写自己的哈希/等于逻辑。

Use already available and tested code like Apache EqualsBuilder and HashCodeBuilder 使用已经可用且经过测试的代码,例如Apache EqualsBuilderHashCodeBuilder

Eg: 例如:

public int hashCode() {
     // you pick a hard-coded, randomly chosen, non-zero, odd number
     // ideally different for each class
     return new HashCodeBuilder(17, 37).
       append(name).
       append(age).
       toHashCode();
   }


public boolean equals(Object obj) {
   // do you basic object check first
   // then delegate to equalsbuilder
   MyClass rhs = (MyClass) obj;
   return new EqualsBuilder()
                 .append(name, rhs.name)
                 .append(age, rhs.age)
                 .isEquals();
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM