我试图通过Google的Maps.newHashMapWithExpectedSize(n)方法将我正在创建的新地图的大小限制为(次要)空间优化,因为我知道它将包含多少个键值条目。尽管两个键是不同的值,但不是在其自己的桶中插入每个新的键值对而是发生了冲突并且我的第一个键值对被覆盖了。我的键是String对象,n = 3.对同一个桶进行散列的两个键是"记录"和" pageSize"。
当我将代码更改为简单地使用Maps.newHashMap()时,虽然它在数据结构中产生了未使用的空间,但行为仍然符合预期。我的猜测,没有深入到实际代码中,限制HashMap的大小只会导致更高的冲突概率,尽管我认为核心数据结构可以更优雅地处理这个问题。所以我的问题是:
答案 0 :(得分:0)
两个密钥是否将散列到同一个桶取决于每个hashCode()
和桶数的组合(加上用于将哈希码映射到桶的算法,显然)。
完全有可能两个键散列到同一个桶中几乎任何表大小。冲突在哈希表中很自然 - 目标只是确保每个桶中的条目平均数相对于条目总数。较大的哈希表以更多空间为代价减少了冲突的可能性。
对n使用小值时,是否要避免使用newHashMapWithExpectedSize(n)?
不,不是真的。事实上你碰撞实际上是一个问题吗?
插入"记录"进入地图,如果我已经调用了map.hasKey(" pageSize")我会得到真的吗?
当且仅当您添加了带有键" pageSize"的条目时。散列到同一个桶对地图的行为没有影响。可以在每个存储桶中存储多个条目,并且仅当等于" pageSize"找到参数将hasKey
返回true。
因为我知道它将包含多少个键值条目
您可以使用ImmutableMap
吗?通常,当您提前知道地图将包含多少条目时,它就意味着不可变。由于ImmutableMap
知道它包含的条目数量永远不会改变,因此它有可能比可变HashMap
更好地优化其大小。更不用说不变性的所有其他好处。
答案 1 :(得分:0)
您确定要在此提供所有信息吗?这是一个互动式Scala会话,展示了您尝试做的事情:
scala> val map = com.google.common.collect.Maps.newHashMapWithExpectedSize[String, String](3)
map: java.util.HashMap[String,String] = {}
scala> map.put("pageSize", "foo")
res1: String = null
scala> map.put("records", "bar")
res2: String = null
scala> map.put("third", "3")
res3: String = null
scala> map.put("fourth", "4")
res4: String = null
scala> map.toString()
res5: String = {pageSize=foo, fourth=4, records=bar, third=3}
如您所见,该方法返回的实例是java.util.HashMap
;您可以添加超过您请求的元素数量;和碰撞处理得很好。
实际上,如果看一下at the source,那么该方法只是HashMap构造函数的包装。