JAVA004【常用API,自定义泛型、collection接口】

1.Date类概述

  • 类Date表示特定的瞬间,精确到毫秒

  • 作用:用来获取日期时间的信息,可以精确到毫秒值

    • 1秒为1000毫秒
    • Date() 获取当前时间对象
    • Date(long time) 根据毫秒值创建日期对象
    • long getTime()获取当前时间的毫秒 从时间零点到当前时间经历的毫秒数:1970.1.1 00:00:00

2.DateFormat类:日期格式化类

  • Date主要表示1970年到某个时间的毫秒值

  • 这是一个抽象类不能直接创建对象 只能创建子类对象

    • 常用子类:SimpleDateFormat
      • SimpleDateFormat类常用构造方法
            * SimpleDateFormat() 创建日期格式化对象,使用默认日期模式
            * SimpleDateFormat(String pattern)
                * 根据日期模式创建日期格式化对象
        
  • 作用:

    • DateFormat类常用方法的两个方法
          * String format(Date date):日期转字符串
          * Date parse(String str):字符串转日期
      
  • 例子:

    //日期转换为字符串
    Date now = new Date();
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-mm-dd hh-mm-ss");
            String s=dateFormat.format(now);
            System.out.println(s);
    //字符串转换为日期
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-mm-dd");
            Date d=dateFormat.parse("2000-10-10");
            System.out.println(d);
    

3.Calendar 日历

  • Calendar 类是一个抽象类:不能创建对象 只能创建子类对象

  • get set add正数向后偏移

  • 注意:month 获取是0到11 需要加1才是中国的

  • 通过此类的静态方法创建日历对象:Calendar c= Calendar.getInstance() 获取日历对象

    • 相对于 Calendar c=new GregorianCalendar 中国
  • 1. Calendar的作用
       非常方便的可以获取到年月日时分秒,昨天,前天,明天,上个星期,上个月,前几年…
       可以方便的调整时间
    
    2. 如何创建Calendar对象
       * Calendar类是一个抽象类:不能创建对象,只能创建子类对象
       * 通过Calendar类的静态方法创建日历对象,该方法如下:
           * static Calendar getInstance()  获得日历对象
    
    3. Calendar类常用方法
        int get(int field):
           根据指定的日历字段获得对应的值
           常用日历字段:YEAR/MONTH/DATE/HOUR/MINUTE/SECOND
    
        void set(int field, int value)
           修改指定日历字段的值为指定值value
    
        void add(int field, int amount)
           将指定日期字段的值在当前值基础上加减一个值:amount
            amount:正数,代表向前偏移
            amount:负数,代表向后偏移
    
    4 .Calendar注意事项
        MONTH: 获得月份取值范围011,需要加1才是我们中国正确的月份
        DAY_OF_WEEK: 取值范围17  1代表周日,2代表周一,.....
    
ublic class Demo03 {
    public static void main(String[] args) {
        /*
          Calendar类静态方法源码分析:
            static Calendar getInstance(){
                return new GregorianCalendar();
            }
         */
        // 创建日历对象
        Calendar c = Calendar.getInstance(); // Calendar c = new GregorianCalendar();

        // 修改年份
        // c.set(Calendar.YEAR, 2018);
        // 修改月份
        // c.set(Calendar.MONTH, 11);


        // 将年份向前偏移1年
        // c.add(Calendar.YEAR, 1);
        // 将月份向后偏移2个月
        // c.add(Calendar.MONTH, -2);

        // java.util.GregorianCalendar
        // 获得年份
        System.out.println(c.get(Calendar.YEAR));
        // 获得月份
        System.out.println(c.get(Calendar.MONTH) + 1);
        // 获得日
        System.out.println(c.get(Calendar.DAY_OF_MONTH));
        // 获得周几
        System.out.println(c.get(Calendar.DAY_OF_WEEK));
    }
}

4.System工具类中常用方法

  • currentTimeMillis() arraycopy()

static long currentTimeMillis()
    获得当前时间的毫秒值

static void arraycopy(Object src, int srcPos,
Object dest, int destPos, int length)
    * 数组复制
    * src   源数组
    * srcPos 源数组的起始索引
    * dest   目标数组
    * destPos  目标数组的起始索引
    * length   要复制元素的个数
