程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> TreeSet實現自動排序的原理

TreeSet實現自動排序的原理

編輯:C++入門知識

今天隨手了一段代碼關於通過treeSet實現自動排序的功能,自己折騰了好久。

始終是存在這一些疑惑,後來和同學的交流和調試可以解釋自動排序的基本原理:

通過可以通過兩種方式實現自動排序:

一種:

package xyxysjxy.io;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

public class StudentInfoImport {

	public static void main(String[] args) throws IOException {
		BufferedWriter bw = new BufferedWriter(
				new FileWriter("f:\\student.txt"));
		Set ss = StudentTools.getStudent();
		Iterator is = ss.iterator();
		while (is.hasNext()) {
			Student student = (Student) is.next();
			bw.write(student.toString());
			bw.newLine();
			bw.flush();
		}
		bw.close();
	}

}

class Student{
	private String name;
	private int cn;
	private int math;
	private int en;
	private int sum;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getCn() {
		return cn;
	}

	public void setCn(int cn) {
		this.cn = cn;
	}

	public int getMath() {
		return math;
	}

	public void setMath(int math) {
		this.math = math;
	}

	public int getEn() {
		return en;
	}

	public void setEn(int en) {
		this.en = en;
	}

	public int getSum() {
		return sum;
	}

	public void setSum(int sum) {
		this.sum = 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;
	}

	@Override
	public int hashCode() {
		return sum * 78 + name.hashCode();
	}

}

class StudentTools {
	static Comparator com = new Comparator() {

		@Override
		public int compare(Student o1, Student o2) {
			int sum = new Integer(o1.getSum()).compareTo(new Integer(o2.getSum()));
			if (sum == 0)
				return o1.getName().compareTo(o2.getName());
			return sum;
		}
		
	};

	public static Set getStudent() throws IOException {
		return getStudent(com);
	}

	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;

	}
}

二種:

package xyxysjxy.io;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

public class StudentInfoImport {

	public static void main(String[] args) throws IOException {
		BufferedWriter bw = new BufferedWriter(
				new FileWriter("f:\\student.txt"));
		Set ss = StudentTools.getStudent();
		Iterator is = ss.iterator();
		while (is.hasNext()) {
			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中的大小進行自動的排序的效果。







  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved