今天基友在学习集合类的时候,问了一些关于compareTo方法的问题,整理如下:
首先我们看代码:
package tv.zhangjia.tv; import java.util.*; public class Student implements Comparable <Student> { String name; int age; public Student(int age, String name) { this.name = name; this.age = age; } public int compareTo(Student a){ if(this.age < a.age) { return -1; } else if(this.age > a.age) { return 1; } else { return 0; } } public String toString() { return " " + this.name + " " + this.age; } public static void main (String[] args) { Student[] s = new Student[] { new Student(18,"李") , new Student(10,"王"), new Student(6,"田"), new Student(20,"张") }; Set<Student> ts = new TreeSet<Student>(); for(int i = 0; i < s.length; i++) ts.add(s[i]); System.out.println(ts); } } 输出: [ 田 6, 王 10, 李 18, 张 20]
可以看到,这段代码实现了Comparable接口,也实现Comparable接口中的compareTo()方法,但是在这个程序中没有看对象调用compareTo()方法,那么compareTo方法是如何被调用的呢:
TreeSet类的底层实现其实是TreeMap(虽然 TreeMap 和TreeSet 实现的接口规范不同,但 TreeSet 底层是通过 TreeMap 来实现的)在每次add的时候,也就是调用TreeMap的put方法这时,如果有外部比较器Comparator的实现就会调用外部的Comparator的比较方法,如果没有就会调用实现Comparable接口的类的compareTo方法
我们来看一下Treeset的add()方法的源码:
public boolean add(E e) { return m.put(e, PRESENT)==null; }
其中,m是TreeMap的一个实例,再看一下TreeMap中的put方法源码
public V put(K key, V value) { Entry<K,V> t = root; if (t == null) { // TBD: // 5045147: (coll) Adding null to an empty TreeSet should // throw NullPointerException // // compare(key, key); // type check root = new Entry<K,V>(key, value, null); size = 1; modCount++; return null; } int cmp; Entry<K,V> parent; // split comparator and comparable paths Comparator<? super K> cpr = comparator; if (cpr != null) { do { parent = t; cmp = cpr.compare(key, t.key); if (cmp < 0) t = t.left; else if (cmp > 0) t = t.right; else return t.setValue(value); } while (t != null); } else { if (key == null) throw new NullPointerException(); Comparable<? super K> k = (Comparable<? super K>) key; do { parent = t; cmp = k.compareTo(t.key); if (cmp < 0) t = t.left; else if (cmp > 0) t = t.right; else return t.setValue(value); } while (t != null); } Entry<K,V> e = new Entry<K,V>(key, value, parent); if (cmp < 0) parent.left = e; else parent.right = e; fixAfterInsertion(e); size++; modCount++; return null; }
其中Comparable<? super K> k = (Comparable<? super K>) key;
作用为:K类型的实例要实现Comparable接口
在cmp = k.compareTo(t.key);
作用为:调用自己实现的compareTo()方法,
请登录之后再进行评论