2015-10-26 48 views
0

我有几个与存储HashMap相关的场景,我不知道该如何实现。Java HashMap在内部存储在不同桶中

案例1:由于存在对象被保存在其中的桶,并且在保存对象时将考虑哈希码。现在说,有5个桶,我想自己控制哪个桶来保存它。有没有办法实现它?说,通过内部机制,它将被保存到桶4中,但我想将该特定对象保存到桶1中。

案例2:同样,如果我看到5个桶中有1桶正在比其他更多的负载,我想通过将它移动到不同的桶来做一个负载平衡类型的工作。如何才能完成?

+3

这些实现设计,使你不应该担心这些细节。 – sdgfsdh

+0

的确如此。想知道,有什么办法来控制自己。有一些方法,我没有找到它 – Deca

+0

@sdgfsdh你应该作出回答 – CPerkins

回答

1

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

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

2

基本上没有办法在哈希表中实现负载平衡。这种结构的典型特征是直接访问必须保存请求密钥的桶。任何平衡计划都会涉及重新洗净水桶之间的物体并摧毁这个属性。这就是为什么高质量的hashcode对散列表正确运行至关重要的原因。

此外请注意,你甚至无法通过操纵你的对象的hashCode()方法控制桶的选择,因为任何两个相等对象的散列码必须匹配,并且因为任何有自尊的散列表实施方案将另外洗牌值的位从hashCode()检索,以确保更好的分散。

1

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

首先HashMap试图完成你在情况2(有点)中陈述的内容。如果你的hashCode实现是好的,意思是可以为各种对象生成均匀分散的hashCode值,而HashMap的桶的加载或多或少是均匀分布的,并且你不需要任何东西(除了编写一个好的hashCode函数)。 。你也可以以某种方式通过相应地实现你的hascode,通过为你希望它们在同一个桶中的对象生成相同的哈希码来平衡平衡。

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

+0

是的,最好确保你的对象散列“正确”,而不是试图使用HashMap实现 – secolive

1

将存储桶创建和布局的基本机制抽象出来。 对于案例1,您可以简单地使用对象作为存储桶布置的关键字。对于情况2,您无法直接看到对象的实际位置。

虽然,你可以做的是使用Multimap,你可以把它们看作是桶。它基本上是从键到集合的映射。在这里你可以检查任何给定的键(桶),看看你有多少物品放在那里。在这里你可以满足这两种情况的要求。这可能与您在不实际篡改内部分拣机制的情况下获得的结果相近。

从链接,这里是一个片段:

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!) 
}