Java 如何检查存储在hashmap中的对象中是否存在字符串?
我创建了一个包含3个参数的Employee类 身份证件 名称 年龄 要求:基于名称搜索。在这种情况下,所有员工都有一个唯一的名称。必须添加键为id的对象。很少有情况需要根据名称进行搜索 我所做的: 在类中,我重写hashCode和Equals方法 我将这些对象的列表添加到hashmap中,id作为key,value作为Employee对象 但是,当添加或从hashmap搜索时,这两个方法都不会被调用 那么这些方法在hasmap上有什么用呢 雇员阶级Java 如何检查存储在hashmap中的对象中是否存在字符串?,java,collections,hashmap,Java,Collections,Hashmap,我创建了一个包含3个参数的Employee类 身份证件 名称 年龄 要求:基于名称搜索。在这种情况下,所有员工都有一个唯一的名称。必须添加键为id的对象。很少有情况需要根据名称进行搜索 我所做的: 在类中,我重写hashCode和Equals方法 我将这些对象的列表添加到hashmap中,id作为key,value作为Employee对象 但是,当添加或从hashmap搜索时,这两个方法都不会被调用 那么这些方法在hasmap上有什么用呢 雇员阶级 public class Employee {
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);
}
}
我没有测试,但是试了一下
HashMap<Integer, Employee> empmap=new HashMap<>();
甚至
HashMap<Integer, Employee> empmap=new HashMap<Integer, Employee>();
这可以在Java8中使用streams很好地完成
empmap.values().stream().anyMatch(emp.getName().equals(searchedName));
这将获取映射中所有条目的集合,并查看流是否匹配名称等于searchedName的任何条目
在可比较的数据库中,您还可以使用
实现不同版本的equals/hashcode是一件棘手的事情,因为它在许多方面改变了类的行为 您没有覆盖Object.equalsObject o,您需要这样做。你让它超载了。这就是为什么没有人叫它 尝试以下方法:
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;
}
在类中,我重写hashCode和Equals方法。
[...]
但是,当添加或从hashmap搜索时,这两个方法都不会被调用
那么这些方法在hasmap上有什么用呢
如果您有一个映射,并且在该映射上调用put或get,那么hashCode和equals将在Key类上调用,而不是在Value类上调用
在您的例子中,这意味着如果您执行empmap.putemp1.getId,emp1;然后检查emp1.getId的散列,以及该散列是否已经在映射中。因此,不在Employee类上调用这些方法是正常的
另外,如果id是唯一属性,那么Employee.hashCode可能也应该基于该属性和equals,以与hashCode保持一致,并且如另一个答案中所述,Employee.equals应该接受任何对象作为参数。解决问题的最简单方法是将此方法添加到Employee类中。 在本例中,HashMap使用值对象的equalsObject来检查该对象是否存在
@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;
}
注意,equalsObject的这个实现只对名称有效,而不检查其他字段
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));
是
真的
true如果id是唯一属性,hashCode不应该基于该属性而不是名称吗?此外,对作为映射键的对象调用hashCode方法,即id,而不是值,即Employee。。。。它比containsValueo更大更复杂。顺便说一句:我会使用emp.values.stream…关于这些值,我会相应地更新答案。containsValue的问题在于,它只允许使用equals,如果您更改其含义,则会产生许多其他影响。如果您使用equalsIgnoreCase进行相等性检查,则hashCode实现也必须不区分大小写。
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));