Ми всі знаємо, що якщо equals
метод повертає true
, тоді два об’єкти рівні.
Хто-небудь може навести приклад, коли 2 об’єкти мають однакові hash
значення, але вони насправді різні?
Відповіді:
1 для відповіді № 1Я припускаю, що ви знайомі з контрактом (контрактами), пов’язаним із заміною equals()
і hashCode()
та наслідки схильності до зіткненьреалізація hashCode. Враховуючи це, у наступному тривіальному прикладі використовується об’єкт, який містить два цілих числа і реалізує дуже простий hashCode, і демонструє, як легко мати два об’єкти, які не рівні, але мають однаковий hashCode. Забезпечення більш досконалого алгоритму hashCode може полегшити це.
Результатом запуску main є:
hashCodes: ih1: 6, ih2: 6
equals: false
Приклад коду:
package example.stackoverflow;
public class IntHolder
{
private Integer primaryData;
private Integer secondaryData;
public IntHolder(Integer primaryData, Integer secondaryData)
{
this.primaryData = primaryData;
this.secondaryData = secondaryData;
}
@Override
public int hashCode()
{
return ((primaryData == null) ? 0 : primaryData.hashCode()) +
((secondaryData == null) ? 0 : secondaryData.hashCode());
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
IntHolder other = (IntHolder) obj;
if (primaryData == null)
{
if (other.primaryData != null)
return false;
}
else if (!primaryData.equals(other.primaryData))
return false;
if (secondaryData == null)
{
if (other.secondaryData != null)
return false;
}
else if (!secondaryData.equals(other.secondaryData))
return false;
return true;
}
public static void main(String[] args)
{
IntHolder ih1 = new IntHolder(1, 5);
IntHolder ih2 = new IntHolder(3, 3);
System.out.println("hashCodes: ih1: " + ih1.hashCode() + ", ih2: " + ih2.hashCode());
System.out.println("equals: " + ih1.equals(ih2));
}
}
Для довідки, автоматично згенерований hashCode () Eclipse для класу IntHolder:
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result
+ ((primaryData == null) ? 0 : primaryData.hashCode());
result = prime * result
+ ((secondaryData == null) ? 0 : secondaryData.hashCode());
return result;
}
1 для відповіді № 2
String str1="abcdef";
String str2="abcdfG";
Вони обидва мають однаковий хеш-код, а метод equals повертає false.
0 для відповіді № 3
public class Employee {
protected long employeeId;
public boolean equals(Object o){
if(o == null) return false;
if(!(o instanceof) Employee) return false;
Employee other = (Employee) o;
return this.employeeId == other.employeeId;
}
public int hashCode(){
return (int) this.employeeId;
}
}
У цьому прикладі ми замінили метод equals - два співробітники рівні, коли вони матимуть однаковий ідентифікатор працівника.
Якщо два об’єкти Employee рівні, вони також матимуть однаковий хеш-код.
Ваші відповіді -
У цьому прикладі ми також реалізували хешкод - хеш-код - це ідентифікатор працівника, який округлюється до значення int. Це означає, що багато ідентифікаторів співробітників можуть призвести до одного і того ж хеш-коду, але ці об'єкти Employee все одно не будуть рівними, оскільки вони не мають однакового ідентифікатора працівника.