今天隨手了一段代碼關於通過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 super E> 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 super K>)k1).compareTo((K)k2) : comparator.compare((K)k1, (K)k2); }
第三步: 當檢查到你是實現了compare接口或是傳遞了一個compator對象時,
他會調用你自身的實現方法進行比較。
通過返回值:-1,0,1來判斷你正要假如的值和treeset中的大小進行自動的排序的效果。