黑马程序员_java的集合三TreeSet_09

<a href="http://www.itheima.com" target="blank">android</a>

<a href="http://www.itheima.com" target="blank">java培训</a>期待与您交流

1.TreeSet是依靠TreeMap来实现的。

TreeSet是一个有序集合,TreeSet中的元素将按照升序排列,缺省是按照自然排序进行排列,意味着TreeSet中的元素要实现Comparable接口。或者有一个自定义的比较器。我们可以在构造TreeSet对象时,传递实现Comparator接口的比较器对象。

它可以给Set集合中的元素进行指定方式的排序。
保证元素唯一性的方式:通过比较的结果是否为0.底层数据结构是:二叉树。
排序的第一种方式
            让元素自身具备比较性。只要让元素实现Comparable接口,覆盖compareTo方法即可。
            但是,如果元素自身不具备比较性,或者元素自身具备的比较性,不是所需要的。
            比如,学生的自然排序是按年龄排序,现在想要按照学生姓名排序。还可以不改动原有代码。
            这时怎么办呢?

排序的第二种方式:自定比较器的方式。
            这时可以让集合自身具备比较性。
            可以定义一个类实现Comparator接口,覆盖compare方法。将该Comparator接口子类对象作为实际参数
            传递给TreeSet集合构造函数。
            该对象就是比较器。

2.什么是Comparable接口


此接口强行对实现它的每个类的对象进行整体排序。此排序被称为该类的自然排序 ,类的 compareTo 方法被称为它的自然比较方法 。实现此接口的对象列表(和数组)可以通过 Collections.sort (和 Arrays.sort )进行自动排序。实现此接口的对象可以用作有序映射表中的键或有序集合中的元素,无需指定比较器。 强烈推荐(虽然不是必需的)使自然排序与 equals 一致。所谓与equals一致是指对于类 C 的每一个 e1 和 e2 来说,当且仅当 (e1.compareTo((Object)e2) == 0) 与e1.equals((Object)e2) 具有相同的布尔值时,类 C 的自然排序才叫做与 equals 一致 。


3.实现什么方法
int compareTo(T o)比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。强烈推荐 (x.compareTo(y)==0) == (x.equals(y)) 这种做法,但不是 严格要求这样做。一般来说,任何实现 Comparable 接口和违背此条件的类都应该清楚地指出这一事实。推荐如此阐述:“注意:此类具有与 equals 不一致的自然排序。”
参数:         o - 要比较的对象。 
返回:        负整数、零或正整数,根据此对象是小于、等于还是大于指定对象。 
抛出:        ClassCastException - 如果指定对象的类型不允许它与此对象进行比较。


抛出异常是因为在TreeSet中是当前对象和集合的其他元素比较,从而实现了在集合中按照某一特性排序的特点,也就是每一个存进Treeset当中的对象必须要满足具有比较性,这样TreeSet才能给他们排序,这样描述该对象的类就实现这样的能被比较的规则。所以就回去implements Comparable接口的compTo()方法。这样达到了让被比较的对象自身具备比较性。(接口的功能本来就是对类的功能的扩展),TreeSet底层就是一个二叉树,根据定义的compartTo(),负数存到liftChildren,正数存到rightChildren,0则是本身来保证元素的唯一性。


4,示例
class Student implements Comparable{
private String name;
private int age;
Student(String name,int age){
this.name = name;
this.age = age;
}
public String getName(){
return this.name;
}
        //实现接口的方法,是底层自动调用的方法
public int comparTo(Object obj){
if(!(obj instanceof Student)){
throw new RunntimeException("不是Student对象");
}
Student s = (Student)obj;
if(this.age > s.age) return -1;
if(this.age == s.age) return 0;
return -1;
}
}
class MainTest{
TreeSet ts = new TreeSet();
ts.add( new Student("张三",20) );


// 如果不实现Comparable接口就会报ClsscastException,因为加入第二个对象的时候就会自动调用 //CompareTo()方法和已经加入的第一个对象比较。
ts.add( new Student("老梁",19));
Iterator it = ts.iterator();
while(it.hasnext() ){
Systm.out.println( it.next() );
}
}
5.与Comparator的区别
Comparator位于包java.util下,而Comparable位于包java.lang下,Comparable接口将比较代码嵌入自身类中,而后者在一个独立的类中实现比较。 如果类的设计师没有考虑到Compare的问题而没有实现Comparable接口,可以通过  Comparator来实现比较算法进行排序,并且为了使用不同的排序标准做准备,比如:升序、降序。也可以说当元素本身不具备比较性的时候,就需要让集合自身具备比较性,在集合初始化的时候就有了比较方式。


我们看一个Comparator的例子:
import java.util.TreeSet; 
import java.util.Comparator; 
class NumComparator implements Comparator<NameTag> { 
    public int compare (NameTag left,NameTag right) { 
        return(left.getNumber() - right.getNumber()); 
    } 

public class CollectionNine { 
    public static void main(String arg[]) { 
        new CollectionNine(); 
    } 
    CollectionNine() { 
        NumComparator comparator = new NumComparator(); 
        TreeSet<NameTag> set = new TreeSet<NameTag>(comparator); 
        set.add(new NameTag("Agamemnon",300)); 
        set.add(new NameTag("Cato",400)); 
        set.add(new NameTag("Plato",100)); 
        set.add(new NameTag("Zeno",200)); 
        set.add(new NameTag("Archimedes",500)); 
        for(NameTag tag : set) 
            System.out.println(tag); 
    } 
}

----------------------- android培训java培训、java学习型技术博客、期待与您交流! ----------------------

详情请查看:http://edu.csdn.net/heima

你可能感兴趣的:(黑马程序员_java的集合三TreeSet_09)