TreeSet总结
- TreeSet是依靠TreeMap来实现的,底层结构是“二叉树”的数据结构。
- TreeSet是一个有序集合,TreeSet中的元素将按照升序排列,缺省是按照自然排序进行排列,所有要存入到TreeSet中的集合元素必须首先具备可比较性,其类必须要实现“Compareble”接口的“compareTo()方法”。
- 如果元素不具备比较性,或者想按照自定义的方法去排序,也可以自定义的比较器,此时要实现“Comparetor接口中的”compare()方法。
- 我们可以在构造TreeSet对象时,传递实现Comparator接口的比较器对象。(
TreeSet(Comparator<? super E> comparator)构造一个新的空 TreeSet,它根据指定比较器进行排序。)
int compareTo(T o):o是要比较的对象,此方法返回的是一个int型,比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。值为”0,1,-1“。
import java.util.*; public class TreeSetTest { public static void main(String[] args) { Set ts = new TreeSet(); ts.add(new Teacher("zhangsan", 1)); // ts.add(new String("lisi")); ts.add(new Teacher("wangmazi", 3)); ts.add(new Teacher("mazi", 3)); ts.add(new Teacher("mazi", 0)); ts.add(new Teacher("mazi", 2)); Iterator it = ts.iterator(); while (it.hasNext()) { System.out.println(it.next()); } } } class Teacher implements Comparable { private int num; private String name; Teacher(){ } Teacher(String name, int num){ this.num = num; this.name = name; } public void setNum(int num){ this.num = num; } public int getNum(){ return num; } public void setName(String name){ this.name = name; } public String getName(){ return name; } public String toString() { return "老师" + this.num + ": "+ "姓名: " + this.name; } public int compareTo(Object o) { if(!(o instanceof Teacher)){ System.out.println("----------"); throw new RuntimeException("二者不具备比较性"); } //为安全起见,将要比较的对象强制转换成Teacher对象再进行比较: Teacher ss = (Teacher) o; //此处的规则是按照学号进行默认的自然排序,根据compareTo()方法的返回值看当前的对象的num和要比较的num //的大小关系来确定他的存放位置。 int result = num > ss.num ? 1 : (num == ss.num ? 0 : -1); //如果二个num相等,在主要条件不满足的情况下要比较次要条件,即,比较name的关系,因为name 是String类型。而String类实现了 //Comparable接口,则比较name中的字母顺序即可(如果在num相等的情况下不比较name的关系,则按照Set接口的规定就认为是同一个 //集合元素,则以后num相等的不Teacher对象就不会被存进集合,这显然合常理了: if (result == 0) { //此处调用String的compareTo()方法进行name的比较: result = name.compareTo(ss.name); } return result; } }
public int compareTo(Integer anotherInteger)如果该Integer等于Integer参数,则返回0值;如果该Integer在数字上小于Integer参数,则返回小于0的值;如果Integer在数字上大于Integer参数,则返回大于0的值(有符号的比较)。
int result = new Integer(this.num).compareTo(new Integer(ss.num));
if(result==0){
result = this.name.compareTo(ss.name);
}
return result;
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<E,Object>(comparator));
}
1.定义一个比较器类,该比较器类必须实现Comparator接口中的compare()方法:
class MyComparator implements Comparator{}
2.创建TreeSet集合时,传入一个自定义好的比较器对象:
TreeSet ts = new TreeSet(new MyComparator ());
import java.util.*; public class TreeSetTest1 { public static void main(String[] args) { //构建TreeSet时传入一个自定义的比较器: TreeSet ts = new TreeSet(new Teacher.TeacherCompare()); ts.add(new Teacher("zhangsan", 2)); ts.add(new Teacher("lisi", 1)); ts.add(new Teacher("wangmazi", 3)); ts.add(new Teacher("mazi", 3)); Iterator it = ts.iterator(); while (it.hasNext()) { System.out.println(it.next()); } } } class Teacher { private int num; private String name; Teacher(String name, int num) { this.num = num; this.name = name; } public String toString() { return "学号:" + num + " 姓名:" + name; } static class TeacherCompare implements Comparator {// 老师自带的一个比较器 public int compare(Object o1, Object o2) { if(!(o1 instanceof Teacher) || !(o2 instanceof Teacher)){ throw new RuntimeException("不具备比较性"); } Teacher s1 = (Teacher) o1;// 转型之后进行比较 Teacher s2 = (Teacher) o2;// 转型 int result = s1.num > s2.num ? 1 : (s1.num == s2.num ? 0 : -1); if (result == 0) { result = s1.name.compareTo(s2.name); } return result; } } }
对二叉树的理解:
给定的一个基准元素,要与之比较的元素若是大于基准元素则放在基准元素的右边,反之放在左边。依次类推:
如,对于一个存到二叉树结构的容器中的一个元素20,现要将[10,30,9,11,32,29]也存入其中,则要对后存入的元素与20进行比较,最终的二叉树结构如下图所示:(每次新加入的元素都首先与20进行比较,大于20的放在其右,如果其右已经有其它元素,则再跟这些元素比较,也是按照大于放右,小于放左的规则。而按照自然排序,最终取出的结果顺序是按红字标出的顺序)

对于TreeSet这种二叉树结构的集合来说,存放元素依靠compareTo()或者compare(),默认是自然排序,跟存入的顺序不一定相同。若是想用TreeSet来实现存取的顺序相同该怎么做呢? 其实理解了二叉树的结构就不难实现了,如果让所有的后存入的元素都位于第一个元素的右侧,也就是说存入时就强制其由小到大存入,结构如下:

怎么实现这种存入呢?只需compareTo()方法的返回值永远为一个正数即可,比如1:
public int compareTo(){
return 1;
}
这样的话,后来存入的元素要调用compareTo()去比较时,永远比前一个大。

浙公网安备 33010602011771号