public class Demo051 {
    public static void main(String[] args) {
        // test01();

        test02();
    }

    /*
      static void arraycopy(Object src, int srcPos,
        Object dest, int destPos, int length)
            * 数组复制
            * src   源数组
            * srcPos 源数组的起始索引
            * dest   目标数组
            * destPos  目标数组的起始索引
            * length   要复制元素的个数
     */
    private static void test02() {
        // 源数组
        int[] src = {1,2,3,4,5,6,7};
        // 目标数组
        int[] dest = new int[7];

        System.out.println(Arrays.toString(src));
        System.out.println(Arrays.toString(dest));

        System.out.println("------------------------");
        // 将数组src元素复制dest数组中
        // System.arraycopy(src, 0, dest, 0, 6);
        System.arraycopy(src, 1, dest, 1, 6);

        System.out.println(Arrays.toString(src));
        System.out.println(Arrays.toString(dest));
    }

    /**
     * currentTimeMillis:获得当前时间毫秒值
     */
    private static void test01() {
        // 获得开始时间:毫秒值
        long start = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            System.out.println("i = " + i);
        }
        // 获得结束时间:毫秒值
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }
}

5. BigDecimal类

1. BigDecimal类的作用
    用于解决小数不能进行精确数学运算的问题
    可以实现小数之间的精确数学运算。

2. BigDecimal类常用构造方法
    BigDecimal(String val)

3. BigDecimal类常用方法
    *  BigDecimal  add(BigDecimal b)  两个数相加
    *  BigDecimal  divide(BigDecimal b) 两个数相除
    *  BigDecimal  subtract(BigDecimal b)  两个数相减
    *  BigDecimal  multiply(BigDecimal b)  两个数相乘
public class Demo061 {
    public static void main(String[] args) {
       /* double a = 4.54;
        double b = 1.51;
        double c = a + b;
        System.out.println(1.5 + 2.5);*/

       // 创建BigDecimal对象
        BigDecimal a = new BigDecimal("1.0");
        BigDecimal b = new BigDecimal("3.0");

        // 进行加减乘除运算
        System.out.println("a + b = " + a.add(b));
        System.out.println("a - b = " + a.subtract(b));
        System.out.println("a * b = " + a.multiply(b));
        System.out.println("a / b = " + a.divide(b,new MathContext(3, RoundingMode.HALF_EVEN)));
    }
}

6.StringBuilder

  • 1. StringBuilder是什么
        StringBuilder:可变字符串
        String:不可变字符串
    
    2. 为什么使用StringBuilder
        解决字符串拼接耗性能问题:耗时间和耗内存
    
    4. StringBuilder类常用方法
        StringBuilder append(数据类型 变量名)
            * 追加数据
        String toString();
            * 将可变字符串转换为不可变字符串
    public class Demo071 {
        public static void main(String[] args) {
            // 创建可变字符串对象
            StringBuilder sb = new StringBuilder();
            /*sb.append(100);
            sb.append(1.5);
            sb.append(true);
            sb.append("abc");*/
    
            // 链式编程:当一个方法的返回值是一个对象时可以继续调用该对象的方法
            sb.append(100).append(1.5).append(true).append("abc");
            System.out.println(sb.toString());
        }
    }
    
/**
    目标:String和StringBuilder性能测试

    小结:
        StringBuilder和String类的选择
            如果需要进行大量的字符串拼接,则选择StringBuilder
            
 */
public class Demo072 {
    public static void main(String[] args) {
        // String str = "";
        StringBuilder sb = new StringBuilder();
        long start = System.currentTimeMillis();
        for (int i = 0; i < 1000000; i++) {
            // str += i;
            sb.append(i);
        }
        long end = System.currentTimeMillis();
        System.out.println(end - start); //  5

    }
}

