草庐IT

java - 在 Hashmap 中重新散列

coder 2023-09-02 原文

关闭。这个问题需要更多focused .它目前不接受答案。












想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post .

7年前关闭。




Improve this question




影响HashMap的初始容量和负载因子两个参数表现。
默认负载因子 ( .75 ) 在时间和空间成本之间提供了很好的权衡。较高的值会减少空间开销,但会增加查找成本。

当一个项目被添加到 HashMap ,根据其 hashCode 派生的值将其分配给桶和 HashMap 的桶大小.
要识别任何桶,哈希映射使用 key.hashCode()并执行一些操作:

Bucket (index) = HashMap.indexFor(HashMap.hash(key.hashCode()),
                                  entryArray.length)

当哈希映射中的条目数超过负载因子和当前容量的乘积时,哈希映射被重新哈希(重建内部数据结构),使得哈希映射具有大约两倍的桶数。

当您重新哈希并将所有内容移动到新位置(存储桶等)时,旧元素也会再次重新哈希并根据其新哈希码存储在新存储桶中。分配给存储元素的旧空间被垃圾回收。

如果两个线程同时发现,现在HashMap需要重新调整大小并且他们都尝试重新调整大小可能会导致 HashMap 中的竞争条件.

关于 HashMap 重新调整大小的过程,存储在链表中的存储桶中的元素在迁移到新存储桶期间按顺序颠倒,因为 java HashMap不会在尾部追加新元素,而是在头部追加新元素以避免尾部遍历。如果发生竞争条件,那么您最终将陷入无限循环。

我有以下问题:
  • 为什么每个bucket的链表在执行过程中顺序颠倒
    迁移到新存储桶?
  • 竞争条件如何导致无限循环?
  • 增加桶的数量如何减少查找等待
    时间?
  • 在同一个桶中的元素仍然会在同一个
    重新散列后存储桶?
  • 最佳答案

    这就是为什么我们有 ConcurrentHashMap .对于绝大多数情况下,在没有同步的情况下不会跨多个线程共享自己的 map ,普通 HashMap就足够了。

    不能保证与 n 个桶碰撞的两个对象仍然会与 2n 个桶碰撞。仅使用计数参数,任何两个对象发生碰撞的可能性应该只有一半左右。更少的冲突意味着更短的列表,这意味着检索时间更短。

    因为我们正在重新散列并且冲突在不同数量的存储桶之间不一致,所以当您断言每个存储桶的列表作为过程的一部分被反转时,我怀疑您是否正确阅读了代码。

    关于java - 在 Hashmap 中重新散列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19020930/

    有关java - 在 Hashmap 中重新散列的更多相关文章

    1. ruby - 将散列转换为嵌套散列 - 2

      这道题是thisquestion的逆题.给定一个散列,每个键都有一个数组,例如{[:a,:b,:c]=>1,[:a,:b,:d]=>2,[:a,:e]=>3,[:f]=>4,}将其转换为嵌套哈希的最佳方法是什么{:a=>{:b=>{:c=>1,:d=>2},:e=>3,},:f=>4,} 最佳答案 这是一个迭代的解决方案,递归的解决方案留给读者作为练习:defconvert(h={})ret={}h.eachdo|k,v|node=retk[0..-2].each{|x|node[x]||={};node=node[x]}node[

    2. ruby - 如何在续集中重新加载表模式? - 2

      鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

    3. ruby-on-rails - active_admin 目录中的常量警告重新声明 - 2

      我正在使用active_admin,我在Rails3应用程序的应用程序中有一个目录管理,其中包含模型和页面的声明。时不时地我也有一个类,当那个类有一个常量时,就像这样:classFooBAR="bar"end然后,我在每个必须在我的Rails应用程序中重新加载一些代码的请求中收到此警告:/Users/pupeno/helloworld/app/admin/billing.rb:12:warning:alreadyinitializedconstantBAR知道发生了什么以及如何避免这些警告吗? 最佳答案 在纯Ruby中:classA

    4. java - 等价于 Java 中的 Ruby Hash - 2

      我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

    5. ruby - 检查字符串是否包含散列中的任何键并返回它包含的键的值 - 2

      我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案

    6. ruby - 按值降序排列散列,然后按升序键入 ruby - 2

      我有这样的哈希trial_hash={"key1"=>1000,"key2"=>34,"key3"=>500,"key4"=>500,"key5"=>500,"key6"=>500}我按值降序排列:my_hash=trial_hash.sort_by{|k,v|v}.reverse我现在是这样理解的:[["key1",1000],["key4",500],["key5",500],["key6",500],["key3",500],["key2",34]]但我希望当值相同时按键的升序排序。我该怎么做?例如:上面的散列将以这种方式排序:[["key1",1000],["key3",500

    7. ruby - 在 Ruby 中重新分配常量时抛出异常? - 2

      我早就知道Ruby中的“常量”(即大写的变量名)不是真正常量。与其他编程语言一样,对对象的引用是唯一存储在变量/常量中的东西。(侧边栏:Ruby确实具有“卡住”引用对象不被修改的功能,据我所知,许多其他语言都没有提供这种功能。)所以这是我的问题:当您将一个值重新分配给常量时,您会收到如下警告:>>FOO='bar'=>"bar">>FOO='baz'(irb):2:warning:alreadyinitializedconstantFOO=>"baz"有没有办法强制Ruby抛出异常而不是打印警告?很难弄清楚为什么有时会发生重新分配。 最佳答案

    8. java - 从 JRuby 调用 Java 类的问题 - 2

      我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

    9. ruby-on-rails - 使用 ruby​​ 将多个实例变量转换为散列的更好方法? - 2

      我收到格式为的回复#我需要将其转换为哈希值(针对活跃商家)。目前我正在遍历变量并执行此操作:response.instance_variables.eachdo|r|my_hash.merge!(r.to_s.delete("@").intern=>response.instance_eval(r.to_s.delete("@")))end这有效,它将生成{:first="charlie",:last=>"kelly"},但它似乎有点hacky和不稳定。有更好的方法吗?编辑:我刚刚意识到我可以使用instance_variable_get作为该等式的第二部分,但这仍然是主要问题。

    10. java - 我的模型类或其他类中应该有逻辑吗 - 2

      我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

    随机推荐