HashSet和HashMap之间的区别?


168

除了HashSet不允许重复值的事实之外,HashMap和之间有什么区别HashSet

我的意思是实施明智?这有点含糊,因为它们都使用哈希表存储值。


HashSet是使用HashMap实现的
Therealprashant 2015年

我认为知道为什么HashSet与ArrayList不同的原因将帮助您理解上述问题的答案: stackoverflow.com/questions/18706870/…–
djangofan

Answers:


150

它们是完全不同的构造。A HashMap是的实现Map。一个地图键映射到值。密钥查找使用散列进行。

另一方面, HashSet是的实现Set。一被设计成一组的数学模型相匹配。一个HashSet不使用HashMap支持其实现,正如你指出。但是,它实现了完全不同的接口。

当您寻找最Collection适合您的目的时,本教程是一个很好的起点。如果您真的想知道发生了什么,那本书就是


该声明有点简单。幕后还有更多内容,“”返回指定对象的哈希值。除了对象自己的hashCode之外,此方法还应用了“补充哈希函数”,以防止劣质的哈希函数。这很关键,因为HashMap使用具有两个长度的哈希表的。” weblogs.java.net/blog/2005/06/18/hashmap-implementation-但是,如果您查看文档,您会看到此哈希分发了一些东西在“桶”,所以最后我相信两件事情可以被映射同一个桶。
justkt

1
要回答第二个问题-不。映射是由@Bruno Rothgiesser的出色答案定义的(键->值)。一组用于非重复元素。如果要复制而不是key-> value,我将签出java.util.List实现。请查看Collection教程以获取
权威

@justk:是的,您可以在一个存储桶中获得两个键,然后使用equals()来区分它们。这就是为什么hashCode()和equals()必须兼容的原因。
Michael Borgwardt 2010年

6
@SpikETidE:HashMap和HashSet都不允许重复。这就是重点。
Michael Borgwardt

23
@SpikETidE:一个集合没有键/值对,只有元素。而HashSet是通过将HashMap与set元素作为键并忽略其值来实现的。
Michael Borgwardt'5

300

HashSet是一个集合,例如 {1,2,3,4,5}

HashMap是一个键->值(键到值)映射,例如 {a-> 1,b-> 2,c-> 2,d-> 1}

请注意,在我上面的示例中,HashMap中不得有重复的键,但可能会有重复的值。

在HashSet中,必须没有重复的元素。


但是,造成混乱的(最有趣的)原因是,即使在HashSet中,您也需要一个“键”来访问元素。即,即使要在数学中使用,对象也要具有名称(或地址),如果要访问或引用它们的话。因此,从实际意义上讲,HashSet是一个特别简单的HashMap,用其元素的名称(或地址)作为键。
安德鲁·马歇尔

65

哈希集

  1. HashSet类实现Set接口
  2. 在HashSet中,我们存储对象(元素或值),例如,如果我们具有字符串元素的HashSet,则它可以描述一组HashSet元素:{“ Hello”,“ Hi”,“ Bye”,“ Run”}
  3. HashSet不允许重复的元素,这意味着您不能在HashSet中存储重复的值。
  4. HashSet允许具有单个null值。
  5. HashSet不同步,这意味着除非显式同步,否则它们不适合线程安全操作。

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

哈希图

  1. HashMap类实现Map接口
  2. HashMap用于存储键和值对。简而言之,它维护键和值的映射(HashMap类与Hashtable大致等效,但它是不同步的,并且允许空值。)如果它具有整数键和String类型的值,则可以用这种方法表示HashMap元素:例如{1->“ Hello”,2->“ Hi”,3->“ Bye”,4->“ Run”}
  3. HashMap不允许重复的键,但是它允许具有重复的值。
  4. HashMap允许单个null键和任意数量的null值。
  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 '18

5

Hashset内部实现HashMap。如果看到内部实现,则在HashSet中插入的值将作为键存储在HashMap中,并且该值是Object类的Dummy对象。
HashMap与HashSet之间的区别是:

  1. HashMap 包含键值对,每个值都可以通过键访问,因为每次都需要迭代HashSet,因为没有get方法。
  2. HashMap实现Map接口,并允许一个null值作为键,并允许多个null值作为值;而在HashSet实现Set接口时,仅允许一个null值,并且不允许重复值。作为HashSet在内部实现HashMap)。
  3. HashSet并且HashMap在迭代时不保持插入顺序。

3

HashSet允许我们将对象存储在集合中,而HashMap允许我们根据键和值存储对象。每个对象或存储的对象都将具有密钥。


2

顾名思义,HashMap 是关联映射(从键到值的映射),HashSet只是Set


2
@SpikETidE这是如何实现唯一性的详细信息,但是HashSet的含义是实现集合。
Michael Borgwardt'5

1
所以..归结为“如果您不希望重复使用hashSet ...如果您不担心重复使用HashMap” ....?
SpikETidE 2010年

