(十)Core Java 集合框架TreeSet与泛型 -02 (102)

1 ) . 集合框架(TreeSet)

2 ) .  集合框架(TreeSet存储自定义对象)

3 ) .   集合框架(二叉树)

4 ) .  集合框架(实现Comparator方式排序)

5 ) .  集合框架(TreeSet练习)

6 ) .  集合框架(泛型概述)

7 ) .   集合框架(泛型使用)

8 ) .  集合框架(泛型类)

9 ).  集合框架(泛型方法)

10 ). 集合框架(静态方法泛型)

11 ). 集合框架(泛型接口)

12 ).集合框架(泛型限定)

13 ). 集合框架(泛型限定 2)

 


     一 .  集合框架(TreeSet)

1 ) TreeSet -->最大的特点就是依靠ASCII码表,对set中的元素进行自然排序

2 ) . Demo :

 
 import java.util.*;
 
 
 /*
  set -->元素是无序(存入和取出的顺序不一定一致),元素不可重复
   -HashSet : 底层元素结构是哈希表
       保证元素唯一性的原理是:  判断元素的hashCode的值是否相同,若相同再通过equlas判断
   -treeSet : 可以对set集合中的元素进行排序
  
  
 */
 
 
 
  class TreeSetDemo
  {
        
       
          
             //输出方法
             public static void sop(Object obj)
             {
                    
                     System.out.println(obj);
                    
             }             
                 //主方法
      public static void main(String args[]) 
      {
             
                    TreeSet ts  = new TreeSet();
                    
                    ts.add("day01");
                    ts.add("aay02");
                    ts.add("bay04");
                    ts.add("cay03");
       
                    for(Iterator it= ts.iterator(); it.hasNext();)
                    {
                           sop(it.next());
                           
                    }
                    
             //小结: 依靠ASCII码表,进行自然字母的自然排序                  
         }
        
        
       
             
  }     
       
             
 


 
小结 :  

             1.  TreeSet-->自然排序
        
 
 

       二. 集合框架(TreeSet存储自定义对象)


1 ) .  需求 :  将自定义对象存入TreeSet集合中,并且将对象以年龄的大小排序,若年龄相等,则用名字排序,并且保证无重复对象 
 
2 ) . Text : 


 
 import java.util.*;
 
 
 /*
  set -->元素是无序(存入和取出的顺序不一定一致),元素不可重复
   -HashSet : 底层元素结构是哈希表
       保证元素唯一性的原理是:  判断元素的hashCode的值是否相同,若相同再通过equlas判断
   -treeSet : 可以对set集合中的元素进行排序
  
  
 */
 
  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 name;
         }
        
         public int getAge()
         {
              
               return age;
         }
        
         //复写底层的compareTo方法用来比较
         public int compareTo(Object obj)
         {
               //判断实例化对象是否是student对象
               if(!(obj instanceof Student))
                      throw new RuntimeException("不是学生对象");
              
               //向下转型
               Student s=(Student)obj;
              
               //判断当前年龄是否大于传入年龄,大于则往上排
               if(this.age>s.age)
                      return 1;
               if(this.age==s.age)
               {
                      return this.name.compareTo(s.name);
               }
                    return -1;
              
              
         }
        
        
  }
 
 
  class TreeSetText
  {
        
       
          
             //输出方法
             public static void sop(Object obj)
             {
                    
                     System.out.println(obj);
                    
             }             
                 //主方法
      public static void main(String args[]) 
      {
             
                    TreeSet ts  = new TreeSet();
                    
                    ts.add(new Student("summer",12));
                    ts.add(new Student("winter",15));
                    ts.add(new Student("spring",18));
                    ts.add(new Student("sring",18));
                    ts.add(new Student("autumn",19));
                    ts.add(new Student("autumn",19));
             
                    //迭代输出,结果是 按年龄排序,并且 当年龄相等按 名字排序的无重复的集合
                    for(Iterator it= ts.iterator(); it.hasNext();)
                    {
                           
                           Student s =(Student)it.next();
                           
                           sop(s.getName()+"::"+s.getAge());
                           
                    }
                    
             
         }
        
        
       
             
  }     
       
             
 



 

