2016-06-24 3 views
0
HashSet hs = new HashSet(); 

    hs.add(10); 
    hs.add("sum"); 
    hs.add(10); 
    hs.add(12.3d); 

    System.out.println(hs); 

1) В приведенном выше коде, как это делает Java знать, что при прохождении второй объект, он должен не проверить его с первым. И как он знает, что, когда передается третий объект (т. Е. 10), ему нужно вызвать метод переопределенных .equals класса Integer для проверки первого и третьего объектов.Фоновая работа метода Object.equals в коллекции?

2) Если он вызывает метод .equals класса объекта, то оба целых числа имеют разные экземпляры, поэтому оба должны быть добавлены, но это не так.

Мне нужен фоновый рабочий метод .equals в коллекции!

+1

Не используйте необработанные типы HashSet

ответ

0

equals не принимает во внимание обстоятельства при учете при любых обстоятельствах. В основном это настраиваемая реализация, которая зависит от типа объекта и по умолчанию просто сравнивает ссылки. Вы можете себе представить, как Integer::equals

boolean equals(Object other) { 
    boolean isSameType = other instanceof Integer; 
    return isSameType && ((Integer)other).value == value; 
} 

Так два Integer экземпляров с одинаковым значением будет считаться равными. Кроме того, вы имеете дело с HashSet<T>, поэтому вы должны принять во внимание int hashCode(), что должно соответствовать реализации equals.

0

Ваш HashSet не является параметрическим с общим, поэтому вы правы, думая, что он будет рассматриваться как HashSet<Object>.

Однако, когда сравнение между элементом для добавления и нынешние элементы множества сделаны, типа объектногоequals и hashCode методы приняты во внимание. Таким образом, добавив 10 и 10, он будет использовать Integer.equals для определения равенства во время выполнения. только

HashSet<Object> сделок с ссылочного типаObject, а это означает, что требования компилятора, что все объекты в HashSet являются экземпляром или расширить Object (которые все объекты, конечно). Однако это не имеет никакого отношения к выполнению методов, поведение которых определяется фактическим объектом.

Суммарно, если я определяю:

Object obj = new Integer(10); 

И я призываю:

obj.equals(anotherObj); 

компилятор гарантирует, что ссылочного типа (Object) имеет метод equals, и во время выполнения выполняется поведение объекта типа (Integer).

0

уникальность в наборе, внутренне в java через HashMap. Всякий раз, когда вы создаете объект HashSet, он создает объект HashMap. Как известно, в HashMap каждый ключ уникален. Если ключ не равен нулю, он будет вызывать хэш-функцию на ключевом объекте, то есть key.hashCode(), поэтому после ключа.hashCode() возвращает hashValue, он выглядит как: int hash = hash (hashValue), и теперь он применяет возвращенный hashValue в свою собственную функцию хэширования. final hashvalue используется для нахождения местоположения ковша, на котором хранится объект Entry. Объект входа хранится в таком ведре (хэш, ключ, значение, bucketindex). Поэтому мы переходим через связанный список, , сравнивая ключи в каждой записи с помощью keys.equals(), пока не вернем true. Затем возвращается соответствующее значение объекта ввода, т. Е. Если значение хэша двух объектов одинаково, метод equals будет вызываться для проверки того, является ли он одинаковым или нет. Если нет, то объект найдет это место в ведре (список ссылок).

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