简体   繁体   English

为下面列出的特定用例处理哈希图中的冲突

[英]Handling collisions in the hashmap for the specific use case enlisted below

I've written a java based web application, simple for now since I'm a beginner in this space. 我已经编写了一个基于Java的Web应用程序,因为我是这个领域的初学者,所以现在很简单。 What it does is looks up the phone number of a person, when the user enters the name of the person in the jsp page. 当用户在jsp页面中输入该人的姓名时,它的作用是查找该人的电话号码。 I'm using a hashmap for now where I've created two objects the person and the number and basically the map is the association of the person to the number. 我现在使用的是一个哈希图,在其中我创建了人和数字两个对象,基本上,地图是人与数字的关联。 The reason I have person as an object is later on I plan to add more information to the person object. 我将人作为对象的原因是稍后计划将更多信息添加到人对象。 I also plan to eventually move the association to the database. 我还计划最终将关联移至数据库。 However, in this specific situation where I have a hash map how do I handle the use case of a "person with the same name" can be two different users because according to my hashmap the key is the person object. 但是,在这种我有哈希图的特定情况下,如何处理“同名人员”的用例可以是两个不同的用户,因为根据我的哈希图,键是人员对象。 Specifically, the user can look up the person by name. 具体而言,用户可以按姓名查找该人。 I also thought of adding a system generated id to the person object to make it unique but it doesn't solve the use case of two people having the same name as when the user is querying for the phone number he will only enter the person's name. 我还想到了将一个系统生成的ID添加到person对象以使其唯一,但这并不能解决两个人具有相同名称的用例,即当用户查询电话号码时,他只会输入该人的姓名。

The simplest solution would be to have your value type be a list of people, so: 最简单的解决方案是让您的值类型成为人员列表,因此:

Map<String, List<Person>> map = new HashMap...

It sounds like your design could do with a bit of work though. 听起来您的设计可以完成一些工作。 While you're prototyping (pre database), for example, is there any reason you need to use a HashMap? 例如,在进行原型制作(数据库前)时,是否有任何需要使用HashMap的原因? Why not just store a List<Person> , and iterate the list each time you want to search? 为什么不只存储List<Person> ,并在每次要搜索时迭代该列表? That would let you easily search on other properties of a person too. 这样一来,您也可以轻松搜索人的其他属性。

Edit: In response to Phoenix's comment. 编辑:回应凤凰城的评论。

The approach is to store a list of all people with the given name in lists within the map. 方法是在地图内的列表中存储具有给定名称的所有人员的列表。

To add a new person, you need to check if a person already exists with their name, and create an empty list to put them into if there isn't already a person. 要添加新人员,您需要检查其名称是否已经存在,如果没有人员,则创建一个空列表以将其放入。 [Sorry, I don't have a compiler handy, so haven't compiled or tested this, but the idea should be right] [抱歉,我没有编译器,所以还没有编译或测试它,但是这个想法应该是正确的]

void add(Map<String, List<Person>> map, Person p) {

    if (!map.containsKey(p.name()) {
        map.put(p.name(), new ArrayList<Person>());
    } 
    // The map will always have a (possibly empty) list of people with a given name now
    map.get(p.name()).add(p);
}

Looking people up is easy. 查找人很容易。 To print all the people with a given name: 要打印所有具有给定名称的人:

void printPeople(BufferedWriter out, Map<String, List<Person>> map, String name) {
    for (Person p : map.get(name)) {
        out.println(p.toString());
    }
}

What about this? 那这个呢?

Map<String, List<Person>> map = new HashMap<String, List<Person>>();

if(!map.contains(personName)){
    map.put(personName, new ArrayList<Person>());
}

// Construct Person person = new Person(personName, phoneNumber);

map.get(personName).add(person);

You keep a list of person as Martin suggested and put the values as list of person instead of single person. 您保留马丁建议的人员清单,并将值作为人员清单而不是单身。

While iterating... 在迭代中...

for(Person person : map.get(personName)){
    // Process person.getPhoneNumber();
}

I'm adding a second answer here. 我在这里添加第二个答案。 My other answer shows how to implement it with a Map , but I don't think it's worth the effort. 我的另一个答案显示了如何使用Map来实现它,但是我认为这样做是不值得的。

If you're using a HashMap because you're worried about performance, then you'll fix that once you put the database backend in that you've mentioned. 如果由于担心性能而使用HashMap ,则一旦提到数据库后端,就将对其进行修复。 As a general rule, don't spend effort optimising code you know you're going to throw away anyway, or don't know for sure even needs optimising. 通常,不要花费精力优化代码,无论您知道自己还是会扔掉它们,或者甚至不确定是否需要优化。

My solution (pending the real backend), would be to just use a List. 我的解决方案(在真正的后端之前)将仅使用列表。 You don't need to worry about getting your hashCode algorithm right, and I doubt it's going to come out significantly slower unless you have many thousands of entries. 您无需担心正确设置hashCode算法,而且我怀疑除非您有成千上万的条目,否则它的发布速度会大大降低。

public class People {
    private List<Person> people = new ArrayList<Person>();

    public void add(Person p) {
        people.add(p);
    }

    public List<Person> findByName(String name) {
        List<Person> result = new ArrayList<Person>();
        for (Person p : people) {
            if (p.getName().equals(name)) {
                result.add(p);
            }
         }
         return result;
     }

It's just so much simpler and clearer than the Map solution. 它比Map解决方案更加简单明了。

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

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