7.包装类名称

  • 基本数据类型功能及其有限

    • 为了实现更多的操作 java为每种数据类型提供了对应的类> 包装类
  • byte Byte

  • short Short

  • int Integer

  • long Long

  • float Float

  • double Double

  • char Character

  • boolean Boolean

    • 作用

      1. 1将字符串转换为对应的基本数据类型

      String y=“100”

      int x=Integer.parseInt(y)

      1. 2将基本数据类型转换为字符串类型

      int n=100;

      sout(Integer.toString(n))

              八种基本数据类型与对应的包装类名称
                   byte                Byte
                   short               Short
                   int                 Integer
                   long                Long
                   float               Float
                   double              Double
                   char                Character
                   boolean             Boolean
      
                  基本数据类型的首字母大写,特别的2个Integer, Character
      
              包装类常用操作
                  1. 将字符串转换为对应的基本数据类型。
                  2. 将基本数据类型转换为字符串类型。
      
          小结:
              8种基本数据类型:byte short int long float double char boolean
              8种包装类类名: Byte  Short Integer Long Float Double Character Boolean
       */
      public class Demo81 {
          public static void main(String[] args) {
              //  1. 将字符串转换为对应的基本数据类型。
              String price = "100";
              String pre = "8.5";
      
              // 将字符串转换为整型数据
              int price01 = Integer.parseInt(price); // 100
              // 将小数字符串转换为浮点型
              double pre02 = Double.parseDouble(pre); // 8.5
      
              System.out.println(price01 * pre02);
      
              // 2. 将基本数据类型转换为字符串类型
              int num01 = 200;
              // 任何内容和字符串拼接都是字符串
              System.out.println(num01 + "");
              System.out.println(Integer.toString(num01)  + 1); // "2001"
              System.out.println(Double.toString(0.85) + 1); // 0.851
          }
      }
      

8.自动装箱和自动拆箱 JDK1.5特性

包装类类型的数据和基本数据可以直接参与数据运算

  • 自动拆箱

    • 包装类转基本数据类型 Integer int
      • JDK1.5之前 Integer x=Integer.valueOf(200) int y=x.intValue()
      • 1.5之后 int y=x // int y=x.intValue()
  • 自动装箱

    • int Integer

      • 1.5之前 int x=100; Integer y=Integer.valueOf(x)//new Integer(x)过时了

      • 1.5之后 Integer y=x;

      • package com.itheima._09自动拆装箱;
        
        import java.util.ArrayList;
        
        /**
            目标:能够说出自动装箱和自动拆箱的概念
        
            讲解:
                自动装箱和自动拆箱概述
                    JDK1.5新特性
        
                什么是自动拆箱:
                        Java编译器自动将包装类类型的数据转换为对应基本数据类型的过程。
                        比如:Integer ==> int
                        比如:Double ==> double
        
                什么是自动装箱:
                        Java编译器自动将基本数据类型转换对应的包装类类型的过程
                        比如:int ==> Integer
        
                自动装箱和自动拆箱的好处
                    * 包装类类型的数据和基本数据可以直接参与数据运算
        
                思考:什么时候会触发自动装箱和自动拆箱?
                    自动装箱:等号左边是包装类类型,等号右边是基本数据类型
                            Integer num = 100;
                    自动拆箱:等号左边是基本数据类型,等号右边是包装类类型
                            Integer a = Integer.valueOf(200);
                            int num = a; // a.intValue();
        
                装箱和拆箱演示
                    int --> Integer
                    Integer --> int
            小结
                1.什么是自动装箱:自动将基本数据类型转换对应的包装类类型
                2.什么是自动拆箱:自动将包装类类型转换为基本数据类型
         */
        public class Demo091 {
            public static void main(String[] args) {
                // int --> Integer
                // JDK1.5之前的做法
                int num01 = 100;
                int a = num01;
        
                Integer num02 = Integer.valueOf(num01); // new Integer(num01)
                Integer b = num02;
        
                // JDK1.5之后的做法
                // 自动装箱
                Integer num03 = num01; // Integer.valueOf(num01);
        
                // Integer --> int
                Integer num04 = Integer.valueOf(200);
                // JDK1.5之前的做法
                int num05 = num04.intValue();
                // JDK1.5之后的做法
                // 自动拆箱
                int num06 = num04; // int num06 = num04.intValue();
                System.out.println(num06 + num01); // 300
                // 自动装箱和拆箱的好处:包装类类型的数据和基本数据可以直接参与数据运算
                // Integer result = Integer.valueOf(num04.intValue() * num01)
                Integer result = num04 * num01;
                System.out.println(result);
        
                System.out.println("--------------");
                // 创建集合存储整型数据
                ArrayList<Integer> list = new ArrayList<>();
                list.add(1);
                list.add(2); // 自动装箱
                list.add(Integer.valueOf(4));
                list.add(3);
        
                int num = list.get(0); // 自动拆箱
            }
        }
        

