今天随手了一段代码关于通过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<Student> ss = StudentTools.getStudent(); Iterator<Student> 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<Student> com = new Comparator<Student>() { @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<Student> getStudent() throws IOException { return getStudent(com); } public static Set<Student> getStudent(Comparator<Student> com) throws IOException { Set<Student> studentSet = null; if (com == null) studentSet = new TreeSet<Student>(); else studentSet = new TreeSet<Student>(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<Student> ss = StudentTools.getStudent(); Iterator<Student> 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<Student> { 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<Student> getStudent() throws IOException { return getStudent(null); } public static Set<Student> getStudent(Comparator<Student> com) throws IOException { Set<Student> studentSet = null; if (com == null) studentSet = new TreeSet<Student>(); else studentSet = new TreeSet<Student>(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]) }); <pre name="code" class="java">// 当往HashSet中添加数据时,他会去找被添加对象的中实现了Comparable接口, studentSet.add(s); } return studentSet; } }
通过上面的两段代码把这个执行的流程给大家讲解一下:
第一步:从控制台接收数值后封装到了一个student对象当中去。
其实在treeSet内部其实封装了一个TreeMap对象
当你调用了ADD方法时其实是调用了put方法。
<pre name="code" class="java">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]) }); <pre name="code" class="java"> // 当往HashSet中添加数据时,他会去找被添加对象的中实现了Comparable接口, studentSet.add(s); } return studentSet; public TreeSet(Comparator<? super E> comparator) { this(new TreeMap<>(comparator)); }
第二步:首先他要进行检查。
这个三目运算符是这个意思:
首先他是判断你在new treeset时候是否向其中传递了一个 comparator
对象,假如传递了那么直接调用你传进来的那个对象
但是你没有传递进来那么他就要做类型检查了,
检查的目的在与看你是否实现了Comparable假如实现了那么就调用你自身的实现接口的方法
<strong></strong><pre name="code" class="java">public V put(K key, V value) { Entry<K,V> 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中的大小进行自动的排序的效果。
TreeSet实现自动排序的原理
时间: 2024-12-18 23:33:59