首页 > 代码库 > TreeSet有趣问题之add方法原理
TreeSet有趣问题之add方法原理
先看如下代码
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方法.
TreeSet有趣问题之add方法原理
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。