Разница между HashSet и HashMap?

168

Помимо того, что HashSetне допускает дублирования значений, в чем разница между HashMapи HashSet?

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

SpikETidE
источник
HashSet реализован с использованием HashMap
там было
Я думаю, знание того, почему HashSet отличается от ArrayList, поможет вам понять ответ на поставленный выше вопрос: stackoverflow.com/questions/18706870/…
djangofan

Ответы:

150

Это совершенно разные конструкции. А HashMapявляется реализацией Map. Карта отображает ключи на значения. Поиск ключа происходит с использованием хэша.

С другой стороны, a HashSetявляется реализацией Set. Набор предназначен для соответствия математической модели набора. A HashSetиспользует a HashMapдля поддержки своей реализации, как вы заметили. Тем не менее, он реализует совершенно другой интерфейс.

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

justkt
источник
Это утверждение немного упрощенно. Под крышками происходит еще кое-что, "" Возвращает значение хеш-функции для указанного объекта. В дополнение к собственному хеш-коду объекта этот метод применяет «дополнительную хеш-функцию», которая защищает от некачественных хеш-функций. Это очень важно, потому что в HashMap используются хеш-таблицы двух степеней длины. " Weblogs.java.net/blog/2005/06/18/hashmap-implementation - однако, если вы посмотрите на документ, вы увидите, что этот хеш-код распределяет вещи над «ведрами», так что в конце я верю, что две вещи могут быть сопоставлены одному и тому же ведру
justkt
1
Ответить на ваш второй вопрос - нет. Карта, если вы хотите (ключ -> значение), как определено отличным ответом @Bruno Rothgiesser. Набор для неповторяющихся элементов. Если вам нужны дубликаты, а не key-> value, я бы проверил реализацию java.util.List. Посмотрите учебник по Коллекции, где вы найдете подробное
justkt,
@justk: да, вы можете получить два ключа в одном ведре, а затем для их различения используется метод equals (). Вот почему важно, чтобы 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 не должно быть повторяющихся элементов.

b.roth
источник
Но (самая интересная) причина путаницы в том, что даже в 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 . Это наименее важная часть из них. Важные части следуют за Хешем - Сет и Карта , как указывали другие. Соответственно, они представляют собой Set - неупорядоченную коллекцию - и Map - коллекцию с доступом по ключу. Они реализованы с помощью хэшей - отсюда и имена, но их сущность скрыта за этой частью их имен.

Не смущайтесь их именами; это глубоко разные вещи.

Карл Манастер
источник
@HiteshSahu Они оба реализованы с помощью хеш-таблиц ( en.wikipedia.org/wiki/Hash_table ). Это хорошая структура данных для представления набора, правильная и эффективная, и, по сути, ключи HashMap реализованы как HashSet. Таким образом, кто бы ни назвал их, они столкнулись с некоторыми трудностями при их реализации и были сосредоточены на реализации, а не на их цели (по предположению).
Карл
1
Хорошо объяснил. Спасибо.
user3932000
5

В HashsetВнутренне орудия HashMap. Если вы видите внутреннюю реализацию, значения, вставленные в HashSet, хранятся в виде ключей в HashMap, а значение является объектом Dummy класса Object.
Разница между HashMap и HashSet:

  1. HashMap содержит пары ключ-значение, и к каждому значению можно получить доступ по ключу, поскольку HashSet необходимо повторять каждый раз, так как нет метода get.
  2. HashMapреализует интерфейс Map и допускает одно нулевое значение в качестве ключа, а несколько пустых значений - в качестве значений. Где HashSetреализован интерфейс Set, допускается только одно нулевое значение и нет дублирующихся значений. (Запомните, один нулевой ключ допускается в ключе HashMap, следовательно, одно нулевое значение в HashSet поскольку HashSet реализует HashMap внутренне).
  3. HashSetи HashMapне поддерживает порядок вставки во время итерации.
Абхай С
источник
3

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

Spidfire
источник
2

Как видно из названий, HashMap - это ассоциативная карта (отображение ключа на значение), а HashSet - это просто Set .

leonbloy
источник
2
@SpikETidE Это деталь того, как реализована уникальность, но смысл HashSet заключается в реализации набора.
Майкл Боргвардт
1
так что ... все сводится к "если вы не хотите дубликатов, используйте hashSet ... Если вы не беспокоитесь о дубликатах, используйте HashMap" ....?
SpikETidE
3
Java не реализует определенный класс для «коллекции с потенциально дублированными элементами» («сумка»), для этого вы можете использовать List (хотя List добавляет некоторую семантику в порядок bag:; но вы можете игнорировать это).
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 - это два разных типа Коллекции, один из которых является Установленным, а другой - Картой.

Вибха Санскритаян
источник
2

Различия между HashSet и HashMap в Java

