Різниця між HashSet і HashMap?


168

Крім того, що HashSetне дозволяє повторювати значення, у чому різниця між HashMapі HashSet?

Я маю на увазі мудре виконання? Це трохи розпливчасто, оскільки обидва використовують хеш-таблиці для зберігання значень.


HashSet реалізований за допомогою HashMap
therealprashant

Я думаю , знаючи , чому HashSet відрізняється від ArrayList допоможе вам зрозуміти відповідь на свій попередній питання: stackoverflow.com/questions/18706870 / ...
djangofan

Відповіді:


150

Вони абсолютно різні конструкції. A HashMap- це реалізація Map. Карта відображає ключі на значення. Ключовий пошук відбувається за допомогою хеша.

З іншого боку, a HashSet- це реалізація Set. Набір призначений для відповідності математичної моделі набору. A HashSetвикористовує a, HashMapщоб підтримати його реалізацію, як ви зазначили. Однак він реалізує зовсім інший інтерфейс.

Коли ви шукаєте, що буде найкраще Collectionдля ваших цілей, цей Підручник є хорошим початковим місцем. Якщо ви справді хочете знати, що відбувається, для цього теж є книга .


Це твердження трохи спрощене. Під обкладинками відбувається ще щось, "" Повертає хеш-значення для вказаного об'єкта. Окрім власного хеш-коду об'єкта, у цьому методі застосовується "додаткова хеш-функція", яка захищає від хеш-функцій низької якості. Це дуже важливо , тому що HashMap використовує потужності двох довжини хеш - таблиць «. Weblogs.java.net/blog/2005/06/18/hashmap-implementation - однак, якщо ви подивитеся на документ , ви побачите , що цей хеш розподіляє речі над "відрами", тож, врешті-решт, я вважаю, що дві речі зможуть відобразити одне відро.
justkt

1
Щоб відповісти на ваше друге запитання - ні. Карта - це якщо ви хочете (ключ -> значення), як визначено відмінною відповіддю @Bruno Rothgiesser. Набір призначений для не повторюваних елементів. Якщо ви хочете дублікати, а не значення key->, я перевірю реалізацію java.util.List. Ознайомтеся з підручником з колекції для остаточного керівництва: java.sun.com/docs/books/tutorial/collections/index.html
justkt

@justk: так, ви можете отримати два ключі в одному відрі, а потім для їх розрізнення використовується рівняння (). Ось чому важливо, щоб hashCode () та equals () були сумісні.
Майкл Боргвардт

6
@SpikETidE: ні HashMap, ні HashSet не дозволяють копії. У цьому вся суть.
Майкл Боргвардт

23
@SpikETidE: у наборі немає пар ключів / значень, а лише елементи. І HashSet реалізований, маючи HashMap із встановленими елементами як ключами та значенням, яке ігнорується.
Майкл Боргвардт

300

HashSet - це набір , наприклад {1,2,3,4,5}

HashMap - це ключове значення -> значення (ключ до значення), наприклад {a -> 1, b -> 2, c -> 2, d -> 1}

Зауважте в моєму прикладі вище, що в HashMap не повинно бути дублікатів ключів, але вони можуть мати повторювані значення.

У HashSet не повинно бути жодних повторюваних елементів.


Але (найцікавіша) причина плутанини в тому, що навіть у HashSet вам потрібен «ключ» для доступу до елементів. Тобто об’єкти, навіть у математиці, мають назви (або адреси), якщо до них можна отримати доступ чи посилання. Тож у цьому реальному сенсі HashSet - це особливо простий HashMap, набраний іменами (або адресами) його елементів.
Ендрю Маршалл

65

HashSet

  1. Клас HashSet реалізує інтерфейс Set
  2. У HashSet ми зберігаємо об’єкти (елементи чи значення), наприклад, якщо у нас є HashSet рядкових елементів, то він може зображати набір елементів HashSet: {"Hello", "Hi", "Bye", "Run"}
  3. HashSet не дозволяє повторювати елементи, що означає, що ви не можете зберігати повторювані значення в HashSet.
  4. HashSet дозволяє мати єдине нульове значення.
  5. HashSet не синхронізований, що означає, що вони не підходять для безпечних потокових операцій, поки тільки вони не будуть синхронізовані явно. [Подібність]

                          add      contains next     notes
    HashSet               O(1)     O(1)     O(h/n)   h is the table 

HashMap

  1. Клас HashMap реалізує інтерфейс Map
  2. HashMap використовується для зберігання пар ключів і значень. Коротше кажучи, він підтримує відображення ключа та значення (клас HashMap приблизно еквівалентний Hashtable, за винятком того, що він не синхронізований і дозволяє нульові знаки.) Ось як ви могли представити елементи HashMap, якщо він має цілий ключ та значення типу String: наприклад {1 -> "Привіт", 2 -> "Привіт", 3 -> "До побачення", 4 -> "Виконати"}
  3. HashMap не дозволяє повторювати ключі, однак дозволяє повторювати значення.
  4. HashMap дозволяє отримати один нульовий ключ і будь-яку кількість нульових значень.
  5. HashMap не синхронізований, що означає, що вони не підходять для безпечних потокових операцій до тих пір, поки не будуть синхронізовані явно. [Подібність]

                           get      containsKey next     Notes
     HashMap               O(1)     O(1)        O(h/n)   h is the table 

