使用equals()从地图中删除条目

问题描述 投票:0回答:3

我正在尝试从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)吗?

谢谢,

java dictionary hashmap tostring
3个回答
1
投票

来自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等),以及其他一些类似命名的类,都需要此。


-1
投票

您错过了优先级hashCode,例如在类Foo中添加以下定义以获得所需的结果:

@Override
public int hashCode() {
    return Objects.hash(name);
}   

-1
投票

关于Java documentation方法,请参见Object#hashCode()。它明确指出:

如果根据equals(Object)方法两个对象相等,则在两个对象中的每个对象上调用hashCode方法必须产生相同的整数结果

您需要与hashCode一起覆盖equalsHashMap同时使用这两者,并且默认情况下您会得到不同的结果,因为hashCode是从Object继承的(它使用对象的内部地址作为哈希码)。

在您的情况下,将执行以下操作:

@Override
public int hashCode() {
    if (name == null) {
        return 0;
    }
    return name.toLowerCase().hashCode();
}
© www.soinside.com 2019 - 2024. All rights reserved.