9.集合和数组

  • 一个用来存储多个元素的容器

  • 集合和数组的区别

    • 数组长度固定 数组可以存储基本数据类型 也可以存储引用数据类型

    • 集合长度可变 只能存储引用数据类型(猪狗猫对象) 如果存储基本数据类型需要使用对应的包装类类型

    • 元素个数固定用数组 否则用集合

    • package com.itheima._10集合概述;
      
      import java.util.ArrayList;
      
      /**
          目标:能够说出集合和数组的区别
      
          讲解:
              1. 什么是集合(回顾)
                  一个用来存储多个元素的容器
      
              2. 集合和数组的区别
                  数组长度固定,数组可以存储基本数据类型,也可以储存引用数据类型
                  集合长度可变,只能存储引用数据类型,如果要存储基本数据类型需要使用对应的
                      包装类类型。
      
              3. 集合的分类
                  Collection ---> 接口  所有单列集合的父类
                      List   ---> 子接口
                          ArrayList
                          LinkedList
                      Set    ---> 子接口
                          HashSet
                          LinkedHashSet
          小结:
              1. 集合和数组的区别
                  集合:长度可变,只能存储引用数据类型
                  数组:长度固定,可以存储基本数据类型和引用数据类型
      
              2. 如何选择集合和数组
                  判断元素个数是否规定,如果是则可以选择数组,否则选择集合。
       */
      public class Demo10 {
          public static void main(String[] args) {
              int[] arr = {1,2,3};
              ArrayList<Integer> list = new ArrayList<>();
              list.add(1);
          }
      }
      

10.Collection接口

分类 Collection 接口 所有集合的父类

  • List 子接口 ArrayList LinkedList

  • Set 子接口 HashSet LinkedHashSet

  • package com.itheima._11Collection概述;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Collection;
    
    /**
        目标:掌握Collection集合的常用功能(方法)
    
        讲解:
            1. Collection集合常用方法
                 public boolean add(E e) : 把给定的对象添加到当前集合中 。
                 public void clear() :清空集合中所有的元素。
                 boolean remove(E e) : 将给定的对象从集合中删除。
                 boolean contains(E e) : 判断当前集合中是否包含给定的对象。
                 public boolean isEmpty() : 判断当前集合是否为空。
                 public int size() : 返回集合中元素的个数。
                 public Object[] toArray() : 把集合中的元素,存储到数组中。
    
        小结
            1. Collection集合常用功能有哪些?
                 add
                 remove
                 clear
                 contains
                 isEmpty
                 size
                 toArray
     */
    public class Demo11 {
        public static void main(String[] args) {
            // 创建集合对象
            Collection<String> list =  new ArrayList<>();
            // public boolean add(E e) : 把给定的对象添加到当前集合中 。
            list.add("aaa");
            list.add("bbb");
            list.add("ccc");
            System.out.println(list); // [aaa, bbb, ccc]
    
            // boolean remove(E e) : 将给定的对象从集合中删除。
            System.out.println(list.remove("ccc")); // true
            System.out.println(list); // [aaa, bbb]
    
            // boolean contains(E e) : 判断当前集合中是否包含给定的对象。
            System.out.println(list.contains("bbb")); // true
    
            // public boolean isEmpty() : 判断当前集合是否为空。
            System.out.println(list.isEmpty()); // false
    
            // public int size() : 返回集合中元素的个数。
            System.out.println(list.size()); // 2
    
            // public Object[] toArray() : 把集合中的元素,存储到数组中。
            // Object[] objs = new Object[list.size()]
            // return objs;
            Object[] objs = list.toArray();
            System.out.println("objs ==> " + Arrays.toString(objs));
    
            // public void clear() :清空集合中所有的元素。
            list.clear();
            System.out.println(list); // []
    
    
        }
    }
    