小结 :  

             1.  使用treeSet存储自定义对象,若要保证对象的唯一性,则需要复写底层的compareTo()方法
        
        


      三. 集合框架(二叉树)

1 ) . 二叉树 : 存的时候通过比较的方式左边小,右边大,最终形成一个树状结构,我们称之为 二叉树  ,也叫 红黑树  ;取的时候 从左边依次取出,左边没值,再取右边的最左边的值,直到最后取完

1.1 优势 : 可减少比较次数,提高系统性能

1.3 特点 : 当元素过多时,进行存时,二叉树会自动取折中值,以减少比较次数

1.4 重点 : treeSet存取的顺序底层依赖的是compareTo()方法的判断,因此可根据此方法变更存取顺序

1.5 底层依赖的数据结构是  --> 二叉树 

1.6 保证数据的唯一性的依据是  compareTo()方法 return  0  

1.7  TreeSet排序的第一种方式是 : 

[1] 让元素自身具备比较性,元素需实现Comparable接口,覆盖compareTo方法,这种方式称为元素的自然顺序,或者叫默认顺序
 
2 ) . Text : 


 
 import java.util.*;
 
 
 /*
  set -->元素是无序(存入和取出的顺序不一定一致),元素不可重复
   -HashSet : 底层元素结构是哈希表
       保证元素唯一性的原理是:  判断元素的hashCode的值是否相同,若相同再通过equlas判断
   -treeSet : 可以对set集合中的元素进行排序
                    底层依赖的数据结构是二叉树
                    保证元素唯一性的依据是方法 compareTo方法return 0
                    TreeSet排序的第一种方式是:让其元素自身具备比较性,实现comparable接口,覆盖compareTo方法,具体详情见下文
  
  
  
  
 */
 
  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 name;
         }
        
         public int getAge()
         {
              
               return age;
         }
        
         //复写底层的compareTo方法用来比较
         public int compareTo(Object obj)
         {
               return 1 ; //1 , 0;
              
                                  //返回1是 怎么存入怎么取
                                  //返回-1是怎么存入倒着取
                                  //返回0是怎么存入都只能取第1个 
                                  //这要涉及到treeSet中底层的数据结构也就是二叉树的存取方式
              
               /*
               //判断实例化对象是否是student对象
               if(!(obj instanceof Student))
                      throw new RuntimeException("不是学生对象");
              
               //向下转型
               Student s=(Student)obj;
              
               //判断当前年龄是否大于传入年龄,大于则往上排
               if(this.age>s.age)
                      return 1;
               if(this.age==s.age)
               {
                      return this.name.compareTo(s.name);
               }
                    return -1;
                */
              
         }
        
        
  }
 
 
  class TreeSetText1
  {
        
       
          
             //输出方法
             public static void sop(Object obj)
             {
                    
                     System.out.println(obj);
                    
             }             
                 //主方法
      public static void main(String args[]) 
      {
             
                    TreeSet ts  = new TreeSet();
                    
                    ts.add(new Student("summer",12));
                    ts.add(new Student("winter",15));
                    ts.add(new Student("spring",18));
                    ts.add(new Student("sring",18));
                    ts.add(new Student("autumn",19));
 
             
                    //迭代输出,结果是怎么传入怎么传出,详情见上边compareTo方法的return处注释
                    for(Iterator it= ts.iterator(); it.hasNext();)
                    {
                           //向下转型
                           Student s =(Student)it.next();
                           
                           sop(s.getName()+"::"+s.getAge());
                           
                    }
                    
             
         }
        
        
       
             
  }     
       
             
 



3 ) .  手绘二叉树图解 : 



 

小结 :  

             1.  二叉树的核心原则是,右下是大数,左下是小数
        
           2.  优势在于后期数量大时比较更少的数以提高效率

          
 

      四. 集合框架(实现Comparator方式排序)

1 ) . TreeSet有两种自定义排序方式 --> TreeSet默认排序是自然排序, 两种自定义排序 一种是让其元素具备比较性而排序,一种是让其容器具备比较性而排序 -->详情见下文

