我们知道HashMap的存储位置是按照key这个对象的hashCode来存放的,而TreeMap则是不是按照hashCode来存放,他是按照实现的Comparable接口的compareTo这个方法来存储的,只要compareTo的返回结果为0就表示两个对象相等,那么就存不进去两个对象,后put的就把前面的覆盖掉,甚至我们都不用重写equasls和hashCode方法,而只需要实现Comparable接口来重写comparareTo方法就行了,但是我们不能保证在应用中不会用到HashMap,所以保持良好的习惯,当我们定义了一个对象之后习惯性的重写equals和hashCode方法。
测试Comparable接口:
第一次比较:定义一个User类,实现Comparable接口,按照年龄排序,我们让equals为true,而hashCode也始终相等。
复制代码
public class User implements Comparable<User> {
private String id;
private String name;
private Integer age;
public User() {
}
public User(String id, String name, Integer age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + "]";
}
@Override
public boolean equals(Object obj) {
return true;
}
@Override
public int hashCode() {
return 0;
}
public int compareTo(User o) {
return this.age > o.getAge() ? 1 : this.age == o.getAge() ? 0 : -1;
}
}
复制代码
测试代码:
复制代码
public class TestUser {
public static void main(String[] args) {
Map<User, Integer> userHashMap = new HashMap<User, Integer>();
User user1 = new User("1", "Jay", 30);
User user2 = new User("2", "Jolin", 21);
User user3 = new User("3", "Jack Cheng", 22);
User user4 = new User("4", "Bruce Lee", 22);
userHashMap.put(user1, 100);
userHashMap.put(user2, 200);
userHashMap.put(user3, 300);
userHashMap.put(user4, 400);
System.out.println(userHashMap);
Map<User, Integer> userTreeMap = new TreeMap<User, Integer>();
userTreeMap.put(user1, 100);
userTreeMap.put(user2, 200);
userTreeMap.put(user3, 300);
userTreeMap.put(user4, 400);
System.out.println(userTreeMap);
}
}
复制代码
结果:
{User [name=Jay, age=30]=400}
{User [name=Jolin, age=21]=200, User [name=Jack Cheng, age=22]=400, User [name=Jay, age=30]=100}
结论:对于HashMap而言,只要key的equals相等就表示两个元素相等,HashMap就存不进去;而TreeMap是不管equals和hashCode的,只要compareTo相等就表示两个元素相同,就存不进去。
2.第二次比较:现在我们按照id来重写hashCode和equals方法,如下:
复制代码
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.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 (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
复制代码
测试代码不变,还是上面的测试代码,结果:
{User [name=Jolin, age=21]=200, User [name=Jay, age=30]=100, User [name=Bruce Lee, age=22]=400, User [name=Jack Cheng, age=22]=300}
{User [name=Jolin, age=21]=200, User [name=Jack Cheng, age=22]=400, User [name=Jay, age=30]=100}
说明:HashMap只要equals不等那就表示不等,而对于TreeMap如果compareTo相等,那么2个元素就相等,并且排序是按照compareTo方法定义的排序规则。
接下来再在测试代码里面添加List测试:
复制代码
List<User> userList = new ArrayList<User>();
userList.add(user1);
userList.add(user2);
userList.add(user3);
userList.add(user4);
System.out.println(userList);
Collections.sort(userList);
System.out.println(userList);
复制代码
结果:
{User [name=Jolin, age=21]=200, User [name=Jay, age=30]=100, User [name=Bruce Lee, age=22]=400, User [name=Jack Cheng, age=22]=300}
{User [name=Jolin, age=21]=200, User [name=Jack Cheng, age=22]=400, User [name=Jay, age=30]=100}
[User [name=Jay, age=30], User [name=Jolin, age=21], User [name=Jack Cheng, age=22], User [name=Bruce Lee, age=22]]
[User [name=Jolin, age=21], User [name=Jack Cheng, age=22], User [name=Bruce Lee, age=22], User [name=Jay, age=30]]
当调用sort方法之后List里面的元素就按照age排序了。