Подтвердить что ты не робот

Будет ли метод Java HashSet <String> contains() проверять равенство строк или идентификатора объекта?

Скажем, у меня есть этот код в Java:

HashSet<String> wordSet = new HashSet<String>();
String a = "hello";
String b = "hello";
wordSet.add(a);

Будет ли wordSet.contains(b); возвращать true или false? Насколько я понимаю, a и b относятся к разным объектам, даже если их значения одинаковы. Поэтому contains() должен возвращать false. Однако, когда я запускаю этот код, он возвращает true. Будет ли он всегда возвращать true независимо от того, где объект String b исходит из тех пор, пока b содержит значение "hello"? Я всегда это гарантировал? Если нет, когда я не гарантирую это? И что, если бы я хотел сделать что-то подобное с объектами, отличными от строк?

4b9b3361

Ответ 1

Он использует equals() для сравнения данных. Ниже приведена javadoc для Set

добавляет указанный элемент e к этому набору, если набор не содержит элемент e2 такой, что (e == null? e2 == null: e.equals(e2)).

Метод equals() для String делает символ по сравнению с символом. Из javadoc для строки

Результат верен тогда и только тогда, когда аргумент не является нулевым и является объектом String, который представляет ту же последовательность символов, что и этот объект

Ответ 2

На самом деле, HashSet делает ни.

В его реализации используется HashMap, и здесь соответствующий код, определяющий, установлен ли набор contains() (фактически он внутри метода HashMap getEntry()):

if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k))))

где:

  • требует, чтобы хеши были равны, и
  • требует либо равенства объекта, либо equals() возвращает true

Ответ "да": wordSet.contains(b) всегда будет возвращать true

Ответ 3

Собственно, и a, и b относятся к одному и тому же объекту, потому что строковые литералы в Java автоматически интернированы.

Ответ 4

Две вещи:

  • Набор был бы бесполезным, если только он не назвал метод equals() для определения равенства. wordset.contains(b) вернет true, поскольку a.equals(b) == true.

  • Вы не можете быть абсолютно уверены, что a и b указывают на разные объекты. Оформить заказ String.intern() для более подробной информации.

Ответ 5

В конечном счете contains будет проверять метод equals, а не проверяет его идентификатор объекта для метода contains. Следовательно, метод equals вызывается для вызова contains. Это структура вызова метода contains.

private transient HashMap<E,Object> map;
    public boolean contains(Object o) {
    return map.containsKey(o);
    }


    public boolean containsKey(Object key) {
        return getEntry(key) != null;
    }


    final Entry<K,V> getEntry(Object key) {
        int hash = (key == null) ? 0 : hash(key.hashCode());
        for (Entry<K,V> e = table[indexFor(hash, table.length)];
             e != null;
             e = e.next) {
            Object k;
            if (e.hash == hash &&
                ((k = e.key) == key || (key != null && key.equals(k))))
                return e;
        }
        return null;
    }

Ответ 6

Равенство. В вашем примере contains() возвращает true, потому что HashSet проверяет a.equals( b ).