zoukankan      html  css  js  c++  java
  • Day13 泛型

    泛型

    泛型定义

    在一个类型(类,接口,方法)之后,定义一个类型参数。

    原生类型:类型后面没有指定具体的类型参数。

    好处

    使用泛型的好处在于,它在编译的时候进行类型安全检查,并且在运行时所有的转换都是强制的,隐式的,大大提高了代码的重用率。

    语法

    class Point<T>{}

    通配符(?)

    无界通配符(?)可以接受任何的类类型。

    public void show(Point<?> p){}

    (? extends 上限类)只能接受上限类和上限类子类,如只能接受数字类型,Byte,Short,Integer,Long,Float,Double

    public void show(Point<? extends Number> p){}

    (? super 下限类)下限,下限类和下限类的父类,Number和Number的父类

    public void show(Point<? super Number> p){}

    注意

    Point<Object>不是Point<String>、Point<Integer>等的父类

    public void add(Point<String> ps,Point<Object> po){//错误
      po = ps
    }
    
    public void add(Point<String> ps,Point<? extends Object> po){//正确

    类型参数与通配符的区别

    类型参数与 通配符的区别:
    <T> 和 <?>
    1.类型参数可以指定上限,也只能指定上限;
    统配符可以指定上限,也可以指定下限;
    2.类型参数 可以指定多个 上限;
    通配符 只能指定一个上限;
    3.类型参数 可以作为一种类型存在;
    统配符不能表示 类型

    泛型构造

    //定义了一个泛型类 
    class PointN<T>{//类型参数 形式类型参数 
        private T x;
        private T y;
        //定义了一个泛型构造器
        <E>PointN(E e){
            System.out.println(e);
        }
        public T getX() {
            return x;
        }
        public void setX(T x) {
            this.x = x;
        }
        public T getY() {
            return y;
        }
        public void setY(T y) {
            this.y = y;
        }
    }
    public class TestPoint2 {
        public static void main(String[] args) {
            //                        指定具体的类型参数
            PointN<String> p1 = new <Integer>PointN<String>(22);
            //类型推断:   根据参数  的类型 自动推断出 构造的类型参数 是Integer类型
            PointN<String> p2 = new PointN<String>(22);
        }
    
    }

    泛型方法

    定义泛型方法时,必须在返回值前边加一个<T>,来声明这是一个泛型方法,持有一个泛型T,然后才可以用泛型T作为方法的返回值。

    class Demo{
        //泛型方法
        public <E> void f(E e) {
            System.out.println(e);
        }
        public <E> E ff(E e) {
            return e;
        }
        public <E extends Number> void fff(E e) {
            System.out.println(e);
            //自动推断的方式
            f("hello");
            //指定的方式,显示,this
            this.<String>f("hello");
        }
    }
    public class TestPoint3 {
        public static void main(String[] args) {
            // 泛型方法应用
            Demo d = new Demo();
            //具体指定 泛型方法参数的类型
            d.<String>f("hello");
            //可以使用类型推断: 根据参数的类型 自动推断
            d.f(11);
            d.fff(33);
    
        }
    
    }

    泛型擦除

    1.参数化类型:Point<String>,擦除后为原生类型Point

    2.类型参数:用上界来替换

    • Point<T>:无界类型参数,用Object来替换

    • 类型参数有上限,用上限来替换。

    • 有多个上限,用第一个上限替换。

    重载

    class PointNew<T>{}
    interface Info1{}
    interface Info2{}
    
    class Demo1{
        //为了实现重载
        //生成的字节码文件中,泛型的信息被擦除了
        public void f(String p) {}
        public void f(PointNew<Integer> p) {}//擦除后:PointNew p
        public <E> void f(E e) {}//擦除后:Object e
        public <E extends Info1> void f(E e) {}//擦除后:Info1 e
        public <E extends Info2 & Info1> void f(E e) {}//擦除后:Info2 e
        
    }

    重写

    class Parent{
        //重写:参数父类中参数擦除后与子类中参数相同
        public void f(PointNew<String> p) {}
    }
    class Child1 extends Parent{
        public void f(PointNew<String> p) {}
    }

    泛型接口

    //泛型接口
    interface Info<T>{
        void f(T t);
    }
    //在实现接口时  指定具体的类型参数
    class InfoImpl1 implements Info<String>{
        @Override
        public void f(String t) {
            System.out.println(t);
        }
    }
    //在实现 接口时  不能确定类型
    class InfoImpl2<T> implements Info<T>{
        @Override
        public void f(T t) {
            System.out.println(t);
        }
    }
    public class TestPoint5 {
    
        public static void main(String[] args) {
            InfoImpl1 i1 = new InfoImpl1();
            i1.f("hello");
            InfoImpl2<String> i2 = new InfoImpl2<>();
            i2.f("tom");
        }
    
    }

    比较器

    Comparable

    Comparator

    对象进行自然方式排序,必须是实现了Comparable接口的。

    Arrays.sort(数组);//默认 自然排序

    Comparable<T> 泛型接口 比较器实现自然排序

    Comparator<T> 泛型接口 外部比较器

     1 package day13;
     2 
     3 import java.util.Arrays;
     4 import java.util.Comparator;
     5 class Student implements Comparable<Student>{
     6     private int age;
     7     private int no;
     8     public Student(int no,int age) {
     9         this.age = age;
    10         this.no= no;
    11     }
    12     public int getAge() {
    13         return age;
    14     }
    15     public int getNo() {
    16         return no;
    17     }
    18     @Override
    19     public String toString() {
    20         return "编号:"+no+",年龄:"+age;
    21     }
    22 /*    @Override
    23     public int compareTo(Object o) {
    24         //this 与  o比较
    25         //this.age   o.age
    26         Student stu = (Student)o;
    27         //this.age  stu.age
    28         
    29         return 0;
    30     }*/
    31     @Override
    32     public int compareTo(Student o) {
    33         // this.age   o.age
    34         //升序的方式 
    35         /*if(this.age > o.age ) {
    36             return 1;//正数
    37         }else if(this.age < o.age) {
    38             return -1;//负数
    39         }else {
    40             return 0;//相等
    41         }*/
    42         return this.age - o.age;
    43     }    
    44 }
    45 //按照 编号升序排序
    46 class NoComparator implements Comparator<Student>{
    47     @Override
    48     public int compare(Student o1, Student o2) {
    49         // o1  和 o2比较
    50 /*        if(o1.getNo() > o2.getNo()) {
    51             return 1;
    52         }else if(o1.getNo() < o2.getNo()) {
    53             return -1;
    54         }else {
    55             return 0;
    56         }*/
    57         return o1.getNo()- o2.getNo();
    58     }    
    59 }
    60 public class TestSort {
    61     public static void main(String[] args) {
    62         Student zhang = new Student(2,44);
    63         Student wang = new Student(1,11);
    64         Student zhao = new Student(3,33);
    65         Student [] stus = {zhang,wang,zhao};
    66         //Arrays.sort()按照自然方式排序的
    67 //        Arrays.sort(stus);
    68         //1.自定义类 实现接口
    69 //        Arrays.sort(stus, new NoComparator());
    70         //2.匿名内部类实现接口
    71         Arrays.sort(stus,new Comparator<Student>() {
    72             @Override
    73             public int compare(Student o1, Student o2) {
    74                 return o1.getNo() - o2.getNo();
    75             }    
    76         });
    77         //3 Lambda
    78         Arrays.sort(stus,(s1,s2)->s1.getNo()-s2.getNo());
    79         
    80         Arrays.stream(stus).forEach(System.out::println);
    81         //--------------------------------------------
    82         int [] arr = {45,1,77,34,3};
    83         Arrays.sort(arr);
    84         Arrays.stream(arr).forEach(System.out::println);
    85         //--------------------------------------------
    86         String [] arrs = {"cc","dd","aa","ee"};
    87         Arrays.sort(arrs);
    88         Arrays.stream(arrs).forEach(System.out::println);
    89         //------------------------------------------------
    90     }
    91 
    92 }
    View Code

    枚举类型

    语法

    enum 枚举类型{
      
    }
      1 package day13;
      2 
      3 import java.util.Scanner;
      4 
      5 //RGB
      6 /*class Color{
      7     public static final int RED = 1;
      8     public static final int GREEN = 2;
      9     public static final int BLUE = 3;
     10 }*/
     11 interface ColorInfo{
     12     void fv();//抽象方法
     13 }
     14 enum Color{
     15     RED(1,"红色") {
     16         @Override
     17         void f() {
     18             // TODO Auto-generated method stub
     19             
     20         }
     21     },GREEN(2,"绿色") {
     22         @Override
     23         void f() {
     24             // TODO Auto-generated method stub
     25             
     26         }
     27     },BLUE(3,"蓝色") {
     28         @Override
     29         void f() {
     30             // TODO Auto-generated method stub
     31             
     32         }
     33     };
     34     
     35     private Color(int no, String name) {
     36         this.no = no;
     37         this.name = name;
     38     }
     39     private int no;
     40     private String name;
     41     //抽象方法
     42     abstract void f();
     43 }
     44 /*enum Color implements ColorInfo{
     45     //定义枚举成员,对象,实例
     46     RED(1,"红色"){
     47         public void fv() {
     48             System.out.println("红色的");
     49         }
     50     },GREEN(2,"绿色"){
     51         public void fv() {
     52             System.out.println("绿色的");
     53         }
     54     },BLUE(3,"蓝色"){
     55         public void fv() {
     56             System.out.println("蓝色的");
     57         }
     58     };    //public static final
     59     private int no;//编号
     60     private String name;//名字
     61     
     62     private Color(int no, String name) {
     63         this.no = no;
     64         this.name = name;
     65     }
     66     public int getNo() {
     67         return no;
     68     }
     69     public void setNo(int no) {
     70         this.no = no;
     71     }
     72     public String getName() {
     73         return name;
     74     }
     75     public void setName(String name) {
     76         this.name = name;
     77     }
     78     public void f() {}
     79     @Override
     80     public String toString() {
     81         // TODO Auto-generated method stub
     82         return this.no+","+this.name();
     83     }
     84     @Override
     85     public void fv() {
     86         // TODO Auto-generated method stub
     87         
     88     }
     89     
     90 }*/
     91 public class TestEnum {
     92     public static void main(String[] args) {
     93 //        System.out.println(Color.RED.getNo()+","+Color.RED.getName());
     94 //        System.out.println(Color.BLUE.getNo()+","+Color.BLUE.getName());
     95 /*        Color.RED.setName("红色");
     96         System.out.println(Color.RED.getName());
     97         Color.RED.f();*/
     98     /*    Color.RED.no = 11;
     99         Color.GREEN.name = "绿色";
    100         System.out.println(Color.RED.no);
    101         System.out.println(Color.GREEN.name);*/
    102         
    103 /*        Scanner input = new Scanner(System.in);
    104         System.out.println("输入一个颜色:");
    105         String s = input.next();
    106         Color co = Color.valueOf(s); 
    107         switch(co) {
    108         case RED:
    109             System.out.println("进行红色的操作");
    110             break;
    111         case GREEN:
    112             System.out.println("进行绿色的操作");
    113             break;
    114         case BLUE:
    115             System.out.println("进行蓝色的操作");
    116             break;
    117         }*/
    118         
    119         //可以遍历枚举值
    120 /*        for(Color c: Color.values()) {
    121             System.out.println(c.name());
    122             System.out.println(c.ordinal());
    123         }*/
    124         
    125 /*        // 类型不安全
    126         int red = Color.RED;
    127         int a = red +5;
    128         System.out.println(a);
    129         //意思不明确
    130         System.out.println(Color.RED);*/
    131 //        System.out.println(Color.RED);
    132         
    133         
    134         
    135         
    136 
    137     }
    138 
    139 }
    View Code

    注意

    1.所有的枚举类型的对象都在枚举类第一行显示定义出来。

    2.对象默认是public static final的

    3.枚举类的构造都是private的

    4.枚举类继承自java.lang.Enum类

    5.对于一个非抽象枚举类来说,都是final

    一个枚举类的所有对象都实现了接口中的抽象方法,此枚举类就是抽象类,abstract的了

    枚举类中定义抽象abstract方法,所有对象都需要实现此抽象方法,那么此枚举类是abstract的了

    强制垃圾回收

    class Person{
    
        @Override
        protected void finalize() throws Throwable {
            System.out.println("this---->"+this);
        }
        
    }
    public class TestGC {
    
        public static void main(String[] args) {
            // 强制垃圾回收
            Person per = new Person();
            System.out.println(per);
            per = null;//断开引用
            System.gc();//强制通知垃圾回收器
    //        Runtime.getRuntime().gc();//
    
        }
    
    }
  • 相关阅读:
    Matplotlib
    Numpy&Pandas
    莫凡《机器学习》笔记
    李宏毅《1天搞懂深度学习》笔记
    Git客户端使用教程
    像素级压缩感知图像融合的论文
    二分图【洛谷P2175】 小Z的游戏分队
    模板【洛谷P3390】 【模板】矩阵快速幂
    模板 可并堆【洛谷P3377】 【模板】左偏树(可并堆)
    LCA SP913 QTREE2
  • 原文地址:https://www.cnblogs.com/qingyunzong/p/8253587.html
Copyright © 2011-2022 走看看