Будь ласка, зверніться до цієї статті, щоб знайти більше інформації.


36

Це справді прикро, що обидва їх імені починаються з Hash . Це найменш важлива їх частина. Важливі частини приходять після хешу - набір і карта , як вказували інші. Відповідно, вони є набором - не упорядкованою колекцією - і картою - колекцією з ключами доступу. Вони, як правило, реалізуються з хешами - саме звідси беруться імена - але їхня суть прихована за цією частиною їхніх імен.

Не плутайте їхні імена; вони глибоко різні речі.


@HiteshSahu Обидва вони реалізовані за допомогою хеш-таблиць ( en.wikipedia.org/wiki/Hash_table ). Це хороша структура даних для представлення набору, ефективного правильних способів, і, по суті, ключі HashMap реалізовані як HashSet. Тому той, хто назвав їх, пішов на певні труднощі з їх реалізацією і був зосереджений на реалізації, а не на їх меті (на здогадку).
Карл Манастер

1
Добре пояснено. Дякую.
користувач3932000

5

У HashsetВнутрішньо знаряддя HashMap. Якщо ви бачите внутрішню реалізацію, значення, вставлені в HashSet, зберігаються як ключі в HashMap, а значення є об'єктом Dummy класу Object.
Різниця між HashMap і HashSet становить:

  1. HashMap містить пари ключових значень, і до кожного значення можна отримати доступ за ключем, оскільки, як HashSet потрібно повторювати кожен раз, оскільки немає методу отримання.
  2. HashMapреалізує інтерфейс Map і дозволяє одне нульове значення як ключ, а кілька нульових значень як значень. Де HashSetреалізується Інтерфейс встановлення, дозволяє лише одне нульове значення і не дублюється значення. (Зберегти один нульовий ключ дозволений у ключі HashMap, отже, одне нулеве значення в HashSet як HashSet реалізує HashMap внутрішньо).
  3. HashSetі HashMapне підтримує порядок вставки під час ітерації.

3

HashSet дозволяє нам зберігати об'єкти у тому наборі, де як HashMap дозволяє нам зберігати об’єкти на основі ключа та значення. Кожен об’єкт або збережений об’єкт матиме ключ.


2

Як випливають з імен, HashMap - це асоціативна карта (відображення від ключа до значення), а HashSet - це лише набір .


2
@SpikETidE Це деталізація того, як реалізована унікальність, але сенс HashSet полягає в реалізації набору.
Майкл Боргвардт

1
так що .. все зводиться до "якщо ви не хочете, щоб дублікати використовували hashSet ... Якщо ви не турбуєтесь про дублікати, використовуйте HashMap" ....?
SpikETidE

3
Java не реалізує специфічний клас для "колекції з потенційно дублюються елементами" ("сумка"), ви можете використовувати Список для цього (хоча Список додає певну семантичну сумку: порядок; але ви можете проігнорувати це).
leonbloy

2

Відмінності між HashSet і HashMap на Java

1) Перша і найсуттєвіша відмінність HashMap від HashSet полягає в тому, що HashMap - це реалізація інтерфейсу Map, тоді як HashSet - це реалізація інтерфейсу Set, що означає, що HashMap є ключовою структурою даних на основі значень, і HashSet гарантує унікальність, не дозволяючи копії. реальність HashSet - це обгортка навколо HashMap на Java, якщо ви подивитесь на код методу add (E e) HashSet.java, ви побачите наступний код:

public boolean add(E e) 
{
    return map.put(e, PRESENT)==null;
}

де його занесення Об'єкта на карту як ключ і значення є кінцевим об'єктом НАСТУПНО, який є манекеном.

2) Друга відмінність HashMap від HashSet полягає в тому, що ми використовуємо метод add () для введення елементів у Set, але ми використовуємо метод put () для вставки ключа і значення в HashMap на Java.

3) HashSet дозволяє лише один нульовий ключ, але HashMap може дозволити один нульовий ключ + кілька нульових значень.

Це все на різниці між HashSet і HashMap на Java. Підсумовуючи, HashSet і HashMap - це два різних типи колекцій: один - Set, а інший - Map.


2

Відмінності між HashSet і HashMap на Java

HashSet внутрішньо використовує HashMap для зберігання предметів. Коли метод додавання (String) називається методом виклику HahsMap put (ключ, значення), де key = String object & value = new Object (Dummy), тому він не підтримує дублікатів, оскільки ключі є не що інше, як значення Об'єкт.

Об'єкти, які зберігаються як ключові в Hashset / HashMap, повинні перекрити контракт хеш-кодів і рівних.

