TreeSet实现自动排序的原理

今天随手了一段代码关于通过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

TreeSet实现自动排序的原理的相关文章

Java基础知识强化之集合框架笔记47:Set集合之TreeSet保证元素唯一性和比较器排序的原理及代码实现(比较器排序)

1. TreeSet保证元素唯一性和比较器排序的原理及代码实现(比较器排序) (1)Student.java: 1 package cn.itcast_07; 2 3 public class Student { 4 private String name; 5 private int age; 6 7 public Student() { 8 super(); 9 } 10 11 public Student(String name, int age) { 12 super(); 13 thi

Java基础知识强化之集合框架笔记44:Set集合之TreeSet保证元素唯一性和自然排序的原理和图解

1. TreeSet保证元素唯一性和自然排序的原理和图解

Java SortedSet为什么可以实现自动排序?

Set中的SortedSet(SortedSet为TreeSet的实现接口),它们之间的继承关系如下: java.util.Set; java.util.SortedSet; java.util.TreeSet; SortedSet中的元素无序不可重复,但是存进去的元素可以按照元素大小顺序自动排序.结合以下代码来看: import java.util.*;import java.text.*;public class SortedSetTest01{ public static void mai

IOS数组自动排序

self.beacons = [beacons sortedArrayUsingComparator:^NSComparisonResult(BRTBeacon* obj1, BRTBeacon* obj2){ return obj1.distance.floatValue>obj2.distance.floatValue?NSOrderedDescending:NSOrderedAscending; }]; 数组的自动排序: 通过比较的方法进行   排序

使用CollectionViewSource,通过Xaml绑定自动排序

这个是一个完成分组和排序功能的Datagrid,同样只是简单的绑定到List集合,后台不用额外的代码,所有功能都在Xaml中完成: 首先在UI中定义CollectionViewSource资源,在这里定义排序和分组的规则 WPF中定义如下: 引入命名空间:xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase" <Window.Resources> <CollectionViewSourc

排序算法原理及实现

算法一:直接插入排序 算法实现原理:就是计算一个新元素是应该放在哪里?每次进来一个都会进行和原来顺序进行重新组合. 代码实现:Java public int[] testInsertionSort(int[] data){ // this methord is very easy. for(int i = 1;i < data.length;i++){ int temp = data[i]; int j =i; while(j>0 && data[j-1]>temp){

DBGrideh 实现自动排序

一.点击标题自动排序 1.在optioneh中设置:AutosortMarking:=True2.设置DbGridEh的属性:(不一定总要设置,与使用的数据连接有关)sortlocal:=True;3.uses 单元Ado------ehlibADoTclientData------ehlibCDSBDE ---------ehlibBDE EhLibUniDAC 4.Column属性 ColumDefValues->Title->TitleButton设为TRUE 二.+序列号

SpringMVC关于json、xml自动转换的原理研究[附带源码分析 --转

SpringMVC关于json.xml自动转换的原理研究[附带源码分析] 原文地址:http://www.cnblogs.com/fangjian0423/p/springMVC-xml-json-convert.html 目录 前言 现象 源码分析 实例讲解 关于配置 总结 参考资料 前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:http://www.cnblogs.com/fangjian0423/p/springMVC-in

SpringMVC关于json、xml自动转换的原理研究[附带源码分析]

本文讨论SpringMVC关于json.xml自动转换的原理. 实现这个功能只需要三个配置 1.springmvc配置文件 dispatcher-servlet.xml中的关键配置如下 <mvc:resources location="/static/" mapping="/static/**"/> <!-- 配置包扫描器 --> <context:component-scan base-package="com.winner