2013-06-27 1 views
0

Ниже приведен фрагмент кода, который я пробовал; вывод также дан.Как сравнение значений выполняется в HashSet, HashMap и т. Д.

Мой вопрос: я устанавливаю то же значение типа String в сеттер HistoryTeardownDetails для обоих объектов htd1 и htd2, так что только один из объектов должны быть разрешены в HashSet (как и в случае реализации String) ,

Может ли кто-нибудь помочь мне в том, как дубликаты устраняются в Hashset или любой коллекции, используя концепцию хэш-кодов?

public class HashSetTry { 
public static void main(String[]args){ 
HistoryTeardownDetails htd1=new HistoryTeardownDetails(); 
htd1.setProcess("ashwin"); 
HistoryTeardownDetails htd2=new HistoryTeardownDetails(); 
htd2.setProcess("ashwin"); 

HashSet<HistoryTeardownDetails> hashSet1=new HashSet<HistoryTeardownDetails>(); 
System.out.println("First --> "+hashSet1); 

hashSet1.add(htd1); 


System.out.println("Second --> "+hashSet1); 

hashSet1.add(htd2); 

System.out.println("Third --> "+hashSet1); 

HashSet<String> hashSet2=new HashSet<String>(); 

System.out.println("First --> "+hashSet2); 

hashSet2.add("abc"); 


System.out.println("Second --> "+hashSet2); 

hashSet2.add("abc"); 

System.out.println("Third --> "+hashSet2); 

HashSet<String> hashSet3=new HashSet<String>(); 

String abc=new String("sakthi"); 

System.out.println("First --> "+hashSet3); 

hashSet3.add(abc); 

String abcd=new String("sakthi"); 

System.out.println("Second --> "+hashSet3); 

hashSet3.add(abcd); 

System.out.println("Third --> "+hashSet3); 

} 
} 

Выход:

First --> [] 
Second --> [[email protected]] 
Third --> [[email protected], [email protected]] 

First --> [] 
Second --> [abc] 
Third --> [abc] 

First --> [] 
Second --> [sakthi] 
Third --> [sakthi] 

ответ

2

Дубликаты определяются методом equals объектов.

Вам необходимо переопределить методы equals и hashCode в вашем классе HistoryTeardownDetails.

0

Я думаю, что в равенстве HashMaps определяется то же хэш-значение метода hashCode() в Object.

Рекомендуется, если вы обеспечиваете реализацию равным образом, чтобы всегда обеспечивать реализацию hashCode, чтобы получить правильное поведение java.util.collection.

1

HashSet.add на самом деле использует метод put внутри HashMap. Так позволяет увидеть исходный код HashMap.put

386  public V put(K key, V value) { 
387   if (key == null) 
388    return putForNullKey(value); 
389   int hash = hash(key.hashCode()); 
390   int i = indexFor(hash, table.length); 
391   for (Entry<K,V> e = table[i]; e != null; e = e.next) { 
392    Object k; 
393    if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { 
394     V oldValue = e.value; 
395     e.value = value; 
396     e.recordAccess(this); 
397     return oldValue; 
398    } 
399   } 
400 
401   modCount++; 
402   addEntry(hash, key, value, i); 
403   return null; 
404  } 

Здесь в строке 393, что если хэш нового ключа равно любой член хеш, то он проверяет, является ли ключ же ссылка и проверить равенство, используя метод Equals. Если он существует, он возвращается без добавления

+0

-1 для перехода к коду вместо документации. Документация является гарантией и должна быть предпочтительнее кода, который представляет собой лишь одну реализацию. – raptortech97

+0

@ raptortech97 ... интересный downvote ..хотя я думал, что показанный код будет более ясно иллюстрировать его – stinepike

+1

+1 для кода вместо документации –

3
  • HashSets хранит уникальные элементы. одно простое правило

Если вы добавляете равный объект к хешсету, то предыдущий будет заменен новым.

Для последних двух случаев вы используете строки, для которых уже реализованы метод equals и hashcode.

Вам необходимо предоставить equals и hashcode для вашего собственного класса, а затем добавить в hashset. Тогда только это даст желаемый результат

  • Если два объекта считаются equal, то их hashcodes MUST быть равна

Я бы рекомендовал использовать затмение сгенерированные equals и hashcode методы ваши собственные классы.