2014-11-13 5 views
-1

Свойство SET это не позволяет дублировать элементы.Путаница относительно hashset, hashmap, hashcode, equals

, но ссылаясь на SCJP: Когда используется hashset или linkedhashset. при добавлении объектов вы должны переопределить hashcode, иначе вы можете получить дубликаты элементов в наборе.

boolean[] b=new boolean[5]; 
Set s=new HashSet(); 
b[0]=s.add("a"); 
b[1]=s.add("a"); 

здесь выход True, False Интересно, как же вывод является ложным, когда вы не переопределен в хэш-код. Но когда вы переопределяете hashcode, вы должны переопределить equals().

Интерфейс DOes Collection предоставляет метод equals() по умолчанию?

Я не могу понять,

+0

'String' переопределяет' hashCode'. – arshajii

+0

СПАСИБО TON Folks :) Я получил его –

ответ

0

Прежде всего, String имеет приоритет hashCode и equals, так что ваш код использует версию String «s из этих методов (так как вы добавляете String с до вашего HashSet).

Во-вторых, даже если это не так, в вашем примере «a» интернирован, поэтому оба вызова s.add («a») добавляют один и тот же объект, поэтому даже Object по умолчанию реализация hashCode и equals дали бы те же результаты.

+0

boolean [] b = new boolean [5]; Набор s = новый HashSet(); b [0] = s.add (новое целое число (2)); b [1] = s.add (новое целое число (2)); // Какой будет выход? –

+0

@SagarByali Integer также переопределяет hashCode и равно. – Eran

+0

boolean [] b = new boolean [5]; Установить s = новый HashSet(); б [0] = s.add (2); b [1] = s.add (2); // Какой будет выход? –

3

Вы хотите добавить два java.lang.String «S, для которых класс ВС/Oracle уже поставляются подходящие .hashCode() и .equals() методы для вас :-)

Примечание: Это не коллекции, которые нуждаются в равных и хэш-методы - это объекты, которые вы положили в них!

Если вы хотите добавить YourOwnClass объектов в коллекцию JDK, вы должны разумно переопределить оба этих метода. Рассмотрим это, где YourOwnClass возвращается к java.lang.Object «s реализаций методов в точке:

class YourOwnClass 
{ 
    String a; 
    public YourOwnClass(String a) { this.a = a; } 
} 

public void testYourOwnClass() throws Exception 
{ 
    Set<YourOwnClass> set = new HashSet<YourOwnClass>(); 

    System.out.println(set.add(new YourOwnClass("b"))); 
    System.out.println(set.add(new YourOwnClass("b"))); 
} 

Это напечатает

правда

правда

, хотя мы могли бы утверждают, что два добавленных объекта YourOwnClass, вероятно, должны считаться идентичными из семантического смотровая площадка.

Затем, измените YourOwnClass следующим образом и повторите попытку.

class YourOwnClass 
{ 
    String a; 
    public YourOwnClass(String a) { this.a = a; } 

    @Override public int hashCode() { return a.hashCode(); } 
    @Override public boolean equals(Object obj) { return a.equals(((YourOwnClass)obj).a); } 
} 

Voila - "true false" на этот раз!

Приветствия,

+0

ссылаясь на SCJP: Когда используется hashset или linkedhashset. при добавлении объектов вы должны переопределить hashcode, иначе вы можете получить дубликаты элементов в наборе. Что это значит? Можете ли вы дать объяснение об установке –

+0

Это означает, что добавляемые объекты должны иметь значимую реализацию equals() и hashCode() - эти методы должны возвращать true и одинаковое значение соответственно для объектов, которые вы считаете равными. См. Дополнения к моему ответу для примера. –

1

Обеспечивает ли интерфейс Collection() метод по умолчанию на равных?

Да по умолчанию hashCode() метод используется в equals(), который определен в классе Object сам

Для некоторых классов, таких как String в equals() чеками для знаков равенства.

Проверьте исходный код String.equals() метода


Если элемент уже добавлен в Set, то он возвращает false в противном случае возвращает true, как указано в Java Doc, а также.

+0

