TreeSet实现自动排序的原理(二)

2014-11-24 13:28:31 · 作者: · 浏览: 55
()) { Student student = (Student) is.next(); bw.write(student.toString()); bw.newLine(); bw.flush(); } bw.close(); } } class Student implements Comparable { private String name; private int cn; private int math; private int en; private int sum; public Student(String name, int... is) { this.name = name; this.cn = is[0]; this.math = is[1]; this.en = is[2]; this.sum = cn + math + en; } @Override public String toString() { return "【name=" + name + "\tcn=" + cn + "\tmath=" + math + "\ten=" + en + "\tsum=" + sum + "】"; } @Override public boolean equals(Object obj) { if (!(obj instanceof Student)) throw new ClassCastException("不能强制的转换"); Student s = (Student) obj; return s.name.equals(this.name) && s.sum == s.sum; } public int compareTo(Student o) { int sum = new Integer(this.sum).compareTo(new Integer(o.sum)); if (sum == 0) return this.name.compareTo(o.name); return sum; } @Override public int hashCode() { return sum * 78 + name.hashCode(); } } class StudentTools { public static Set getStudent() throws IOException { return getStudent(null); } public static Set getStudent(Comparator com) throws IOException { Set studentSet = null; if (com == null) studentSet = new TreeSet (); else studentSet = new TreeSet (com); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String len = ""; while ((len = br.readLine()) != null) { if (len.equals("over")) break; String[] studentInfo = len.split(","); Student s = new Student(studentInfo[0], new int[] { Integer.parseInt(studentInfo[1]), Integer.parseInt(studentInfo[2]), Integer.parseInt(studentInfo[3]) });
// 当往HashSet中添加数据时,他会去找被添加对象的中实现了Comparable接口,
			studentSet.add(s);
		}
		return studentSet;

	}
}

 通过上面的两段代码把这个执行的流程给大家讲解一下: 
           

第一步:从控制台接收数值后封装到了一个student对象当中去。

其实在treeSet内部其实封装了一个TreeMap对象

当你调用了ADD方法时其实是调用了put方法。

 
while ((len = br.readLine()) != null) {
			if (len.equals("over"))
				break;
			String[] studentInfo = len.split(",");

			Student s = new Student(studentInfo[0], new int[] {
					Integer.parseInt(studentInfo[1]),
					Integer.parseInt(studentInfo[2]),
					Integer.parseInt(studentInfo[3]) });			
              // 当往HashSet中添加数据时,他会去找被添加对象的中实现了Comparable接口,
			studentSet.add(s);
		}
		return studentSet;



public TreeSet(Comparator
               comparator) { this(new TreeMap<>(comparator)); }






第二步:首先他要进行检查。

这个三目运算符是这个意思:

首先他是判断你在new treeset时候是否向其中传递了一个 comparator

对象,假如传递了那么直接调用你传进来的那个对象

但是你没有传递进来那么他就要做类型检查了,

检查的目的在与看你是否实现了Comparable假如实现了那么就调用你自身的实现接口的方法

public V put(K key, V value) {
        Entry
               
                 t = root;
        if (t == null) {
            compare(key, key); // type (and possibly null) check(L类型检查)

            root = new Entry<>(key, value, null);
            size = 1;
            modCount++;
            return null;
        }


//其实在第一次存储对象时,所进行的比较是和自身比较 compare(key, key)
final int compare(Object k1, Object k2) {
     return comparator==null   ((Comparable
                )k1).compareTo((K)k2) : comparator.compare((K)k1, (K)k2); } 
               




第三步: 当检查到你是实现了compare接口或是传递了一个compator对象时,

他会调用你自身的实现方法进行比较。

通过返回值:-1,0,1来判断你正要假如的值和treeset中的大小进行自动的排序的效果。