2 ) . Text:


 
 import java.util.*;
 
 
 /*
  TreeSet的第一种排序方式是通过实现Comparable,重写compareTo方法完成  -->第一种是让元素自身具备比较性而后比较
  TreeSet的第二种排序方式是通过外部创建比较器以参数的形式传入TreeSet的方式完成 -->第二种是让容器具备比较性而后比较
  两者的优先级是, 先比较器为主,再 以元素的compareTo为主
   ps:当自身元素不具备比较性时,或者具备的比较性不是所需要的时,这时用第二种方式让容器自身具备比较性
   方式 : 定义比较器,将比较器对象以参数传递给TreeSet集合的构造函数
  
  
 */
 
 //自定义比较器  -->首先按名字排序,而后按年龄排序
 class MyCompare implements Comparator
 {
       
        public int compare(Object o1 ,Object o2)
        {
              if(!(o1 instanceof Student && o2 instanceof Student))
                      throw new RuntimeException("不是学生对象");
              
               Student s1 = (Student)o1;
               Student s2 = (Student)o2;
              
               //首先按年龄排序
             int num =   s1.getName().compareTo(s2.getName());
             
             
             //这里比较等于0.是因为上边若想等则num=0,则就往下边比较
             if(num==0)
             {      //通过将数值放入对象的方式然后调用compareTo进行比较
                    return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
             }
             
             
               return num;
        }
       
       
       
       
 }
 
  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 name;
         }
        
         public int getAge()
         {
              
               return age;
         }
        
         //原始的排序
         //复写底层的compareTo方法用来比较
          public int compareTo(Object obj)
         {
              
              
             
               //判断实例化对象是否是student对象
               if(!(obj instanceof Student))
                      throw new RuntimeException("不是学生对象");
              
               //向下转型
               Student s=(Student)obj;
              
               //判断当前年龄是否大于传入年龄,大于则往上排
               if(this.age>s.age)
                      return 1;
               if(this.age==s.age)
               {
                      return this.name.compareTo(s.name);
               }
                    return -1;
               
              
         }
        
        
  }
 
 
  class TreeSetText2
  {
        
       
          
             //输出方法
             public static void sop(Object obj)
             {
                    
                     System.out.println(obj);
                    
             }             
                 //主方法
      public static void main(String args[]) 
      {
             
                    TreeSet ts  = new TreeSet();
                    
                    ts.add(new Student("summer",12));
                    ts.add(new Student("winter",15));
                    ts.add(new Student("spring",18));
                    ts.add(new Student("sring",18));
                    ts.add(new Student("autumn",19));
 
             
                    //迭代输出,结果是怎么传入怎么传出,详情见上边compareTo方法的return处注释
                    for(Iterator it= ts.iterator(); it.hasNext();)
                    {
                           //向下转型
                           Student s =(Student)it.next();
                           
                           sop(s.getName()+"::"+s.getAge());
                           
                    }
                    
             
         }
        
        
       
             
  }     
       
             
 



 

 
小结 :  

             1. 不同的集合如何确保值唯一?

[1]LinkedList底层依赖的是 equals  , 是链表结构

[2] ArrayList底层依赖的是 equals ,是数组结构

[3]vector 底层依赖的是 equals ,是 数组结构

[4] HashSet底层依赖的是HashCode和Equals  是哈希表结构

[5] TreeSet底层依赖的是CompareTo  ,是二叉树结构

2.自定义比较器实现 的接口是 Comparator(让集合拥有比较性) , 元素本身的比较器实现的接口是  Comparable(让元素拥有比较性)
     


     五 .  集合框架(TreeSet练习)

1 ) . 需求 : 按照字符串的长度排序

