• 中文
    • English
  • 注册
  • 查看作者
    • 关于Java中compareTo方法的一些问题

      今天基友在学习集合类的时候,问了一些关于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()方法,

      参考资料:

      inuyasha1的CSDN提问

    • 0
    • 0
    • 0
    • 3.6k
    • 请登录之后再进行评论

      登录

      赞助本站

      • 支付宝
      • 微信
      • QQ

      感谢一直支持本站的所有人!

      单栏布局 侧栏位置: