简体   繁体   English

澄清基于接触式应用程序的Java中的冲突处理

[英]Clarification regarding collision handling in Java for my contact based app

I am using java.util.HashMap for association between a contact Name and a list of phone numbers associated with the contact so it is of type String, List<String> . 我正在使用java.util.HashMap在联系人姓名和与该联系人关联的电话号码列表之间建立关联,因此它的类型为String, List<String> However there can be more than one keys that can map to the the same bucket correct as in Say key1:<1234,5678> is stored in index 2 in the hash Map. 但是,可以有多个键可以映射到与Say 1中正确的桶相同的值:<1234,5678>存储在哈希映射的索引2中。 I could have another key2 that can hash into the same index. 我可以拥有另一个可以哈希到相同索引的key2。 So, will the key1:<1234,5678> be replaced by key2:<7890,1456> ???? 因此,将key1:<1234,5678>替换为key2:<7890,1456>吗???? Or will it be chained and both key1 and key2 will be stored in that index ? 还是将其链接起来,并将key1和key2都存储在该索引中?

EDIT: I'm trying to understand this, the code below only returns New Mexico. 编辑:我试图理解这一点,下面的代码仅返回新墨西哥州。 Now in this case both they both get the same hashcode so this is a collision correct ? 现在,在这种情况下,它们两个都获得相同的哈希码,因此这是否正确? In that case shouldn't both the values be chained ? 在那种情况下,两个值都不应该被链接吗? So shouldn't the storage look like say hashcode is 2 then at the index of 2 in the map (OR array) it should be 1-Mexico, 1-New mexico correct? 因此,存储不应该像哈希码那样为2,然后在映射(OR数组)的索引为2的情况下,它应该是1-Mexico,1-New Mexico正确吗? So the values returned should be of Mexico and New mexico ? 因此返回的值应该是墨西哥和新墨西哥州? Why isn't it getting chained here ? 为什么它在这里不被束缚?

public static void main(String[] args)
    {
        Map<Integer,String> map = new HashMap<Integer,String>();
        map.put(1, "Mexico");
        map.put(1, "New Mexico");
        System.out.println(map.get(1));

    }

I'm not totally sure I understand your question. 我不确定我是否理解您的问题。

In a standard HashMap , if you put another value with the same key, it replaces the first one. 在标准HashMap中 ,如果您使用相同的键放置另一个值,它将替换第一个值。

But you may use for example a MultiMap (from Apache commons) to store more than one value per key. 但是,您可能会使用例如MultiMap (来自Apache公用事业)来为每个键存储多个值。

If your question is related to more than one key having the same index, this is handled by the implementation : the keys for are stored in linked lists (one for each bucket) and real comparisons (using equals ) are done on get and put operations so that no collision can happen as long as equals returns false. 如果您的问题与具有相同索引的多个键有关,则由以下实现处理:的键存储在链接列表中(每个存储桶一个),真正的比较(使用equals )在get和put操作中完成因此只要equals返回false,就不会发生碰撞。

As with any collection related problem, the important thing to do if you intend to use your own class is to correctly implement the equals and hashcode methods (read this ). 与任何与集合相关的问题一样,如果您打算使用自己的类,那么要做的重要事情就是正确地实现equalshashcode方法(请阅读this )。

Regarding your question in edit : 关于您的编辑问题:

This is a feature of HashMap that the first value with a given key is erased by the new one. 这是HashMap的功能,具有给定键的第一个值将被新的键擦除。 So "Mexico" is removed from the HashMap when you add "New Mexico". 因此,当您添加“ New Mexico”时,将从HashMap中删除“ Mexico”。

If you want to have more than one value for a given key, use a MultiMap (or simply use a HashMap<Integer, List<String>> but the put operation is a little more tedious). 如果您希望给定键具有多个值,请使用MultiMap(或简单地使用HashMap<Integer, List<String>>put操作则有些繁琐)。

This is a design that you ought to think through more carefully. 这是您应该仔细考虑的设计。 It seems to me that you're using a Map and primitives - String is a primitive when you use it this way - as a poor approximation to an abstraction that would be better served by a real abstract data type of your own design. 在我看来,您正在使用Map和基元-当您以这种方式使用String时,它是基元-作为对抽象的较差近似,而您自己设计的真实抽象数据类型将更好地解决这一问题。

For example, contact name String doesn't feel like a good abstraction to me. 例如,联系人姓名String对我而言感觉不是很好的抽象。 How many repeated names are there in a phone book? 电话簿中有多少个重复的名字? Once your solution grows beyond a non-trivial size you'll have collisions. 一旦您的解决方案扩展到非同寻常的规模,您就会遇到冲突。

So where's the Contact class? 那么Contact类在哪里? Let it encapsulate the name String and List of associated phone numbers in a single object, with a well-written equals and hashCode. 让它将名称String和关联的电话号码List封装在一个对象中,并带有编写良好的equals和hashCode。 Give it a unique id private member; 给它一个唯一的id私人成员; no collisions that way. 这样就不会发生碰撞。 People who use that class will instantly get a better understanding of what you're trying to accomplish. 使用该课程的人将立即更好地了解您要完成的工作。

No, when two different keys hash to the same value, the keys are chained and then during operations, the system performs a equals against the actual keys to located the correct entry. 否,当两个不同的键散列到相同的值时,这些键被链接在一起,然后在操作过程中,系统对实际键执行等于操作以找到正确的条目。

If you created a degenerate class that simply returns 1 for hashCode(), HashMap will still work to spec, it will just perform terribly and turn in to a simple list. 如果您创建的简并类仅为hashCode()返回1,则HashMap仍将按规范运行,它将执行得很糟糕,并显示一个简单列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM