簡體   English   中英

Java覆蓋等於和hashCode建議

[英]Java Overriding equals and hashCode advice

我有一個嘗試覆蓋我正在創建和開發的接口/實用程序類以使用Java 1.7來實現的對象上的equals / hashCode的想法。 由於我不確定這種方法的執行方式,因此,我希望能得到任何反饋。 我主要關心的是將自動裝箱與原始類型一起使用以及對性能產生什么樣的影響。

接口:

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();
}

實用程序類別:

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();
    }
}

相信我。 不要寫自己的哈希/等於邏輯。

使用已經可用且經過測試的代碼,例如Apache EqualsBuilderHashCodeBuilder

例如:

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