Ключі, які використовуються для доступу / зберігання об'єктів значення в HashMap, повинні бути оголошені як Кінцеві, оскільки при зміні об'єкт Value не може бути розташований і повертає null.


1

A HashMap- це додавання, отримання, видалення ... об'єктів, індексованих користувацьким ключем будь-якого типу.
A HashSet- додавати елементи, видаляти елементи та перевіряти наявність елементів, порівнюючи їх хеші.

Таким чином, HashMap містить елементи, а HashSet запам'ятовує їхні хеші.


1
Порівнюючи їх хеши та називаючи їх equals()методи.
Маркіз Лорн

1

Відмінності: стосовно герархії: HashSet реалізує Set. HashMap реалізує Map і зберігає відображення ключів і значень.

Використання HashSet і HashMap стосовно бази даних допоможе вам зрозуміти значення кожного.
HashSet: зазвичай використовується для зберігання унікальних об'єктів колекції. Напр.: Він може бути використаний як клас реалізації для зберігання суднозв'язку "багато в один" між
класом "Елемент" і "Клас Bid", де (у "У об'єкта є багато ставок") HashMap: використовується для відображення ключа до value.the може бути нульовим або будь-яким об'єктом / список об'єкта (який сам по собі є об'єктом).



0

HashSet використовує HashMap внутрішньо для зберігання своїх записів. Кожен запис у внутрішньому HashMap вводиться одним об'єктом, тому всі записи хешуються в одне відро. Я не пам'ятаю, що внутрішній HashMap використовує для зберігання своїх значень, але це насправді не має значення, оскільки цей внутрішній контейнер ніколи не буде містити повторюваних значень.

РЕДАКЦІЯ : Щоб вирішити коментар Метью, він правий; Я мав це назад. Внутрішній HashMap за допомогою клавіш Об'єкти, що складають елементи Set . Значення HashMap - це об'єкт, який просто зберігається у відрах HashMap.


Це не правильно. Набір елементів використовується безпосередньо як клавіші HashMap.
Меттью Флашен

0

HashMapце Mapреалізація, що дозволяє повторювати значення, але не дублювати ключі. . Для додавання об'єкта потрібна пара ключ / значення. Допустимі значення Null Keys та Null. наприклад:

{The-> 3, world-> 5, is-> 2, nice-> 4}

HashSetце Setреалізація, яка не дозволяє дублікати. Якщо ви намагалися додати дублікат об'єкта, виклик public boolean add(Object o)методу, то набір залишається незмінним і повертається false. наприклад:

[Світ, є, приємно]


-1

Ви майже відповіли на власне запитання - хешсет не дозволяє повторювати значення. було б банально побудувати хеш-код за допомогою резервного хешмапу (і просто перевірити, чи є значення вже). Я здогадуюсь, що різні реалізації Java або роблять це, або реалізують якийсь спеціальний код, щоб зробити це більш ефективно.


1
@oedo - java.util.HashSetговорить, що це підкріплено a java.util.HashMap.
justkt

2
Не допускати копій не є різницею між ними.
Маркіз Лорн

-1

В основному в HashMap користувач повинен надавати і ключ, і значення, тоді як у HashSet ви надаєте лише значення, ключ автоматично отримується зі значення за допомогою хеш-функції. Отже, маючи і ключ, і значення, HashSet може зберігатися як HashMap внутрішньо.


Ключовим є значення в HashSet.
Маркіз Лорн

-1

HashSet і HashMap обидва зберігають пари, різниця полягає в тому, що в HashMap ви можете вказати ключ, а в HashSet ключ походить від хеш-коду об'єкта


Якщо це було правдою, HashSet не міг зберігати кілька об’єктів з одним і тим же хеш-кодом, і це робить.
Маркіз Лорн

-1

HashMapsдозволити один нульовий ключ та нульові значення. Вони не синхронізовані, що підвищує ефективність. Якщо це потрібно, ви можете зробити їх синхронізованими за допомогоюCollections.SynchronizedMap()

Hashtables не дозволяють нульові ключі та синхронізуються.


Він не просив Hashtables. Не відповідає на запитання.
Маркіз Лорн

-2

HashMap - це реалізація інтерфейсу Map. HashSet - це реалізація інтерфейсу Set

HashMap Зберігає дані у вигляді пари ключових значень HashSet Store лише об'єкти

Для додавання елемента на карті використовується метод Put, який використовується для додавання елемента Set

У хеш-карті значення хеш-коду обчислюється за допомогою ключового об'єкта. Тут об'єкт-член використовується для обчислення значення хеш-коду, яке може бути однаковим для двох об'єктів, тому метод рівного () використовується для перевірки рівності, якщо він повертає помилковим, що означає, що два об'єкти різні.

HashMap швидше, ніж хешсет, тому що унікальний ключ використовується для доступу до об'єкта HashSet повільніше, ніж Hashmap


1
Вони мають по суті ідентичну продуктивність, а "тому, що використовується унікальний ключ" є неправильним.
Маркіз Лорн
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.