HashMap未返回全部值问题求助:自定义类作为键的使用异常
解决HashMap使用自定义类作为Key的问题
嘿,我看你在把Zoo作为HashMap的Key关联Animals时遇到了麻烦,这其实是自定义类作为HashMap Key的常见坑,我帮你拆解下问题和解决方案:
1. 先解决方法里的变量名冲突
你写的setAnimal方法里,参数名zoo和成员变量的HashMap同名了!直接写zoo.put(zoo, animal)其实是在操作参数里的Zoo对象(根本不是你的HashMap),这会导致编译错误或者完全没往Map里存数据。得用this.zoo明确指向成员变量:
public void setAnimal(Zoo zoo, Animals animal ){ this.zoo.put(zoo, animal); // 用this区分成员变量和参数 }
2. 核心问题:自定义Key必须重写equals和hashCode
这是最关键的点——HashMap判断两个Key是否相等,靠的是hashCode确定存储位置+equals确认内容一致。默认情况下,Object类的equals是比较对象的内存地址,hashCode返回的也是内存地址值。这意味着哪怕两个Zoo对象的国家、编号完全一样,只要是new出来的不同对象,HashMap就会把它们当成两个不同的Key。
所以必须在Zoo类里重写这两个方法,基于你的核心属性(比如country和id)来实现:
import java.util.Objects; public class Zoo { private String country; private int id; // 构造方法 public Zoo(String country, int id) { this.country = country; this.id = id; } // 重写equals:比较核心属性是否一致 @Override public boolean equals(Object o) { if (this == o) return true; // 同一对象直接返回true if (o == null || getClass() != o.getClass()) return false; // 类型不同直接false Zoo zoo = (Zoo) o; // 比较id和country(用Objects.equals避免空指针) return id == zoo.id && Objects.equals(country, zoo.country); } // 重写hashCode:基于核心属性生成哈希值 @Override public int hashCode() { return Objects.hash(country, id); } // 可选:添加getter方便后续操作 public String getCountry() { return country; } public int getId() { return id; } }
3. 测试验证修改效果
修改后,你可以这样测试是否能正确存储和获取数据:
public class Main { private HashMap<Zoo, Animals> zooMap; public Main() { zooMap = new HashMap<>(); } public void setAnimal(Zoo zoo, Animals animal ){ zooMap.put(zoo, animal); } public Animals getAnimal(Zoo zoo) { return zooMap.get(zoo); } public static void main(String[] args) { Main main = new Main(); Zoo zoo1 = new Zoo("France", 1); Zoo zoo2 = new Zoo("Spain", 2); Zoo zoo1Clone = new Zoo("France", 1); // 和zoo1属性完全一致的新对象 Animals gorilla = new Animals(2015, "Gorilla"); Animals lion = new Animals(2018, "Lion"); main.setAnimal(zoo1, gorilla); main.setAnimal(zoo2, lion); // 现在用zoo1Clone也能拿到gorilla,因为equals和hashCode匹配了 System.out.println(main.getAnimal(zoo1Clone).getName()); // 输出Gorilla } } // 补充Animals类示例 class Animals { private int birthYear; private String name; public Animals(int birthYear, String name) { this.birthYear = birthYear; this.name = name; } public String getName() { return name; } }
总结一下:
- 用
this解决成员变量和参数的命名冲突 - 自定义Key类必须重写
equals和hashCode,确保属性相同的对象被视为同一个Key - 优先用
Objects工具类实现这两个方法,避免空指针异常
内容的提问来源于stack exchange,提问作者Banha Dix
相关产品推荐
相关产品推荐

