【问题标题】:Java HashMap to store in different buckets internallyJava HashMap 在内部存储在不同的桶中
【发布时间】:2015-10-27 02:22:31
【问题描述】:

我有几个与存储 HashMap 相关的场景,我不知道如何完成。

案例1:因为有存储对象的桶,在保存时会考虑hashcode。现在说,有 5 个存储桶,我想自己控制保存哪个存储桶。有没有办法实现它?比如说,通过内部机制,它将被保存到存储桶 4,但我想将该特定对象保存到存储桶 1。

案例 2:同样,如果我看到 5 个存储桶中的 1 个存储桶的负载比其他存储桶多得多,我想通过将其移动到不同的存储桶来完成负载平衡工作。怎么实现?

【问题讨论】:

  • 实现的目的是让您不必担心这些细节。
  • 确实如此。想知道,有什么方法可以控制我们自己。有办法,我没找到
  • @sdgfsdh 你应该这样回答
  • 不,没有办法。内部存储是私有的。如果你想进入那个兔子洞,你可以编写自己的 HashMap 实现。
  • 如果您有理由相信一个或多个存储桶的条目过多,您可以做的一件事是将所有内容复制到具有更大容量的新HashMap,但没有什么可以弥补对于一个可怜的hashCode

标签: java memory memory-management collections


【解决方案1】:

基本上没有办法在哈希表中实现负载平衡。该结构的典型属性是直接访问必须保存所请求密钥的存储桶。任何平衡方案都将涉及重新洗牌桶之间的对象并破坏此属性。这就是为什么高质量的哈希码对于哈希表的正确操作至关重要的原因。

另外请注意,您甚至无法通过操作对象的 hashCode() 方法来控制存储桶选择,因为任何两个相等对象的哈希码必须匹配,并且因为任何自尊的哈希表实现都会另外打乱从hashCode() 检索的值以确保更好的分散。

【讨论】:

    【解决方案2】:

    这些实现的设计让您不必担心这些细节。

    如果您想更仔细地控制这些,那么您可以创建自己的类来实现Map

    【讨论】:

      【解决方案3】:

      对于 HashMap 和所有名称以 Hash 开头的集合,更重要的部分是您尝试存储的域对象生成的 hasCode。这就是为什么每个对象都有一个 hashCode 实现(使用 object.hashCode() 或显式隐含)。

      首先 HashMap 试图完成你在案例 2 中所说的(有点)。如果您的 hashCode 实现良好,则意味着可以为各种对象生成均匀分散的 hashCode 值,而不是 HashMap 的存储桶的负载或多或少均匀分布,并且您不必做任何事情(除了编写一个好的 hashCode 函数。) .此外,您可以通过为您希望它们位于同一存储桶中的对象生成相同的哈希码来相应地实现您的 hascode 来以某种方式操纵平衡。

      如果您想完全控制 hashMap 的内部结构,那么您应该通过实现 Map 接口来实现自己的 HashMap。

      【讨论】:

      • 是的,最好确保您的对象“正确”散列,而不是尝试使用 HashMap 实现
      【解决方案4】:

      桶创建和放置的底层机制被抽象掉了。 对于案例 1,您可以简单地使用对象作为存储桶放置的键。对于情况 2,您无法直接看到对象的实际位置。

      不过,您可以使用Multimap,您可以将密钥视为存储桶。它基本上是从键到集合的映射。在这里,您可以检查任何给定的键(桶)并查看您在其中放置了多少项目。在这里,您可以满足两种情况的要求。这可能与您在不实际篡改内部分桶机制的情况下所获得的一样接近。

      从链接,这里是一个sn-p:

      public class MutliMapTest {
          public static void main(String... args) {
        Multimap<String, String> myMultimap = ArrayListMultimap.create();
      
        // Adding some key/value
        myMultimap.put("Fruits", "Bannana");
        myMultimap.put("Fruits", "Apple");
        myMultimap.put("Fruits", "Pear");
        myMultimap.put("Vegetables", "Carrot");
      
        // Getting the size
        int size = myMultimap.size();
        System.out.println(size);  // 4
      
        // Getting values
        Collection<string> fruits = myMultimap.get("Fruits");
        System.out.println(fruits); // [Bannana, Apple, Pear]
      
        Collection<string> vegetables = myMultimap.get("Vegetables");
        System.out.println(vegetables); // [Carrot]
      
        // Iterating over entire Mutlimap
        for(String value : myMultimap.values()) {
         System.out.println(value);
        }
      
        // Removing a single value
        myMultimap.remove("Fruits","Pear");
        System.out.println(myMultimap.get("Fruits")); // [Bannana, Pear]
      
        // Remove all values for a key
        myMultimap.removeAll("Fruits");
        System.out.println(myMultimap.get("Fruits")); // [] (Empty Collection!)
       }
      

      【讨论】:

        猜你喜欢
        • 2012-03-25
        • 2017-04-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多