2 ) . Text : 

 
 import java.util.*;
 
 
 /*
  
  需求:按照字符串的长度排序
 
 
  
 */
 
 
  
   class SingleTreeSet implements Comparator
   {
        
                    public int compare(Object o1, Object o2)
                    {
                           //先将传进来的值向下转型
                           String s1= (String)o1;
                           
                           String s2= (String)o2;
                           
                           
                           //先依据长度判断排序 -->通过new对象方式判断,因为对象中有自带compareTo方法
                           int num= new Integer(s1.length()).compareTo(new Integer(s2.length()));
                           
                           //若长度出现相等的,则第二重判断依据值排序
                           if(num==0)
                                 return s1.compareTo(s2);
                           //若第二重判断也相等,则返回num,意味着走第一回合判断,重复的值刷了下去
                           return num;
                           
                    
                    /*     这个是 第一轮判断的复杂方式
                           if(o1.length()>o2.length())
                                 return 1;
                           if(o1.length()==o2.length())
                                 return 0;
                           return -1; */
                           
                    }
        
         
   }
 
 
  class TreeSetText3
  {
        
       
          
             //输出方法
             public static void sop(Object obj)
             {
                    
                     System.out.println(obj);
                    
             }             
                 //主方法
      public static void main(String args[]) 
      {
              
              
             TreeSet ts = new TreeSet(new SingleTreeSet());
             ts.add("abhgs");
             ts.add("as");
             ts.add("ahdddd");
             ts.add("asa");
             ts.add("aefg");
             
             
             //迭代输出
             for(Iterator it=ts.iterator(); it.hasNext();)
             {
                    sop(it.next());
                    
             }
             
        
        
        
        
         }
             
  }     
       
             
 


3 ) .  切记在实际开发中,会用到多重判断,第一轮判断过后,再判断第二轮,以免丢失数据

 
小结 :  

             1.  若类中只有一个方法,也可以用匿名类的方式去实现功能
        
   
 

       六. 集合框架(泛型概述)


1 ) . 引入 : 

1.1 问题 ; JDK版本1.5之前,集合中不能存入两种不同类型的数值,若存入则报错

[1] 理解 : 若集合像数组一样初始化时便声明了类型则不会出现类似的安全隐患

1.2 解决 : JDK版本1.5 之后,引入的泛型,解决了集合类型不统一的问题

2 ) . Demo : 


 
 import java.util.*;
 
 
 /*
 
   泛型 : -->广泛的类型,用<>修饰,放在实例化对象类的后边,因为<>中可以放任何类型用来限制传进集合的值,因此成为泛型
  
  1.介绍 : JDK1.5版本以后出现新特性,用于解决安全问题,是一个类型安全机制
  2.好处:
 
  [1] 将运行时出现问题classCastException,转移到了编译时期,也就是从用户角度转移到了编程员角度
             方便编程员解决问题,让运行问题减少,安全
  [2] 避免了强制转换麻烦
 
  
 */
 
 
       //泛型示例
  class genericityDemo
  {
        
       
          
             //输出方法
             public static void sop(Object obj)
             {
                    
                     System.out.println(obj);
                    
             }            
             
               //主方法
               public static void main(String args[]) 
               {
                     
                       ArrayList<String> al = new ArrayList<String>();
                       al.add("day01");
                       al.add("day02");
                       al.add("day03");
                       al.add("day04");
 
                      
                       for(Iterator<String> it = al.iterator();it.hasNext();)
                       {
                              sop(it.next());
                             
                       }
        
        
        
        
         }
             
  }     
       
             
 

 


小结 :  

             1.  {}用户程序层次结构, ()用于参数 ,<>用于集合泛型,[]用于数组类型 
        
    

      七. 集合框架(泛型使用)


1 ) . 简述 : 

1.1 泛型的格式 : 通过<>来定义要操作的引用数据类型

1.2 在使用java提供的对象时,什么时候写泛型呢?

[1] 通常在集合框架汇总很常见,在API中见到带<>的集合就是要定义泛型

[2] 其实<>在集合中是用来接收类型的,当使用集合时,将集合中要存储的数据类型作为参数传递到<>中,再传递到add( )方法中来限制