11.泛型

A.泛型回顾

package com.itheima._12泛型回顾;

import java.util.ArrayList;

/**
    目标:理解集合中使用泛型的好处

    讲解:
        1. 集合不使用泛型存在问题
            集合可以存储任意类型的数据,在遍历集合获取元素时,元素类型都是Object类型
            如果要调用子类特有的方法,需要向下转型,且还需要做判断。

        2. 集合使用泛型的好处
            * 将运行时错误转换为编译时错误。
            * 省去了数据类型转换的麻烦

    小结:
        1. 集合使用泛型的好处
             * 将运行时错误转换为编译时错误。
             * 省去了数据类型转换的麻烦
 */
public class Demo121 {
    public static void main(String[] args) {
        // 在JDK1.5之前:创建集合对象
        // ArrayList list = new ArrayList();

        // 在JDK1.5之后:创建集合对象
        ArrayList<String> list = new ArrayList();
        // 添加元素
        list.add("a");
        list.add("b");
        list.add("c");
        // list.add(123);

        // 使用普通for遍历
        for(int index = 0;index < list.size(); index ++){
           /* // 根据索引获得元素
            Object obj = list.get(index);
            // 向下转型为字符串
            String str = (String) obj;
            System.out.println(str.length());*/


            String str = list.get(index);
            System.out.println(str.length());
        }
    }
}
  • 父类obj 不能用子类特有的方法之类的 所以要向下转型

  • 或者 判断 是否是String 用if( obj instanceof String )

  • 加入泛型 不需要做任何判断或者强制转换

B.泛型与泛型类

package com.itheima._13泛型类;

import java.util.Arrays;

/**
    目标:能够定义和使用泛型类

    讲解:
        1. 泛型概述
            * 概念:数据类型参数化,JDK1.5新特性
            * 泛型可以使用在方法上,类上,接口上。
            * 泛型变量命名规则:只要是合法的标识符就可以,但一般使用一个大写字母
                 常用的大小字母:T type,K key,V value,E element
            * 泛型变量可以理解为是某种数据类型的占位符


        2. 泛型类概念
            在定义类时定义了泛型变量的类

        3. 泛型类定义格式
            class 类名<T>{
                在类中可以将泛型变量T当成一种数据类型使用
            }

        4. 泛型类使用注意事项
            * 泛型变量的具体数据类型是由对象创建者在创建对象时指定。
            * 如果没有指定泛型变量的具体数据类型,则默认是Object

    小结:
        1. 泛型类定义格式:
            class 类名<泛型变量>{ }

        2. 如何使用泛型类
            创建泛型类对象时给泛型变量赋值
            格式:泛型类名<具体数据类型> 变量名 = new 泛型类名();
 */
public class Demo13 {
    public static void main(String[] args) {
        // 创建字符串数组
        String[] strs = {"1","2","3"};
        // 创建整型数组
        Integer[] ins = {4,5,6};

        // 创建MyArrays对象:指定泛型变量为String
        MyArrays<String> array01 = new MyArrays<>();
        array01.reverse(strs);

        // 创建MyArrays对象:指定泛型变量为Integer
        MyArrays<Integer> array02 = new MyArrays<>();
        array02.reverse(ins);

        // 创建MyArrays对象:不指定泛型变量类型
        MyArrays array03 = new MyArrays();
    }

