2015-06-26 4 views
2

У меня есть некоторая ниша, необходимая для отключения двух объектов общих типов X и Y, и используйте это для возврата типа T. Я хочу поставить эти элементы в строго управляемый HashMap и использовать это для поиска по клавише X, Y.Hashcode и Equals для ссылки на объект?

Однако, как я могу обеспечить, X и Y являются hashcoded и равенства по сравнению с их ссылкой на память, а не любая переопределенная реализация hashCode/equals?

public final class BiReferenceCache<X,Y,T> { 
    private final HashMap<Key<X,Y>,T> cacheMap = new HashMap<>(); 

    public T get(X item1, Y item2) { 
     return cacheMap.get(new Key<X,Y>()); 
    } 

    private static final class Key<X,Y> { 
     private final X val1; 
     private final Y val2; 

     Key(X val1, Y val2) { 
      this.val1 = val1; 
      this.val2 = val2; 
     } 

     public int hashCode() { 
      //??? What do I do to hashcode by val1 and val2's memory reference? 
     } 
     public boolean equals(Object obj) { 
      //??? What do I do to check equality for val1 and val2's memory reference? 
     } 
    } 

} 
+0

Вы уверены, что хотите получить ссылку на память? Это практически противоречило бы контракту на равный метод. – Robert

ответ

4

Использование

System.identityHashCode 

и

== 
+0

Был очень уверен в '==', но этот 'System.identityHashCode' был именно тем, что я искал. – tmn

0

Вы должны использовать для хэш-код:

val1.hashCode() + val2.hashCode(); 

и равных:

val1.equals(obj.val1) && val2.equals(obj.val2); 

в основном пересылка ответственность.

PS: Если null разрешен, вы должны добавить соответствующий код.

1

Вы можете использовать ==, чтобы проверить идентичность памяти и java.lang.System#identityHashCode(Object), чтобы получить хэш-код без переопределения.

private static final class Key<X,Y> { 
    private final X val1; 
    private final Y val2; 

    Key(X val1, Y val2) { 
     this.val1 = val1; 
     this.val2 = val2; 
    } 

    public int hashCode() { 
     return 31 * System.identityHashCode(val1) + System.identityHashCode(val2); 
    } 

    public boolean equals(Object obj) { 
     if (obj == null) { 
      return false; 
     } 
     if (!obj instanceof Key) { 
      return false; 
     } 
     Key other = (Key)obj; 
     return val1 == other.val1 && val2 == other.val2; 
    } 
} 
1

Не должен ли оператор == ссылаться на равенство?

Этот вопрос может ответить на ваши Hashcode проблемы: How do you get the "object reference" of an object in java when toString() and hashCode() have been overridden? (цитируемые ниже)

Что именно вы планируете делать с ним (то, что вы хотите сделать, делает разницу с тем, что вам нужно будет позвонить)?

хэш-код(), как это определено в Javadocs говорит:

Насколько разумно практично, метод хэш-код определяется классом Object действительно возвращается различных целых чисел для различных объектов. (Это, как правило, реализуется путем преобразования внутреннего адреса объекта в целое число, но этот метод реализации не требуется языком программирования JavaTM.)

Так что, если вы используете хэш-код, чтобы узнать, если это уникальный объект в памяти, который не является хорошим способом сделать это.

System.identityHashCode выполняет следующие действия:

Возвращает тот же хэш-код для данного объекта, как будет возвращен методом по умолчанию хэш-код (в), перекрывает ли или нет класс данного объекта хэш-код(). Хэш-код для нулевой ссылки равен нулю.

Который, за то, что вы делаете, звучит так, как вы хотите ... но то, что вы хотите сделать, может быть небезопасным в зависимости от того, как реализована библиотека.

0

Для hashCode() вы можете просто использовать: val1.hashCode()^val2hashCode(); (по порядку XOR-оператора ^) - не большое решение, но делает то, что должно.

В equals() вы должны сначала проверить, имеют ли оба объекта одинаковые ссылки (с ==), а затем проверьте, что объекты, которые вы сравниваете, не равны нулю. После этого убедитесь, что оба объекта являются экземплярами одного и того же типа. И последний шаг: проверьте, равны ли значения атрибутов обоих.

В случае, если у вас есть суперкласс, это будет считаться хорошим стилем для решения первых трех шагов в суперклассе.

Смежные вопросы