2 ) . Text:


 
 import java.util.*;
 
 
 /*
 
   泛型 : -->广泛的类型,用<>修饰,放在实例化对象类的后边,因为<>中可以放任何类型用来限制传进集合的值,因此成为泛型
  
  1.介绍 : JDK1.5版本以后出现新特性,用于解决安全问题,是一个类型安全机制
  2.好处:
 
  [1] 将运行时出现问题classCastException,转移到了编译时期,也就是从用户角度转移到了编程员角度
             方便编程员解决问题,让运行问题减少,安全
  [2] 避免了强制转换麻烦
 
  3.常用 : 泛型在集合框架中很常见,但凡见到<> ,就是用来传入泛型的类型的,当使用集合时,我们会发现add()方法内的参数类型就是泛型所约束的
  
 */
 
 
       //泛型示例
  class genericityText
  {
        
       
          
             //输出方法
             public static void sop(Object obj)
             {
                    
                     System.out.println(obj);
                    
             }            
             
               //主方法
               public static void main(String args[]) 
               {
                     
                       TreeSet<String> ts = new TreeSet<String>(new SortTreeSet());
                       ts.add("asdf");
                       ts.add("wertq");
                       ts.add("zx");
                       ts.add("uts");
 
                      
                       for(Iterator<String> it = ts.iterator();it.hasNext();)
                       {
                              sop(it.next());
                             
                       }
        
        
        
        
         }
             
  }     
 
  //排序 -->正序
 /*  class SortTreeSet implements Comparator<String>
  {
        
         public int compare(String s1 ,String s2)
         {
              //先依据长度判断 
              int num =  new Integer(s1.length()).compareTo(new Integer(s2.length()));
             
              //当长度相等时,再依据值判断
              if(num==0)
                     return s1.compareTo(s2);
              return num;
             
              
              
         }
        
        
        
        
  } */
 
 
        //排序 -->倒序
  class SortTreeSet implements Comparator<String>
  {
        
         public int compare(String s1 ,String s2)
         {
              //先依据长度判断 
              int num =  new Integer(s2.length()).compareTo(new Integer(s1.length()));
             
             //当长度相等时,再依据值判断
              if(num==0)
                     return s2.compareTo(s1);
              return num;
             
              
              
         }
        
       //  小结 : 正序与倒序的区别,在于先拿什么去判断什么
        
        
  }
       
             
 

 

小结 :  

             1.  泛型避免了强转
        
           2.  正序变倒序最快捷的方式就是在程序中让比较的元素调换位置

         
 

     八 . 集合框架(泛型类)

1 ) . 通过泛型类来控制类中传入引用数据类型的唯一性

2 ) . Text : 


 
 import java.util.*;
 
 
 /*
 
  需求 : 实现一个泛型类,让其用一个类可以完成创建其它不同的类的操作
 
  什么时候定义泛型类?
  当类中要操作的引用数据类型不确定的时候,早期定义Object来完成扩展,现在定义泛型类来完成扩展
 */
 
 
 class Student
 {
       
 }
 
 class Worker
 {
       
       
 }
 
 //早期方式 -->通过boject的方式
class Util
{
       private Object obj;
       
       
       public void setObject(Object obj)
       {
             this.obj=obj;
             
       }
       
       public Object getObject()
       {
             return obj;
             
       }
       
}
//现在方式 -->通过泛型的方式
class Utils<Genericity> 
{
       private Genericity gen;
       
       public void setObject(Genericity gen)
       {
             this.gen=gen;
             
       }
       
       public Genericity getObject()
       {
             return gen;
             
       }
}
 
       //泛型示例
  class genericityClassText
  {
        
        //主方法
               public static void main(String args[]) 
               {
                           //老方式
                           /*  Util t =new Util();
                     
                           //采用一个工具类创建实体类对象
                              t.setObject(new Worker());
                            Worker w = (Worker)t.getObject();
                           
                            t.setObject(new Student());
                            Student s = (Student)t.getObject(); */
                            
                            
                            
                             //新方式
                             //采用一个工具类创建实体类对象
                           /*    Utils<Worker> t =new Utils<Worker>();
                            t.setObject(new Worker());
                            Worker w =  t.getObject();
                           
                           
                            Utils<Student> t =new Utils<Student>();
                         t.setObject(new Student());
                            Student s =(Student)t.getObject(); */
                            
                           //通过泛型类保证了传入对象的唯一性
        
        
               }
          
             //输出方法
             public static void sop(Object obj)
             {
                    
                     System.out.println(obj);
                    
             }            
             
              
             
  }     
 
       
 
 
小结 :  

             1.  泛型类也可让问题发生在编译时期,以为运行时期较少问题
        
           2.  泛型的出现避免了强转,还将问题从运行时期转移到了编译时期

 

     九 .  集合框架(泛型方法)