3
Java没有为“具有可能重复的元素的集合”(“袋子”)实现特定的类,您可以为此使用List(尽管List为bag:命令添加了一些语义;但是您可以忽略它)。
leonbloy 2010年

2

Java中HashSet和HashMap之间的区别

1) HashMap和HashSet之间的首要差异是HashMap是Map接口的实现,而HashSet是Set接口的实现,这意味着HashMap是基于键值的数据结构,HashSet通过不允许重复来保证唯一性。现实HashSet是Java中HashMap的包装,如果您查看HashSet.java的add(E e)方法的代码,您将看到以下代码:

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

其中将Object放入映射中作为键和值的是最终对象PRESENT,该对象是虚拟的。

2) HashMap和HashSet之间的第二个区别是,我们使用add()方法将元素放入Set中,但是我们使用put()方法将键和值插入Java中的HashMap中。

3) HashSet只允许一个空键,但是HashMap可以允许一个空键+多个空值。

这就是Java中HashSet和HashMap之间的区别。总之,HashSet和HashMap是Collection的两种不同类型,一种是Set,另一种是Map。


2

Java中HashSet和HashMap之间的区别

HashSet内部使用HashMap来存储对象。当add(String)方法调用时,它调用HahsMap put(key,value)方法,其中key = String object&value = new Object(Dummy)。因此它不会重复,因为键只不过是Value目的。

在Hashset / HashMap中作为键存储的对象应覆盖哈希码并等于合约。

用于访问/存储HashMap中的值对象的键应声明为Final,因为修改后无法找到Value对象并返回null。


1

A HashMap是通过任何类型的自定义键索引的添加,获取,删除...对象。
A HashSet是添加元素,删除元素并通过比较元素的哈希值检查元素是否存在。

因此,HashMap包含元素,而HashSet记住其哈希值。


1
通过比较它们的哈希值并调用其equals()方法。
罗恩侯爵

1

区别:就层次结构而言:HashSet实现Set。HashMap实现Map并存储键和值的映射。

对数据库使用HashSet和HashMap可以帮助您理解它们的重要性。
HashSet:通常用于存储唯一的集合对象。例如:它可以用作实现类,用于在
类Item和类Bid 之间存储多对一关系,其中(项具有很多Bid)HashMap:用于将键映射到value。该值可以为null或任何Object /对象列表(本身就是对象)。



0

HashSet在内部使用HashMap来存储其条目。内部HashMap中的每个条目都由单个Object键控,因此所有条目都哈希到同一存储桶中。我不记得内部HashMap用于存储其值的内容了,但是这并不重要,因为该内部容器永远不会包含重复的值。

编辑:要解决马修的评论,他是对的;我倒退了。内部HashMap 用组成Set元素的Object进行键控。HashMap的值是一个仅存储在HashMap存储桶中的对象。


那是不对的。set元素直接用作HashMap键。
马修·弗拉申

0

HashMap是一种Map实现,允许重复的值,不允许重复的键。。要添加对象,需要键/值对。空键和空值是允许的。例如:

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

HashSet是一个Set实现,不允许重复。如果您尝试添加重复的对象(对public boolean add(Object o)方法的调用),则该集合将保持不变并返回false。例如:

[这个世界真好]


-1

您几乎回答了自己的问题-哈希集不允许重复的值。使用后备哈希表构建哈希集(并且仅检查值是否已存在)将是微不足道的。我猜想各种Java实现要么这样做,要么实现一些自定义代码以更有效地实现它。


1
@oedo- java.util.HashSet表示由java.util.HashMap
justkt 2010年

2
不允许重复没有区别。
罗恩侯爵,

-1

基本上,在HashMap中,用户必须同时提供键和值,而在HashSet中,您仅提供值,则使用哈希函数从值自动派生键。因此,在拥有键和值之后,HashSet可以在内部存储为HashMap。


关键 HashSet中的值。
罗恩侯爵,

-1

HashSet和HashMap都存储对,区别在于在HashMap中可以指定键,而在HashSet中,键来自对象的哈希码


如果是这样,则HashSet不能存储具有相同hashCode的多个对象,并且可以。
罗恩侯爵

-1

HashMaps允许一个空键和空值。它们不同步,从而提高了效率。如果需要,可以使它们使用同步Collections.SynchronizedMap()

Hashtables 不允许使用空键并已同步。


他没有问过哈希表。不回答问题。
罗恩侯爵

-2

HashMap是Map接口的实现HashSet是Set接口的实现

HashMap以键值对的形式存储数据HashSet仅存储对象

Put方法用于在地图中添加元素Add方法用于添加Set中的元素

在哈希图中,哈希码值是使用键对象计算的。成员对象用于计算哈希码值,该值对于两个对象可以是相同的,因此equal()方法用于检查是否相等,如果它返回false则意味着两个对象不同。

HashMap比hashset快,因为使用唯一键访问对象HashSet比Hashmap慢


1
它们具有基本相同的性能,并且“因为使用了唯一密钥”是不正确的。
罗恩侯爵,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.