import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * HashMap问题 * @author 15735400536 * 使用HashMap,如果key是自定义的类,就必须重写hashcode()和equals() * 使用ArrayList,如果元素是自定义的类,要做相等判断,就必须重写hashCode()和equals() */ public class HashMapTest { public static void main(String[] args) { Map<User,Doc> hashMap = new HashMap<User,Doc>(); hashMap.put(new User("mxh","mxh"), new Doc("mxh","mxh")); hashMap.put(new User("root","root"), new Doc("root","root")); hashMap.put(new User("admin","admin"), new Doc("admin","admin")); //再不重写hashCode方法和equals方法的情况下get()方法拿到的结果为null //原因: new一个新的对象时,地址变了,不能保证hash值和equals结果还是一样。所以取不到对应的value。 Object object = hashMap.get(new User("admin","admin")); System.out.println(object); List<Doc> list = new ArrayList<Doc>(); list.add(new Doc("三国演义","罗贯中")); list.add(new Doc("红楼梦","曹雪芹")); list.add(new Doc("水浒传","施耐庵")); list.add(new Doc("西游记","吴承恩")); //Doc类未重写hashCode()和equals()方法前,结果为false boolean result = list.contains(new Doc("水浒传","施耐庵")); System.out.println("list集合是否存在该元素: " + result); } } /** * 用户 * @author 15735400536 * */ class User { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public User(String username, String password) { super(); this.username = username; this.password = password; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((password == null) ? 0 : password.hashCode()); result = prime * result + ((username == null) ? 0 : username.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; User other = (User) obj; if (password == null) { if (other.password != null) return false; } else if (!password.equals(other.password)) return false; if (username == null) { if (other.username != null) return false; } else if (!username.equals(other.username)) return false; return true; } } /** * 文档 * @author 15735400536 * */ class Doc { private String title; private String content; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public Doc(String title, String content) { super(); this.title = title; this.content = content; } @Override public String toString() { return "Doc [title=" + title + ", content=" + content + "]"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((content == null) ? 0 : content.hashCode()); result = prime * result + ((title == null) ? 0 : title.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Doc other = (Doc) obj; if (content == null) { if (other.content != null) return false; } else if (!content.equals(other.content)) return false; if (title == null) { if (other.title != null) return false; } else if (!title.equals(other.title)) return false; return true; } }
1.hashcode()和equals()是在哪里被用到的?什么用的?
HashMap是基于散列函数,以数组和链表的方式实现的。而对于每一个对象,通过其hashCode()方法可为其生成一个整形值(散列码),该整型值被处理后,将会作为数组下标,存放该对象所对应的Entry(存放该对象及其对应值)。equals()方法则是在HashMap中插入值或查询时会使用到。当HashMap中插入 值或查询值对应的散列码与数组中的散列码相等时,则会通过equals方法比较key值是否相等,所以想以自建对象作为HashMap的key,必须重写 该对象继承object的equals方法。
2.本来不就有hashcode()和equals()了么?干嘛要重写,直接用原来的不行么?
HashMap中,如果要比较key是否相等,要同时使用这两个函数!因为自定义的类的hashcode()方法继承于Object类,其hashcode码为默认的内存地址,这样即便有相同含义的两个对象,比较也是不相等的。
Doc doc1 = new Doc("三国演义","罗贯中"); Doc doc2 = new Doc("三国演义","罗贯中");
正常理解这两个对象存入到hashMap中应该是相等的,但如果你不重写 hashcode()方法的话,比较是其地址,不相等!
HashMap中的比较key是这样的,先求出key的hashcode(),比较其值是否相等,若相等再比较equals(),若相等则认为他们是相等 的。若equals()不相等则认为他们不相等。如果只重写hashcode()不重写equals()方法,当比较equals()时只是看他们是否为 同一对象(即进行内存地址的比较),所以必定要两个方法一起重写。HashMap用来判断key是否相等的方法,其实是调用了HashSet判断加入元素 是否相等。
原文地址:https://www.cnblogs.com/mxh-java/p/11048700.html