    public static class MyArrays<T>{
        /**
         * 反转数组元素
         */
        public void reverse(T[] arr) {
            for(int i = 0,j = arr.length - 1;i < j; i++,j--) {
                T temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
            System.out.println(Arrays.toString(arr));
        }


        /**
         * 将数组元素拼接成字符串
         */
        public String toString(T[] arr) {
            StringBuilder sb = new StringBuilder("[");
            for (T t : arr) {
                sb.append(t).append(",");
            }
            sb.deleteCharAt(sb.length()-1);
            sb.append("]");
            return sb.toString();
        }
    }
}

C.泛型方法

package com.itheima._14泛型方法;

import java.util.Arrays;

/**
    目标:能够定义和使用泛型方法

    讲解:
        1. 泛型类的缺点:创建类对象时确定类型之后,只能使用这种类型了。

        2. 泛型方法的概念
            定义方法时定义了泛型变量的方法

        3. 泛型方法的定义格式
            修饰符 <T> 返回值类型 方法名(参数列表){
                可以将T当成一种数据类型在方法中使用:方法参数,方法返回值,方法体中
            }

        4. 泛型方法的注意事项
            * 泛型变量的具体数据类型时由调用者传参决定。
            * 泛型方法上定义的泛型变量一般都会使用在参数列表上
            * 静态方法不能使用类上定义的泛型变量,如果静态方法中需要使用泛型变量,则只能
                将该方法定义为泛型方法。
    小结:
        1.泛型方法的定义格式: 修饰符 <T> 返回值类型 方法名(参数列表){ }
        2.泛型方法的好处:可以让同一个方法处理多种类型的数据

 */
public class Demo14 {
    public static void main(String[] args) {
        // 创建字符串数组
        String[] strs = {"a","b"};
        // 创建整型数组
        Integer[] ins = {1,2,3};

        MyArrays.reverse(strs);
        MyArrays.reverse(ins);
        //static可以由类.方法

        System.out.println(Arrays.toString(strs));
        System.out.println(Arrays.toString(ins));
    }

    public static class MyArrays{
        /**
         * 反转数组元素:泛型方法
         */
        public static <E>  void reverse(E[] arr) {
            for(int i = 0,j = arr.length - 1;i < j; i++,j--) {
                E temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
    }


}

D.泛型接口

package com.itheima._15泛型接口;

/**
  泛型接口
  数据访问层:对数据库进程增删改查操作的
 */
public interface Dao<T> {
    void save(T t);
    void update(T t);
    void delete(int id);
    T findById(int id);
}
package com.itheima._15泛型接口;

/**
 * 实现接口时不指定泛型变量的具体数据类型,此时需要将实现类定义为泛型类
 */
public class BaseDao<T> implements  Dao<T> {
    @Override
    public void save(T t) {

    }

    @Override
    public void update(T t) {

    }

    @Override
    public void delete(int id) {

    }

    @Override
    public T findById(int id) {
        return null;
    }
}
package com.itheima._15泛型接口;

/**
    目标:能够定义和使用泛型接口

    讲解:
        1. 泛型接口概念
            在定义接口时定义了泛型变量的接口

        2. 泛型接口的定义格式
            interface 接口名<T>{
                在接口中可以将T当成一种数据类型使用
            }

        3. 泛型接口的实现方式
            * 方式1:实现接口同时指定泛型变量的具体数据类型
            * 方式2:实现接口时不指定泛型变量的具体数据类型,
                    此时需要将实现类定义为泛型类(推荐使用,比较灵活)
    小结:
        1.泛型接口的格式
            interface 接口<T>{ }

        2.泛型接口实现方式
             * 方式1:实现接口同时指定泛型变量的具体数据类型
             * 方式2:实现接口时不指定泛型变量的具体数据类型,
             此时需要将实现类定义为泛型类(推荐使用,比较灵活)
 */
public class Demo15 {
    public static void main(String[] args) {
        // 创建StudentDao类对象
        StudentDao stuDao = new StudentDao();
        stuDao.save(new Student());
        stuDao.findById(1);

        //  创建ProductDao类对象
        ProductDao productDao = new ProductDao();
        productDao.save(new Product());
        productDao.findById(1);

        // 创建BaseDao对象指定泛型变量:Student
        BaseDao<Student> dao01 = new BaseDao<>();
        dao01.save(new Student());

        // 创建BaseDao对象指定泛型变量:Product
        BaseDao<Product> dao02 = new BaseDao<>();
        dao02.save(new Product());

    }
}
package com.itheima._15泛型接口;

/**
 * 方式1:实现接口同时指定泛型变量的具体数据类型
 */
public class StudentDao implements Dao<Student> {

    @Override
    public void save(Student student) {
        System.out.println("保存学生...");
    }

    @Override
    public void update(Student student) {
        System.out.println("更新学生...");
    }

    @Override
    public void delete(int id) {
        System.out.println("根据id删除学生...");
    }

    @Override
    public Student findById(int id) {
        System.out.println("根据id查询学生...");
        return new Student();
    }
}
package com.itheima._15泛型接口;

public class ProductDao implements Dao<Product> {

