Set接口中的TreeSet

来源:互联网 发布:linux 查看压缩包格式 编辑:程序博客网 时间:2024/05/17 07:44
     TreeSet也是Set的一个子类,它同样是拥有Collection接口的所有方法,TreeSet类主要有以下几个特点:
1:TreeSet类中所存储的元素必须是属于同一个类的
2:TreeSet类可以按照所添加进如集合的元素的指定的顺序进行遍历。比如按字典的排序顺序遍历。
     我们先来看一个例子:
import java.util.Set;
import java.util.TreeSet;
import org.junit.Test;
public class TestTreeSet {
@Test
        public void TreeSetTest1(){
       Set A = new TreeSet ();
        A.add("CC" );
        A.add("AA" );
        A.add("RR" );
        A.add("FF" );
        for(Object each : A )
       {
              System. out.println(each );
       }
}
}//输出结果如下:
AA
CC
FF
RR
     从上面的例子我们可以看到String类型的对象在TreeSet中默认遍历顺序是按照字典顺序排序的
3:在向TreeSet中添加自定义类的对象时,可以选择两种排序方法:
     ①自然排序:自然排序是按照字典中的位置进行排序的,它要求自定义的类中实现Comparable接口并重写其中的compareT(Object e)方法,并在此方法中指明按照自定义类中的哪个属性进行遍历。还要必须去重写equals(Object Obj)方法和hashCode()方法。来看个例子
import java.util.Set;
import java.util.TreeSet;
import org.junit.Test;
public class TestTreeSet {
@Test
        public void TreeSetTest1(){
       Set A = new TreeSet ();
        A.add(new Man("帅哥",18));
        A.add(new Man("美女",16));
        A.add(new Man("孩子",9));
        A.add(new Man("MM",18)) ;
        for(Object each : A )
       {
              System. out.println(each );
       }
}
}
class Man implements Comparable{
        private String name ;
        private Integer age 
        public Man(String name , Integer age) {
               super();
               this.name = name ;
               this.age = age ;
       }
       
        public Man() {
               super();
       }

        @Override
        public int hashCode() {
               final int prime = 31;
               int result = 1;
               result = prime * result + (( age == null) ? 0 : age .hashCode());
               result = prime * result + (( name == null) ? 0 : name .hashCode());
               return result ;
       }
        @Override
        public boolean equals(Object obj) {
               if (this == obj )
                      return true ;
               if (obj == null)
                      return false ;
               if (getClass() != obj .getClass())
                      return false ;
              Man other = (Man) obj;
               if (age == null) {
                      if (other .age != null)
                            return false ;
              } else if (!age .equals(other .age ))
                      return false ;
               if (name == null) {
                      if (other .name != null)
                            return false ;
              } else if (!name .equals(other .name ))
                      return false ;
               return true ;
       }

        @Override
        public String toString() {
               return "Man [name=" + name + ", age=" + age + "]" ;
       }

        @Override
        public int compareTo(Object e) {
               if(e instanceof Man){
                     Man P = (Man) e;
                      return this .age .compareTo(P.age);
              }
               return 0;
              }     
}//运行结果
Man [name=孩子, age=9]
Man [name=美女, age=16]
Man [name=帅哥, age=18]
     显然我们可以看到,明明传入了4个不同内容的Man对象,却只存入了3个,那是因为他们的age值相同,所以我们就要修改compareTo(Object e)方法了
     这里先说明以下原来的compareTo(Object e)方法是干什么的,是按照字典顺序比较两个字符串,如果当前字符串排在参数字符串之前,则返回一个负整数,反之返回正整数,相同则返回0.
     TreeSet中添加元素的时候,首先是按照compareTo()方法进行比较,若两个对象的属性值相同,则返回0,虽然他们的地址不相同,但是程序会认为这两个对象是相同的,就像我们上面写的一样,优于age相同了,导致了程序认为他们是相同的,所以这里我们需要添加一些语句,具体实现如下
        public int compareTo(Object e) {
               if(e instanceof Man){
                     Man P = (Man) e;
                      int i = this.age.compareTo( P. age);
                      if(i == 0)
                     {
                            return this .name .compareTo(P.name);//如果年龄相同的话就比较名字是否相同并返回值
                     } else{
                            return i ;
                     }
              }
               return 0;
       }//运行结果
Man [name=孩子, age=9]
Man [name=美女, age=16]
Man [name=MM, age=18]
Man [name=帅哥, age=18]
     像这样,程序就能放心的存入啦
     ②定制排序
对于定制排序它要求自定义的类中实现Comparator接口(注意不是Comparable)并且重写compare(Object e1,Object e2)方法,当然也要重写equals(Object e1)方法,hashCode()方法,他们三个要保持一侄,具体的实现步骤为:
1:创建一个Comparator类的对象,并根据自己的需求去重写compare(Object e1,Object e2)方法
2:然后将此对象作为形参传递给TreeSet的构造器中
3:向TreeSet中添加在compare方法中设计到的类的对象
具体实现方法如下
import java.util.Comparator;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
import org.junit.Test;\
public class TestTreeSetCompare {
@Test
        public void TestTree2 (){
        Comparator A new Comparator (){

               @Override
               public int compare(Object e1, Object e2) {
                      if (e1 instanceof Student && e2 instanceof Student)
                     {
                           Student P1 = (Student) e1;
                           Student P2 = (Student) e2;
                            int i P1 .getId().compareTo( P2.getId());
                            if (i == 0)
                           {
                                   return P1 .getName().compareTo( P2.getName());
                           }
                            return i ;
                     }
                      return 0;
              }      
       };
        Set B new TreeSet( A);
        B .add(new Student( "张三" ,1000));
        B .add(new Student( "李四" ,1004));
        B .add(new Student( "王五" ,1007));
        B .add(new Student( "赵六" ,1002));
        B .add(new Student( "吴三" ,1100));
        Iterator iterator B .iterator();
        while (iterator .hasNext())
       {
              System. out .println(iterator .next());
       }
}
}
class Student{
        private String name ;
        private Integer id ;
        public Student(String name , Integer id) {
               super ();
               this .name name ;
               this .id id ;
       }
        public Student() {
               super ();
       }
        @Override
        public int hashCode() {
               final int prime = 31;
               int result = 1;
               result = prime * result + (( id == null ) ? 0 : id .hashCode());
               result = prime * result + (( name == null ) ? 0 : name .hashCode());
               return result ;
       }
        @Override
        public boolean equals(Object obj) {
               if (this == obj )
                      return true ;
               if (obj == null)
                      return false ;
               if (getClass() != obj .getClass())
                      return false ;
              Student other = (Student) obj;
               if (id == null) {
                      if (other .id != null)
                            return false ;
              } else if (!id .equals(other .id ))
                      return false ;
               if (name == null) {
                      if (other .name != null)
                            return false ;
              } else if (!name .equals(other .name ))
                      return false ;
               return true ;
       }
        @Override
        public String toString() {
               return "Student [name=" name ", id=" id "]" ;
       }
        public String getName() {
               return name ;
       }
        public Integer getId() {
               return id ;
       }
       
}
     感觉代码有点多了,那是因为我们重写了很方法,其实这些重写的方法和前几个例子中没什么区别,大家可以忽略了他们,在这里我们主要就是看这个Comparator接口中的compare(Object e1,Object e2)是如何实现的,先实现创建了一个Comparator类的对象,然后利用匿名类去进一步重写其中的compare(Object e1,Object e2)方法,最后将它作为参数传入TreeSet集合中,然后添加了对象之后就可以利用迭代器遍历啦。

原创粉丝点击