Я знаю, что строки, дата, календарь, обертки имеют hashcode по умолчанию и равны. Но мой вопрос: hashset и linkedhashset также попадают под одну и ту же скобку (поскольку они распространяются из коллекции) (строки, дата, календаря, обертки, хашсет, Linkedhashset). Но карта не наследуется от colection –

+0

Ваш вопрос не ясен для меня. Это зависит от объекта, который вы добавляете в коллекцию. Он использует 'equals()' и 'hashCode()' добавленного элемента. – Braj

+0

На ваш вопрос, почему переопределить 'equals()' когда 'hashCode()' переопределяется? – Braj

2

ОК .. Для начала.

Если используется hashset или linkedhashset. LinkedhashSet поддерживает порядок вставленных элементов, HashSet doesnt.

Интересно, как же вывод является ложным Метод add() возвращает истину, если элемент добавляется (если элемент не уже присутствует в set.So, в вашем случае, первый раз, " «нет в наборе», поэтому он возвращает true в первый раз. во второй раз «а» уже будет присутствовать, поэтому он вернет ложь.

Далее, по умолчанию все объекты имеют hashCode() и equals() реализации. Вы должны переопределить их, чтобы изменить поведение по умолчанию.

+1

Просто уточнение - LinkedHashSet поддерживает порядок вставки, а не естественный порядок значений. Я предполагаю, что это то, что вы имели в виду, но это может смутить некоторых. –

+0

@DonRoby - Да. Я имел в виду то же самое :) – TheLostMind

0

Первое, что нужно сначала - я полностью согласен и +1 @TheLostMind ответ выше относительно LinkedHashset. Кроме того, вам, вероятно, не хватает понимания того, что метод .add() фактически возвращает i.e, что он проверяет, прежде чем возвращать вам логический результат.

P.S. Это один из стандартов в JavaBeans, что вы должны переопределить хэш-код() и Equals(), чтобы избежать ошибочных результатов - см http://www.xyzws.com/javafaq/why-always-override-hashcode-if-overriding-equals/20

Помните, что вы используете HashSet и HashSet в equals() и hashCode() методы наследуются от AbstractSet. AbstractSet - это абстрактный класс, и HashSet расширяет его, и нет необходимости внедрять абстрактные методы. Поскольку equals() и hashCode() уже реализованы, результат, который вы видите для кода ниже, выглядит как true и false. Я разделил их с помощью области действия {} для улучшения ясности.

public static void main (String[] args) throws java.lang.Exception 
{ 

{ boolean[] b = new boolean[5]; 
    Set s = new HashSet(); 
    b[0]=s.add(new Integer(2)); 
    b[1]=s.add(new Integer(2)); 

    System.out.println("Using Hashset Integers b0 = "+b[0]+" and b1 = "+b[1]); 
} 

{ 
    boolean[] b=new boolean[5]; 
    Set s=new HashSet(); 
    b[0]=s.add(2); 
    b[1]=s.add(2); 
    System.out.println("Using Hashset int b0 = "+b[0]+" and b1 = "+b[1]); 
} 


} 

Я считаю, что для int и Integer хэш-код() и Equals() являются alrady отсортированы по Java. Тебе не нужно об этом беспокоиться. Я применил dataserver с использованием Spring Framework, где мне нужен мой собственный класс сущностей, и чтобы я мог сохранить объекты Entity bean в HashMap, мне пришлось переопределить equals() и hashCode() в моем классе определения Entity. Если вы используете Eclipse, вы можете использовать автогенератор, чтобы дать вам скелет hashCode() и equals(), который затем можно редактировать в соответствии с вашими потребностями.

+0

boolean [] b = new boolean [5]; Установить s = новый HashSet(); b [0] = s.add (новое целое число (2)); b [1] = s.add (новый Integer (2)); // Какой будет выход? и boolean [] b = new boolean [5]; Установить s = новый HashSet(); б [0] = s.add (2); b [1] = s.add (2); // Какой будет выход? –

+0

@SagarByali Это будет true false - и true false. См. Здесь - http://ideone.com/cJTlRL – ha9u63ar