1 ) . 泛型方法一可以用来在不确定传入啥类型时用来定义,也可用来确定传入啥类型时用来限制,都可以

2 ) . Demo : 


 
 import java.util.*;
 
 
 /*
 
  需求 : 实现一个泛型方法,让其用一个方法可以传入不同的参数类型的值
 
  解说 : 泛型类定义的泛型,在整个类中有效,若被方法使用,则泛型类的对象明确要操作的具体类型后,所要操作的方法上的类型就已固定,因此泛型方法出现了
 
  泛型方法 : 为了让不同方法可以操作不同类型,而且在类型还不确定的情况下,可以将泛型定义在方法上
 
 
  
 */
 
 
 //泛型类的方式的方法使用  -->类的作用范围的整个类,全部方法一个类型  -->这种方式不可存入不同类型的值,由此出现了泛型方法,见下一个
 class Person<T>
 {
        public void print(T t)
        {
              System.out.println(t);
             
        }
       
         public void show(T t)
        {
              System.out.println(t);
             
        }
 }
 
 
 
 
 
  //泛型方法使用  -->泛型方法的作用范围在泛型方法上 ,传入的参数类型统一
 class PersonNew
 {
        public <S> void print(S s)
        {
              System.out.println(s);
             
        }
       
         public <T> void show(T t)
        {
              System.out.println(t);
             
        }
 }
 
   
       //泛型方法示例
  class genericityMethodText
  {
        
        //主方法
               public static void main(String args[]) 
               {
              
               //泛型类的方法演示
             /* Person<String> p =      new Person<String>();
             
               p.print("day01");
               p.show("day02"); */
              
              
               //泛型方法演示
               PersonNew  p =     new PersonNew ();
             
               p.print("day01");
               p.show(123);
              
              
                           
               }
          
             
             
              
             
  }     
 
       

 
小结 :  

             1.  泛型方法有一定局限性,当传入泛型类的类型是什么,那么泛型方法的参数类型就被确定了
        
         
 

       十. 集合框架(静态方法泛型)


1 ) . 特殊之处 : 

1.1 静态方法不可访问类上定义的泛型类型,若静态方法操作的应用类型不确定,可将泛型类型定义在方法上

2 ) . Text : 


 
 import java.util.*;
 
 
 /*
 
  需求 : 实现一个泛型方法,让其用一个方法可以传入不同的参数类型的值
  
   总结 :
   [1]普通方法可以用在方法上定义的泛型类型,也可用在类上定义的类泛型
   [2]静态方法只能用在方法上定义的泛型类型
 */
 
  class Person<T>
  {
         //此时方法上的类型用的是类上定义的
         public void print(T t)
         {
               System.out.println(t);
              
         }
        
           //此时方法上的类型用的是方法上定义的
         public <S> void show(S s)
         {
               System.out.println(s);
              
         }
        
        
            //此时静态方法上的类型只能用方法上定义的类型
         public static <Z> void show1(Z z)
         {
               System.out.println(z);
              
         }
  }
 
 
 
 
   
       //泛型方法示例
  class genericityStaticMethodText
  {
        
               //主方法
               public static void main(String args[]) 
               {
              
                           Person p = new Person<String>();
              
                           p.print("普通方法......"+"Class01");    
                           p.show("泛型方法输出....."+"Method01");  
                           p.show1("静态泛型方法输出....."+"StaticMethod01");    
                           
               }
          
              public void sop(Object obj)
              {
                    
                     System.out.println(obj);
              }
             
              
             
  }     
 
       
 

小结 :  

             1.  泛型在方法上定义在返回值类型的前边, 泛型在类上定义在类名的后边
        
           2.  静态先加载,后来才有实例化对象

           3. 静态泛型方法只能用方法上定义的类型,而不能运用类上定义的,因为静态先加载,而后实例化,因此会导致静态不可引用非静态,

         

      十一. 集合框架(泛型接口)

1 ) . 泛型接口也可实现在不确定性的情况下实现功能扩展

