如何检查存储在哈希图中的对象中是否存在字符串?
How to check if a string exists in a object which is stored in a hashmap?
我创建了一个带有 3 个参数的员工 class。
- 编号
- 姓名
- 年龄
要求:根据姓名搜索。在这种情况下,所有员工都有一个唯一的名字。必须添加以 key 作为 id 的对象。在极少数情况下需要根据名称进行搜索。
我做了什么:
在 class 中,我覆盖了 hashCode 和 Equals 方法。
我将这些对象的列表添加到 hashmap 中,id 作为键,value 作为 Employee 对象
但是在从哈希图中添加或搜索时,这两种方法都不会被调用
那么这些方法在hasmap上有什么用呢?
员工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;
}
}
主要方法:
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);
}
}
更新解决方案:
谢谢大家的回答。
1.仅当 Key 是一个对象并且该方法存在于 Key Class
中时才会调用 hashCode 方法
2。 Equals(Employee emp) 导致函数重载而不是覆盖。我应该使用 equals(Object o)
更改代码以解决问题
@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;
}
我没有测试,但用
试试
HashMap<Integer, Employee> empmap=new HashMap<>();
甚至
HashMap<Integer, Employee> empmap=new HashMap<Integer, Employee>();
这可以在 Java 8 中使用流很好地完成。
empmap.values().stream().anyMatch(emp.getName().equals(searchedName));
这会获取映射中所有条目的集合,并查看流是否与任何名称与您的 searchedName
相同的条目相匹配。
在可比较的情况下,您还可以使用 Stream.filter()
获取所有匹配的名称
实施不同版本的 equals/hashcode 很棘手,因为它在很多方面改变了 class 的行为。
您没有重写 Object.equals(Object o),这是您需要做的。你正在超载它。这就是它没有被调用的原因。
试试这个 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.
[...]
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?
如果您有 Map<Key, Value>
,并且您在该地图上调用 put
或 get
,则 hashCode
和 equals
会在 Key
class,不上Value
class.
在您的情况下,这意味着如果您执行 empmap.put(emp1.getId(), emp1);
那么它会检查 emp1.getId()
的散列以及它是否已经在地图中。因此,在您的 Employee
class.
上不调用这些方法是正常的
此外,如果 id
是 "unique" 属性,那么 Employee.hashCode
可能应该基于该属性(并且 equals
也应该与 hashCode
),并且如另一个答案中所述,Employee.equals
应该接受任何 Object
作为参数。
解决您问题的最简单方法是将此方法添加到 Employee class。
默默地,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;
}
注意,这个 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));
是
真
真
我创建了一个带有 3 个参数的员工 class。
- 编号
- 姓名
- 年龄
要求:根据姓名搜索。在这种情况下,所有员工都有一个唯一的名字。必须添加以 key 作为 id 的对象。在极少数情况下需要根据名称进行搜索。
我做了什么:
在 class 中,我覆盖了 hashCode 和 Equals 方法。
我将这些对象的列表添加到 hashmap 中,id 作为键,value 作为 Employee 对象
但是在从哈希图中添加或搜索时,这两种方法都不会被调用
那么这些方法在hasmap上有什么用呢?
员工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;
}
}
主要方法:
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);
}
}
更新解决方案:
谢谢大家的回答。
1.仅当 Key 是一个对象并且该方法存在于 Key Class
中时才会调用 hashCode 方法2。 Equals(Employee emp) 导致函数重载而不是覆盖。我应该使用 equals(Object o)
更改代码以解决问题
@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;
}
我没有测试,但用
试试HashMap<Integer, Employee> empmap=new HashMap<>();
甚至
HashMap<Integer, Employee> empmap=new HashMap<Integer, Employee>();
这可以在 Java 8 中使用流很好地完成。
empmap.values().stream().anyMatch(emp.getName().equals(searchedName));
这会获取映射中所有条目的集合,并查看流是否与任何名称与您的 searchedName
相同的条目相匹配。
在可比较的情况下,您还可以使用 Stream.filter()
实施不同版本的 equals/hashcode 很棘手,因为它在很多方面改变了 class 的行为。
您没有重写 Object.equals(Object o),这是您需要做的。你正在超载它。这就是它没有被调用的原因。
试试这个 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. [...] 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?
如果您有 Map<Key, Value>
,并且您在该地图上调用 put
或 get
,则 hashCode
和 equals
会在 Key
class,不上Value
class.
在您的情况下,这意味着如果您执行 empmap.put(emp1.getId(), emp1);
那么它会检查 emp1.getId()
的散列以及它是否已经在地图中。因此,在您的 Employee
class.
此外,如果 id
是 "unique" 属性,那么 Employee.hashCode
可能应该基于该属性(并且 equals
也应该与 hashCode
),并且如另一个答案中所述,Employee.equals
应该接受任何 Object
作为参数。
解决您问题的最简单方法是将此方法添加到 Employee class。 默默地,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;
}
注意,这个 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));
是
真 真