HashSet внутренне использует HashMap для хранения objects.when метод add (String), вызывающий его, вызывает метод put (key, value) HahsMap, где key = String object & value = new Object (Dummy). Таким образом, он не содержит дубликатов, потому что ключи - это не что иное, как Value Объект.

Объекты, которые хранятся как ключи в Hashset / HashMap, должны переопределять хэш-код и равно контракту.

Ключи, которые используются для доступа / сохранения объектов-значений в HashMap, должны быть объявлены как Final, поскольку при его изменении объект Value не может быть найден и возвращает ноль.

user3539704
источник
1

А HashMapзаключается в добавлении, получении, удалении ... объектов, проиндексированных с помощью пользовательского ключа любого типа.
А HashSetсостоит в добавлении элементов, удалении элементов и проверке наличия элементов путем сравнения их хешей.

Таким образом, HashMap содержит элементы, а HashSet запоминает их хеши.

Мартейн Курто
источник
1
Сравнивая их хеши и вызывая их equals()методы.
маркиз Лорн
1

Различия: по отношению к иерархии: HashSet реализует Set. HashMap реализует Map и хранит сопоставление ключей и значений.

Использование HashSet и HashMap по отношению к базе данных поможет вам понять значение каждого из них.
HashSet: обычно используется для хранения уникальных объектов коллекции. Например: он может использоваться в качестве класса реализации для хранения отношения многие-к-одному между
классом Item и предложением класса, где (Item имеет много предложений) HashMap: используется для сопоставления ключа со значением. Значение может быть нулевым или любым объектом. / список объекта (который сам по себе является объектом).

frictionlesspulley
источник
0

HashSet реализуется в терминах HashMap . Это отображение между ключом и НАСТОЯЩИМ объектом.

Мэтью Флэшен
источник
5
Что такое «НАСТОЯЩИЙ объект»?
Маркиз Лорн
0

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

РЕДАКТИРОВАТЬ : Чтобы ответить на комментарий Мэтью, он прав; У меня было это задом наперед. Внутренний HashMap связан с объектами, которые составляют элементы Set . Значения HashMap - это Объект, который просто хранится в корзинах HashMap.

Энди Герна
источник
Это не правильно. Заданные элементы непосредственно используются в качестве ключей HashMap.
Мэтью Флэшен
0

HashMapявляется Mapреализацией, позволяющей дублировать значения, но не дублировать ключи. , Для добавления объекта требуется пара ключ / значение. Нулевые ключи и нулевые значения допускаются. например:

{В-> 3, миро-> 5, IS-> 2, nice-> 4}

HashSetявляется Setреализацией, которая не допускает дублирования. Если вы попытались добавить дублирующийся объект, вызов public boolean add(Object o)метода, то набор остается неизменным и возвращается false. например:

[, Мир, есть хороший]

Минни
источник
-1

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

Крис
источник
1
@oedo - java.util.HashSetговорит, что это поддерживается java.util.HashMap.
Юстект
2
Запрет дубликатов не является разницей между ними.
Маркиз Лорн
-1

По сути, в HashMap пользователь должен предоставить и Key, и Value, тогда как в HashSet вы предоставляете только Value, ключ автоматически получается из Value с помощью хеш-функции. Таким образом, имея ключ и значение, HashSet может храниться как HashMap внутри.

Муниш Гоял
источник
Ключ является значением в HashSet.
Маркиз Лорн
-1

HashSet и HashMap хранят пары, разница в том, что в HashMap вы можете указать ключ, а в HashSet ключ происходит из хеш-кода объекта

prateeksarda
источник
Если это так, HashSet не может хранить несколько объектов с одинаковым hashCode, и это происходит.
Маркиз Лорн
-1

HashMapsразрешить один нулевой ключ и нулевые значения. Они не синхронизированы, что повышает эффективность. Если это необходимо, вы можете синхронизировать их, используяCollections.SynchronizedMap()

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

Appesh
источник
Он не спрашивал о Hashtables. Не отвечает на вопрос.
Маркиз Лорн
-2

HashMap - это реализация интерфейса Map. HashSet - это реализация интерфейса Set.

HashMap Хранит данные в виде пары ключ-значение. HashSet Хранит только объекты

Метод Put используется для добавления элемента в карту. Метод Add используется для добавления элемента. Set

В хэш-карте значение хеш-кода вычисляется с использованием ключевого объекта. Здесь объект-член используется для вычисления значения хеш-кода, которое может быть одинаковым для двух объектов, поэтому метод equal () используется для проверки на равенство, если он возвращает false, что означает, что два объекта различны.

HashMap работает быстрее, чем hashset, поскольку для доступа к объекту используется уникальный ключ. HashSet работает медленнее, чем Hashmap.

Хенгейм
источник
1
Они имеют практически одинаковую производительность, а «потому что используется уникальный ключ» неверно.
Маркиз Лорн