2 ) . Demo:


   
 import java.util.*;
 
 
 /*
 
  需求 :  将泛型定义在接口上
 
 
 
 */
 
 
  interface  Inter<T>
  {
         void show(T t);
        
  }
  /*   第一种方式 : 不确定接口类型.确定实现类类型
 class  InterImple  implements Inter<String>
 {
        public void show(String t)
        {
             
              System.out.println("show:"+t);
        }
       
 }
  */
    //第二种方式 : 不确定接口类型.不确定实现类类型
 class InterImple1<T>  implements Inter<T>
 {
        public void show(T t)
        {
             
              System.out.println("show:"+t);
        }
       
 }
 
 
   
       //泛型接口示例
  class genericityInterfaceText
  {
        
               //主方法
               public static void main(String args[]) 
               {
                //第一种方式
               /*  InterImple in =new InterImple();
               
                in.show("Day01");  */
               
               
                //第二种方式
                InterImple1<Integer> in1 =new InterImple1<Integer>();
               
                in1.show(123);
               
               
               
               
               
               }
          
              public void sop(Object obj)
              {
                    
                     System.out.println(obj);
              }
             
              
             
  }     
 
       


 

小结 :  

             1.   创建对象时的泛型-->泛型类-->普通泛型方法 --> 静态泛型方法-->泛型泛型  -->都可实现在不确定性的情况下的传参,另外也都可对接口/类/方法/自定义做限制
        
     
          
 

     十二 . 集合框架(泛型限定)

1 ) . 泛型限定 : 

1.1 ? extedns E : 可以接收E类型或E的子类型, --> 指上限

1.2  ?   super  E  : 可以接收E类型或者E的父类型  -->指下限

2 ) . 泛型限定的使用场景 : 

2.1 上限用于存在继承关系时,父类需要用到子类的时候 可使用到下限

2.2 下限用于存在继承关系时,子类用到父类的时候,可使用到上限

3 ) .  Demo:


 
 import java.util.*;
 
 
 /*
 
  需求 :  泛型限定
 
  格式 : ArrayList<? extends Person> arr 
 
  ? 通配符 ,可以理解为占位符
  泛型的限定:
  ? extends E : 可以接收E类型或E的子类型 -->指上限
  ? super   E : 可以接收E类型或者E的父类型 -->指下限
 
 
 
 */
 
 //关于上限
  class Person 
  {
         private String name;
        
         Person(String name)
         {
               this.name=name;
         }
        
       
         public String getName()
         {
               return name;
              
         }
       
        
  }
  
  
   class Student extends Person
   {
       
         
        Student(String name)
        {
              super(name);
             
        }
 
   }
 
 
 
 
 
 
   
       //泛型限定
  class genericityDemo
  {     
              //关于下限
             class student implements Comparable<Person>  <? supper E>
             {
                     public int compareTO(Person p)
                     {
                            this.getName();
                           
                     }
             
             }
 
              class Comp implements Comparator<Student>
              {
                     public int compare(Student s1,Student s2)  //这里填person 也就是student的父类,也可编译通过,实现,这是泛型的上限
                     {
                           
                           return s1.getName().compareTO(s2.getName());
                     }
                    
                    
              }
             
              TreeSet<Student> ts =new TreeSet(Student)(new Comp())
              ts.add(new Student("add1"));
              ts.add(new Student("add2"));
              ts.add(new Student("add3"));
             
             
             
             
             
              public static void sop(Object obj)
              {
                    
                     System.out.println(obj);
              }
        
               //主方法
               public static void main(String args[]) 
               {
              
               ArrayList<Person> arr = new ArrayList<Person>();
               arr.add(new Person("summer"));
               arr.add(new Person("autumn"));  
              
               ArrayList<Student> arr1 = new ArrayList<Student>();
               arr1.add(new Student("Lily"));
               arr1.add(new Student("mater"));
               
              
             
             // printColl2(arr1);
             
                printColl2(arr);
              
              
               /*
               ArrayList<String> arr =new ArrayList<String>();
               
                arr.add("day01");
                arr.add("day02");
                arr.add("day03");
                arr.add("day04");
                 
               
                ArrayList<Integer> arr1 =new ArrayList<Integer>();
               
                arr1.add(12);
                arr1.add(13);
                arr1.add(14);
                arr1.add(15);   */
               
                /* 方式一调用 :
                printColl(arr);
                 printColl(arr1);
                 */
                    
                    //方 式二调用 ;
                /*  printColl2(arr);
                 printColl2(arr1); */
               
               }
              
               //用来传入继承对象的  -->关于上限
               public static void printColl2(ArrayList<? extends Person> arr)  //  或者 <? supper Student>
               {
                      for(Iterator<? extends Person> it = arr.iterator(); it.hasNext();)
                      {
                            
                             sop(it.next().getName());
                      }
                     
               }
              
             
              
              
              
               //方式一 :  通过使用占位符的方式传入不同参数的值
               public static void printColl(ArrayList<?> arr)
               {
                     
                      for(Iterator<?> it = arr.iterator(); it.hasNext();)
                      {
                            
                             sop(it.next());
                      }
                     
                     
               }
              
               //方式二 :  通过使用静态方法的方式传入不同参数的值
              /*  public static <T> void printColl2(ArrayList<T> arr)
               {
                     
                      for(Iterator<T> it = arr.iterator(); it.hasNext();)
                      {
                            
                             sop(it.next());
                      }
                     
                     
               } */
              
              
              
       
             
              
             
  }     
 
       


 

 
