先看如下代码
class Worker implements Comparable<Worker> {
private int age;
private String name;
public Worker(int age, String name) {
this.setAge(age);
this.setName(name);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.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;
Worker other = (Worker) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public int compareTo(Worker worker) {
return new Integer(getAge()).compareTo(new Integer(worker.getAge()));
}
...//setter/getter方法
}
public static void main(String[] args) {
<span style="white-space:pre"> </span>TreeSet<Worker> set = new TreeSet<Worker>();
set.add(new Worker(21, "测试人员1"));
set.add(new Worker(22,"测试人员2"));
set.add(new Worker(21, "测试人员3"));
System.out.println(set.size());
}
输出的结果是几呢?
按照写代码者的原意应该是想set里面有三个worker,按照年龄排序的.
可是执行出来的结果却是2,再细查看会发现测试人员1没有了,只有2和3.
这是为什么呢?查看源代码,发现TreeSet的add方法定义如下:
public boolean add(E paramE)
{
return this.m.put(paramE, PRESENT) == null;
}
其中this.m为TreeMap,其put方法定义如下:
public V put(K paramK, V paramV)
{
Entry localEntry1 = this.root;
if (localEntry1 == null)
{
compare(paramK, paramK);
this.root = new Entry(paramK, paramV, null);
this.size = 1;
this.modCount += 1;
return null;
}
Comparator localComparator = this.comparator;
Entry localEntry2;
int i;
if (localComparator != null)
{
do
{
<span style="color:#ff0000;">localEntry2 = localEntry1;
i = localComparator.compare(paramK, localEntry1.key);
if (i < 0) {
localEntry1 = localEntry1.left;
} else if (i > 0) {
localEntry1 = localEntry1.right;
} else {
return localEntry1.setValue(paramV);
}</span>
} while (localEntry1 != null);
}
else
{
if (paramK == null) {
throw new NullPointerException();
}
localObject = (Comparable)paramK;
do
{
<span style="color:#ff0000;">localEntry2 = localEntry1;
i = ((Comparable)localObject).compareTo(localEntry1.key);
if (i < 0) {
localEntry1 = localEntry1.left;
} else if (i > 0) {
localEntry1 = localEntry1.right;
} else {
return localEntry1.setValue(paramV);
}</span>
} while (localEntry1 != null);
}
Object localObject = new Entry(paramK, paramV, localEntry2);
if (i < 0) {
localEntry2.left = ((Entry)localObject);
} else {
localEntry2.right = ((Entry)localObject);
}
fixAfterInsertion((Entry)localObject);
this.size += 1;
this.modCount += 1;
return null;
}
如上红色代码,原来在TreeSet的add方法中根本就没有使用equals方法来判断两个元素是否相等,而是直接使用
compareTo方法来确定添加元素在集合中的位置.
若要实现我们想要的结果,Worker中的compareTo方法应该做修改为
@Override
public int compareTo(Worker worker) {
int index = getName().compareTo(worker.getName());
if(index != 0){
index = new Integer(getAge()).compareTo(new Integer(worker.getAge()));
}
return index;
}
如此就能得到我们想要的结果了
结论:TreeSet中确定集合中两元素相等不是使用equals方法,而是使用compareTo方法.