简体   繁体   English

如何检查存储在哈希图中的对象中是否存在字符串?

[英]How to check if a string exists in a object which is stored in a hashmap?

I have created a Employee class with 3 parameters. 我用3个参数创建了一个Employee类。

  1. Id ID
  2. Name 名称
  3. Age 年龄

Requirement: Search based on Name. 要求:根据名称搜索。 This is a case where all employees have a unique name. 在这种情况下,所有员工都有唯一的名称。 Its mandatory to add the objects with key as id. 必须添加键为id的对象。 There are rare cases where it is required to search based on name. 在极少数情况下,需要根据名称进行搜索。

What i have done : 我做了什么 :

Within the class I am overriding hashCode and Equals method. 在该类中,我将重写hashCode和Equals方法。

I am adding a list of these objects into the hashmap with id as key and value as Employee object 我将这些对象的列表添加到哈希图中,其ID为键,值作为Employee对象

But while adding or searching from a hashmap both the methods do not get called 但是在添加或从哈希图搜索时,两种方法都不会被调用

So what is the use of these methods in terms on hasmap? 那么在hasmap上这些方法的用途是什么?

Employee Class 员工阶层

public class Employee {

    private int id;
    private String name;
    private int age;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int hashCode() {
        return name.hashCode();
    }

    public boolean equals(Employee emp) {
        if (emp == null)
            return false;
        else if (emp.name.equalsIgnoreCase(this.name))
            return true;
        else
            return false;
    }
}

Main Method: 主要方法:

public class HashMapTest {

    public static void main(String[] args) {

        Employee emp1=new Employee();
        emp1.setId(1);
        emp1.setName("Maclean");
        emp1.setAge(24);

        Employee emp2=new Employee();
        emp2.setId(2);
        emp2.setName("Sampath");
        emp2.setAge(25);

        Employee emp3=new Employee();
        emp3.setId(3);
        emp3.setName("Achar");
        emp3.setAge(27);

        Employee emp4=new Employee();
        emp4.setId(4);
        emp4.setName("Sudheer");
        emp4.setAge(25);

        Employee emp5=new Employee();
        emp5.setId(5);
        emp5.setName("Kunder");
        emp5.setAge(25);

        HashMap<Integer, Employee> empmap=new HashMap();
        empmap.put(emp1.getId(), emp1);
        empmap.put(emp2.getId(), emp2);
        empmap.put(emp3.getId(), emp3);
        empmap.put(emp4.getId(), emp4);
        empmap.put(emp5.getId(), emp5);

        Employee emp=new Employee();
        emp.setName("Maclean");
        System.out.println(empmap.containsValue(emp));

        System.exit(1);
    }

}

Update Solution: 更新解决方案:

Thanks for all the answers. 感谢所有的答案。

1. hashCode method gets called only if the Key is a object and the method exists within the Key Class 1.仅当Key是一个对象并且该方法存在于Key类中时,hashCode方法才被调用

2. Equals(Employee emp) is causing function overloading instead of overriding. 2. Equals(Employee emp)导致函数重载而不是覆盖。 I should have used equals(Object o) 我应该使用equals(Object o)

Changes in the code to resolve the issue 更改代码以解决问题

@Override
public boolean equals(Object o) {
    if (o == null)
        return false;
    if (!(o instanceof Employee))
        return false;

    Employee emp = (Employee) o;
    if (emp.name.equalsIgnoreCase(this.name))
        return true;
    else
        return false;
}

You are not overriding Object.equals(Object o), which you need to do. 您没有重写需要做的Object.equals(Object o)。 You are overloading it. 您正在超载。 That's why it's not being called. 这就是为什么它没有被调用的原因。

Try this equals() instead: 试试这个equals():

public boolean equals(Object o) {
    if (o == null)
        return false;
    if (!(o instanceof Employee))
        return false;

    Employee emp = (Employee) o;
    if (emp.name.equalsIgnoreCase(this.name))
        return true;
    else
        return false;
}

Within the class I am overriding hashCode and Equals method. 在该类中,我将重写hashCode和Equals方法。 [...] But while adding or searching from a hashmap both the methods do not get called So what is the use of these methods in terms on hasmap? [...]但是在添加哈希表或从哈希表搜索时,这两种方法都不会被调用。那么在hasmap上这些方法的用途是什么?

If you have a Map<Key, Value> , and you call put or get on that map, then hashCode and equals are called on the Key class, not on the Value class. 如果您有Map<Key, Value> ,并且在该地图上调用putget ,那么hashCodeequals会在Key类而不是Value类上调用。

In your case, that means that if you do empmap.put(emp1.getId(), emp1); 就您而言,这意味着如果您执行empmap.put(emp1.getId(), emp1); then it checks the hash of emp1.getId() and whether that's already in the map. 然后它检查emp1.getId()的哈希值以及该哈希值是否已在映射中。 So it's normal that those methods are not called on your Employee class. 因此,通常不会在Employee类上调用这些方法。

Also, if id is the "unique" attribute, then Employee.hashCode should probably be based on that (and equals , too, to be consistent with hashCode ), and as noted in another answer, Employee.equals should accept any Object as parameter. 另外,如果id是“唯一”属性,则Employee.hashCode可能应该基于该属性(也equals hashCode ,也要与hashCode保持一致),如另一个答案所述, Employee.equals应该接受任何Object作为参数。

I did not test, but try it with 我没有测试,但可以尝试

HashMap<Integer, Employee> empmap=new HashMap<>();

or even 甚至

HashMap<Integer, Employee> empmap=new HashMap<Integer, Employee>();

This can be done very nicely in Java 8 using streams. 在Java 8中使用流可以很好地做到这一点。

empmap.values().stream().anyMatch(emp.getName().equals(searchedName)); 

This takes the set of all entries in the map and see if the stream matches any entry that has a name equal to your searchedName . 这将获取映射中所有条目的集合,并查看流是否与名称等于searchedName任何条目匹配。

In a comparable you can also fetch all matching names by using Stream.filter() 在可比对象中,您还可以使用Stream.filter()获取所有匹配的名称。

Implementing a different version of equals/hashcode is tricky because it changes the behavior of the class in many ways. 实现不同版本的equals / hashcode是棘手的,因为它以多种方式改变了类的行为。

The easiest solution for your problem is to add this method to the Employee class. 解决您问题的最简单的方法是将此方法添加到Employee类中。 Silently, HashMap uses the equals(Object o) of a value object (in this case Employee) for checking the existence of that object. HashMap静默地使用值对象(在本例中为Employee)的equals(Object o)检查该对象的存在。

@Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Employee employee = (Employee) o;

        if (name != null ? !name.equals(employee.name) : employee.name != null) return false;

        return true;
    }

Be careful, This implementation of equals(Object o) just works on the name and it does not check other fields. 请注意,equals(Object o)的此实现仅对名称起作用,并且不检查其他字段。

Employee emp=new Employee();
emp.setId(10);
emp.setName("Maclean");
emp.setAge(240);

System.out.println(empmap.containsValue(emp));
System.out.println(emp1.equals(emp));

is

true true 真实真实

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

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