小结 :  

             1.  泛型的上限与下限,用在继承上较多,用来限制只允许 存在继承关系的导入数据
        
         
          

     十三 .  集合框架(泛型限定-2)

1 ) . 关于泛型的高级用法   : 

1.1 只想用单一类型 : 例子 : <String>  ;   特定类型

1.2 什么类型都可以传入  : 例子 : <?>  ;   占位符 ,所有类型

1.3  只想存在继承关系的类型的可以传入 :  例如 : 上限 --> <? extends E> 或者  下限 -->  <? supper E>

2 ) . Demo : 


 
 import java.util.*;
 
 
 /*
 
  需求 :  泛型限定
 
  格式 : ArrayList<? extends Person> arr 
 
  ? 通配符 ,可以理解为占位符
  泛型的限定:
  ? extends E : 可以接收E类型或E的子类型 -->指上限
  ? super   E : 可以接收E类型或者E的父类型 -->指下限
 
 
 
 */
 
 //父类
  class Person 
  {
         private String name;
        
         Person(String name)
         {
               this.name=name;
         }
        
       
         public String getName()
         {
               return name;
              
         }
       
        
  }
  
   //子类
   class Student extends Person
   {
       
         
        Student(String name)
        {
              super(name);
             
        }
       
       
       
 
   }
 
 
 
 
  //一个比较器,无论传入子类还是父类都可搞定,这就是上限,在<>内填入父类来表示上限
class Comp implements Comparator<Person>
 {
       public int compare(Person s1,Person s2)
        {
              return s1.getName().compareTo(s2.getName());
             
        }
 
 }
 
 
 
 
   
       //泛型限定
  class genericityDemo1
  {    
              public static void sop(Object obj)
              {
                    
                     System.out.println(obj);
              }
        
               //主方法
               public static void main(String args[]) 
               {
                           //打印子类-->观察比较器.观察泛型即可发现不同点
                           TreeSet<Student> ts = new TreeSet<Student>(new Comp());
                           
                           ts.add(new Student("summer"));
                           ts.add(new Student("autumn"));
                           ts.add(new Student("winter"));
                           
                           for(Iterator<Student> it =ts.iterator(); it.hasNext();)
                           {
                                 
                                 sop(it.next().getName());
                           }
                           
                           
                           
                           //打印父类-->观察比较器.观察泛型即可发现不同点
                           TreeSet<Person> ts1 = new TreeSet<Person>(new Comp());
                           
                           ts1.add(new Person("summerFatcher"));
                           ts1.add(new Person("autumnFatcher"));
                           ts1.add(new Person("winterFatcher"));
                           
                           for(Iterator<Person> it =ts1.iterator(); it.hasNext();)
                           {
                                 
                                 sop(it.next().getName());
                           }
              
               }
             
              
             
  }     
 
       



3 ) .  泛型的限定 可用在TreeSet中排序,依靠自定义比较器时,可以经典的用到

 
小结 :  

             1.  泛型也可限定treeSet中的比较器的比较元素 
        
           2.  泛型限定是用于泛型扩展用的

       
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值