我正在尝试从HashMap中删除一个元素,其中的键是一个称为(Foo)的对象。我为equals方法设置了@Override,因此对象没有匹配。
public class Foo{
String name;
Foo(String name){
this.name = name;
}
@Override
public String toString() {
return this.name;
}
@Override
public boolean equals(Object o) {
if (o == null)
return false;
if (!(o instanceof Foo))
return false;
Foo foo = (Foo) o;
if (this.name.equalsIgnoreCase(foo.name))
return true;
return false;
}
}
主类
import java.util.*;
public class A{
public static void main(String[] args){
Map<Foo, String> map = new HashMap<>();
map.put(new Foo("Robert"), "USA");
map.put(new Foo("Daniel"), "UK");
map.put(new Foo("Ralf"), "Sweden");
map.remove(new Foo("Robert"));
System.out.println(map.size());
}
}
[输出为3,而在删除“ Robert”之后应为2。我知道在这种情况下可以使用String对象而不是Foo,但是我需要此特定示例才能将其应用于其他位置。
我也可以使用remove(Object K,Object V)吗?
谢谢,
来自Object.equals()
的Java API。
[注意,通常必须重写hashCode方法,以保持hashCode方法的常规约定,该约定规定相等的对象必须具有相等的哈希码。
因此,由于您正在使用字符串检查地图,因此您可以执行以下操作:
@Override
public int hashCode() {
return name != null ? name.toLowerCase().hashCode() : 0;
}
感谢@jferard
巧妙地指出equals替代会进行ignore case
比较。为了允许将name
转换为固定大小写(大写或小写),然后再返回hashCode。
请注意,其中包含单词hash的任何内容(例如HashSet,HashMap,LinkedHashSet等),以及其他一些类似命名的类,都需要此。
您错过了优先级hashCode
,例如在类Foo
中添加以下定义以获得所需的结果:
@Override
public int hashCode() {
return Objects.hash(name);
}
关于Java documentation方法,请参见Object#hashCode()
。它明确指出:
如果根据equals(Object)方法两个对象相等,则在两个对象中的每个对象上调用hashCode方法必须产生相同的整数结果
您需要与hashCode
一起覆盖equals
。 HashMap
同时使用这两者,并且默认情况下您会得到不同的结果,因为hashCode
是从Object
继承的(它使用对象的内部地址作为哈希码)。
在您的情况下,将执行以下操作:
@Override
public int hashCode() {
if (name == null) {
return 0;
}
return name.toLowerCase().hashCode();
}