    @Override
    public void save(Product product) {

    }

    @Override
    public void update(Product product) {

    }

    @Override
    public void delete(int id) {

    }

    @Override
    public Product findById(int id) {
        return null;
    }
}
package com.itheima._15泛型接口;

public class Student {
}



package com.itheima._15泛型接口;

public class Product {
}

12.泛型上下限 通配符?

  • 通配符 ?可以匹配任意类型的数据

  • package com.itheima._16泛型上下限;
    
    import com.itheima._15泛型接口.Student;
    
    import java.util.ArrayList;
    
    /**
        目标:理解泛型通配符?的含义
    
        讲解:
            1. 多态语法回顾
                父类类型 变量名 = new 子类类名();
    
            2. 通配符?的含义:可以匹配任意类型的数据
    
            3. 泛型通配符使用场景演示
                * 需求:定义一个方法接收ArrayList集合,方法功能:遍历打印集合元素。
    
        小结:
            1. 泛型通配符?的含义:可以匹配任意类型的数据
     */
    public class Demo161 {
        public static void main(String[] args) {
            // 多态语法:父类类型 变量名 = new 子类类名();
    
            // 在JDK1.7之前,两边的<>都必须写上数据类型,而且必须两边一致。
            // 在泛型中没有多态的概念
            ArrayList<Object> list01 = new ArrayList<Object>();
            ArrayList<String> list02 = new ArrayList<String>();
            ArrayList<Student> list03 = new ArrayList<Student>();
    
            ArrayList<?> list04 = new ArrayList<String>();
            ArrayList<?> list05 = new ArrayList<Double>();
            ArrayList<?> list06 = new ArrayList<Student>();
    
            printArrayList(list01);
            printArrayList(list02);
            printArrayList(list03);
            printArrayList(list04);
            printArrayList(list05);
            printArrayList(list06);
        }
    
        // 需求:定义一个方法接收ArrayList集合,方法功能:遍历打印集合元素。
        // ArrayList<?> list = new ArrayList<Object>();
        public static void printArrayList(ArrayList<?> list){
            for (int i = 0; i < list.size(); i++) {
                System.out.println(list.get(i));
            }
        }
    }
    
  • 泛型上下限

    • 泛型上限 一根线上面不能传 <? extends Animal > 可以传递 animal的子类或者animal本身
    • 泛型下限 <? super Animal > 可以传递animal的父类或者animal本身
  • 通配符?注意事项

    • 一般不会单独使用 会结合泛型上下限使用哦

    • 也不能用来定义泛型类 方法 变量

    • package com.itheima._16泛型上下限;
      
      import java.util.ArrayList;
      
      /**
          目标:理解泛型上下限含义
      
          讲解:
              1. Animal类型的继承体系
                        Object
                           |
                        Animal
                         /  \
                        /    \
                      Dog    Cat
      
              2. 需求:
                  * 定义方法接收ArrayList集合:存储动物对象。
                  * 方法中遍历集合调用动物的eat方法。
      
              3. 泛型上限
                  ? extends Animal :可以传递Animal类型及其子类类型数据
      
              4. 泛型下限
                  ? super Animal: 可以传递Animal类型及其父类类型数据
      
              5. 注意事项:
                  * 通配符?一般不会单独使用,会结合泛型上下限使用。
                  * 通配符?不能用来定义泛型类,泛型方法,泛型接口.
      
          小结:
              1. <? extends Animal> 的含义? 泛型上限,可以传递Animal及其子类数据
              2. <? super Animal> 的含义? 泛型下限,可以传递Animal及其父类数据
       */
      public class Demo162 {
          public static void main(String[] args){
              // 创建集合对象
              ArrayList<Object> list01 = new ArrayList<>();
      
              ArrayList<Animal> list02 = new ArrayList<Animal>();
              ArrayList<Dog> list03 = new ArrayList<>();
              ArrayList<Cat> list04 = new ArrayList<>();
      
              // feedAnimal(list01);
              feedAnimal(list02);
              feedAnimal(list03);
              feedAnimal(list04);
      
              feedAnimal02(list01);
              feedAnimal02(list02);
              // feedAnimal02(list03);
              // feedAnimal02(list04);
          }
      
          /*
           * 定义方法接收ArrayList集合:存储动物对象。
           * 方法中遍历集合调用动物的eat方法。
           */
          public static void feedAnimal02(ArrayList<? super Animal> list){
              for (int i = 0; i < list.size(); i++) {
                  // 根据索引获得元素
                  Object an = list.get(i);
                  // an.eat();
              }
          }
      
          /*
           * 定义方法接收ArrayList集合:存储动物对象。
           * 方法中遍历集合调用动物的eat方法。
           */
          public static void feedAnimal(ArrayList<? extends Animal> list){
              for (int i = 0; i < list.size(); i++) {
                  // 根据索引获得元素
                  Animal an = list.get(i);
                  an.eat();
              }
          }
      
      }
      

15.总结

package com.itheima._17教学目标小结;

/**

 - 能够使用日期类输出当前日期
    Date d = new Date();

 - 能够使用将日期格式化为字符串的方法
       DateFormat类方法:String format(Date d) 日期转字符串

 - 能够使用将字符串转换成日期的方法
      DateFormat类方法:Date parse(String str) 字符串转换日期对象

    1. 创建日期格式对象并指定日期模式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    2. 调用日期格式对象的方法进行字符串和日期对象的相互转换
        * DateFormat类方法:String format(Date d) 日期转字符串
        * DateFormat类方法:Date parse(String str) 字符串转换日期对象

 - 能够使用System类的数组复制方法
    System.arraycopy(源数组,源数组起始索引,目标数组,目标数组起始索引,复制元素的个数)

 - 能够使用System类获取当前毫秒时刻值
    long time = System.currentTimeMillis();

 - 能够说出使用StringBuilder类可以解决的问题
    解决字符串拼接耗时间和耗内存的内容

 - 能够使用StringBuilder进行字符串拼接操作
    StringBuilder append(数据类型 变量名);

 - 能够说出8种基本类型对应的包装类名称
    除了int和char特殊,其他都是基本类型名称首字母大写即可
    int ==> Integer
    char ==> Character

 - 能够说出自动装箱、自动拆箱的概念
    自动装箱:自动将基本数据类型转换为包装类类型
    自动拆箱:自动将包装类类型转换为基本数据类型

 - 能够将字符串转换为对应的基本类型
    int num = Integer.parseInt("100");
    .....

 - 能够将基本类型转换为对应的字符串
    String str = Integer.toString(100);
    String str01 = 100+"";

 - 能够说出Collection集合的常用功能
    add
    remove
    clear
    contains
    isEmpty
    toArray
    size

 - 能够使用泛型创建集合对象
    ArrayList<String> list = new ArrayList<>()

 - 能够理解泛型上下限
    <? extends Animal>
    <? super Animal>

 - 能够阐述泛型通配符的作用
    ? :可以匹配任意类型数据



 知识回顾
    多态格式:父类引用 变量名 = new 子类类名()
    多态的使用场景
        * 作为方法参数:可以接收多种子类类型的数据(对象)
        * 作为方法返回值:可以返回多种子类类型的数据(对象)
    多态的转型
        向上转型:父类引用 变量名 = new 子类类名()
        向下转型:子类类名 变量名 = (子类类名)父类引用
        instanceof:判断父类引用指向哪种子类类型的数据
        instanceof格式:boolean result = 父类引用 instanceof 子类类名;

    匿名内部类格式
        new 类名(){ }  直接创建已知类的子类对象
        new 接口名(){ } 直接创建已经接口的实现类对象

    静态代码块格式
        static { }  类加载时会自动执行1次,常用初始化资源

    Object类特点:所有类父类
        String toString();  默认返回格式:类全名字符串@对象地址值
        boolean equals(Object obj); 默认比较对象地址值判断

    今天
        1. 常用API:Application Progromming Interface 应用程序编程接口
            Date/DateFormat/Calendar/System/BigDecimal/StringBuilder/包装类
            自动装箱和自动拆箱
            Collection集合

        2. 泛型
            泛型在集合中的应用
            泛型类/泛型方法/泛型接口
            泛型上下限

  

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值