栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java泛型、枚举和静态导入

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java泛型、枚举和静态导入

文章目录
        • 泛型
          • 定义
            • 概念:
            • 语法:
          • 深入了解
            • 泛型接口,类,方法
            • 泛型方法和可变参数
            • 泛型的继承
            • 通配符
          • 泛型上下界:
            • 上界 <= 【extends】
            • 下界 >= 【super】
          • 泛型嵌套
          • 注意:
            • static和泛型:
            • 泛型和数组
            • 泛型没有多态,泛型没有数组
        • 枚举类
          • 定义理解
            • 概念:
            • 语法:
            • 注意:
          • 使用
          • 枚举和switch
            • 说明
            • 示例
          • java.lang.Enum
          • 枚举类
          • EnumMap 与 EnumSet
            • EnumMap 类
            • EnumSet
        • 静态导入
          • 理解
          • 使用
        • lambda表达式
          • 简介
            • 概念:
            • 理解:
          • 使用
            • 接口的实现
            • 语法
            • 函数式编程接口
          • lambda表达式的特征
        • 可变参数:
          • 定义
          • 特点

泛型

JDK1.5加入的新特性,泛型的本质是参数化类型,即操作的数据类型被指定为一个参数。安全简单,且所有的强制类型转换都是隐式和自动进行的,提高代码的重用率。

定义 概念:

将对象类型作为参数,指定到其它类或者方法上,从而保证类型转换的安全性和稳定性。

语法:

类型 对象 = new 类型();

  • 解析:
    • <> 是泛型的特征
    • E 表示某种数据类型,也可用其它字母,实际使用中需要用明确类型换掉 E
深入了解 泛型接口,类,方法
  • 泛型接口:

    • 泛型接口与泛型类的定义及使用基本相同。泛型接口常被用在各种类的生产器中。

    • 只能用在抽象方法上

    • public interface Generator {
          public T next();
      }
      
      
      class FruitGenerator implements Generator{
          @Override
          public T next() {
              return null;
          }
      }
      
  • 泛型类:

    • 用于类的定义中,被称为泛型类

    • 最典型的就是各种容器类,如:List、Set、Map

    • 只能用在成员变量上,只能使用引用类型

    • class 类名称 {
        .....
      }
      
    • 泛型类,是在实例化类的时候指明泛型的具体类型;泛型方法,是在调用方法的时候指明泛型的具体类型 。

  • 泛型方法

    • 是在调用方法的时候指明泛型的具体类型 。

    • 返回值前面加上

    • public  T genericMethod(Class tClass)throws InstantiationException ,
        IllegalAccessException{
              T instance = tClass.newInstance();
              return instance;
      }
      
泛型方法和可变参数
  • public  void printMsg( T... args){
        for(T t : args){
            Log.d("泛型测试","t is " + t);
        }
    }
    
泛型的继承
  • package com.bigdata.practice1011;
    
    public abstract class FanXin {
        T1 name;
        public abstract void setName(T2 sex);
    }
    
  • 保留父类泛型

    • // 全保留
      package com.bigdata.practice1011;
          // 泛型父类 子类全部保留父类的泛型
      public class FanXin1 extends FanXin{
          @Override
          public void setName(T2 sex) {
              
          }
      }
      
      // 保留一个
      package com.bigdata.practice1011;
          // 继续全写泛型不合适 得把用的那个泛型写成具体类型
      public class FanXin2 extends FanXin {
          @Override
          public void setName(String sex) {
              
          }
      }
      
  • 不保留父类泛型

    • package com.bigdata.practice1011;
          // 不保留父类的泛型
              // 父类的泛型显示
              // 泛型擦除:实现或继承父类的子类没有指定类型 类似于Object【不等于Object,编译不通过】
      
      public class FanXin3 extends FanXin{
          @Override
          public void setName(Object sex) {
      
          }
      }
      class FanXin4 extends FanXin{
          @Override
          public void setName(Integer sex) {
      
          }
      }
        
    • 子类重写父类的方法,泛型类型随父类而定 子类使用父类的属性,该属性类型随父类定义的泛型

    • 通配符
      • T、K、V、E 等泛型字母为有类型,类型参数赋予具体的值
      • ?未知类型 类型参数赋予不确定值,任意类型
      • 只能用在声明类型、方法参数上,不能用在定义泛型类上
      泛型上下界: 上界 <= 【extends】
      • 语法:? extends List
      • 范围:指定的类必须是继承某个类,或者实现了某个接口(不是implements),即<=
      • 注意:一般用于限制操作 不能使用在添加数据上,一般都是用于数据的读取
      下界 >= 【super】
      • 语法:? super List
      • 范围: 即父类或本身
      • 注意:一般用于下限操作
      大概阅读源码理解一下就好了!
      
      泛型嵌套

      HashMap使用了泛型的嵌套

      	Map map =  new HashMap();
          map.put("a", "张三");
          map.put("b", "李四");
          Set> set = map.entrySet();
          for (Entry entry : set) {
           System.out.println(entry.getKey()+":"+entry.getValue());
          }
      
      注意: static和泛型:

      静态方法有一种情况需要注意一下,那就是在类中的静态方法使用泛型:静态方法无法访问类上定义的泛型;如果静态方法操作的引用数据类型不确定的时候,必须要将泛型定义在方法上。即使该类已经定义为泛型类。

      // 泛型参数T2其实没用 静态方法的泛型T2和类定义的泛型T2没有任何关系
      public class FanXin {
          T1 name;
      
          public static  T2 get(T2 name){
              T2 t2 = name;
              return t2;
          };
      }
      
      泛型和数组

      不能创建一个确切的泛型类型的数组,使用通配符创建泛型数组是可以的

      List[] ls = new ArrayList[10]; // 不行
      List[] ls = new ArrayList[10];  // 可以
      List[] ls = new ArrayList[10];  // 可以
      
      泛型没有多态,泛型没有数组 枚举类 定义理解 概念:

      JDK1.5引入的一种新类型枚举(Enum),是指一组固定常量组成的类型。其实是一种类型,是java.lang.Enum的子类。

      如果学过单例模式,我们可以理解为枚举就是多例模式,一个类有多个实例,但实例个数不是越多越好的,是有限的。

      语法:
      修饰符 enum 枚举名{
      	枚举常量值1;
      	枚举常量值2;
      }
      // 调用
      枚举名.枚举常量值1;
      
      注意:
      • enum 是关键字,小写的 ;
      • 枚举型其实就是本类的实例;
      • 多个枚举项之间使用逗号分隔,最后一个枚举项需要给出分号!如果只有枚举项(没有构造器,方法,实例变量)则可以省略分号。
      • 不可使用new来创建枚举类对象,枚举类的枚举项就是实例,所以在外面用类面点来调用
      使用

      通常用枚举表示一组常用且个数有限的值,用于实现对输入值进行约束检查

      内部类的形式去给到性别属性的控制:

      package com.bigdata.practice1008;
      
      
      public class Person {
      
          private String name;
          private int age;
          private sexType sex;
          private T personType;
      
          public Person() {
      
          }
      
          enum sexType{
              男,女
          }
      
          public Person(String name, int age, sexType sex, T personType) {
              this.name = name;
              this.age = age;
              this.sex = sex;
              this.personType = personType;
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public int getAge() {
              return age;
          }
      
          public void setAge(int age) {
              this.age = age;
          }
      
          public sexType getSex() {
              return sex;
          }
      
          public void setSex(sexType sex) {
              this.sex = sex;
          }
      
          public T getPersonType() {
              return personType;
          }
      
          public void setPersonType(T personType) {
              this.personType = personType;
          }
      
          public static  void printInfo(T st){
              System.out.println("泛型类中的静态方法!");
              if (st instanceof Student){
                  System.out.println("OK!");
              }
          }
      
          @Override
          public String toString() {
              return "Person{" +
                      "name='" + name + ''' +
                      ", age=" + age +
                      ", sex=" + sex +
                      ", personType=" + personType +
                      '}';
          }
      }
      
      枚举和switch 说明
      • switch中不可使用枚举类名称
      • 编译器会根据switch(s)中的s来确定每个枚举类型
      • case中直接使用枚举项
      示例
      public enum Signal{
      	RED, GREEN, BLANK, YELLOW; 
      }
      
      public class TrafficLight {  
          Signal color = Signal.RED;  
          public void change() {  
              switch (color) {  
              case RED:  
                  color = Signal.GREEN;  
                  break;  
              case YELLOW:  
                  color = Signal.RED;  
                  break;  
              case GREEN:  
                  color = Signal.YELLOW;  
                  break;  
              }  
          }  
      }
      
      java.lang.Enum

      Java 中的每一个枚举都继承自 java.lang.Enum 类。当定义一个枚举类型时,每一个枚举类型成员都可以看作是 Enum 类的实例,这些枚举成员默认都被 final、public, static 修饰,当使用枚举类型成员时,直接使用枚举名称调用成员即可

      方法名称描述
      values()以数组形式返回枚举类型的所有成员
      valueOf()将普通字符串转换为枚举实例
      compareTo()比较两个枚举成员在定义时的顺序
      ordinal()获取枚举成员的索引位置
      枚举类
      • 可以拥有自己的方法
      • 可以拥有自己的构造
      EnumMap 与 EnumSet

      为了更好地支持枚举类型,java.util 中添加了两个新类:EnumMap 和 EnumSet。使用它们可以更高效地操作枚举类型。

      EnumMap 类

      EnumMap 是专门为枚举类型量身定做的 Map 实现。虽然使用其他的 Map(如 HashMap)实现也能完成枚举类型实例到值的映射,但是使用 EnumMap 会更加高效。

      HashMap 只能接收同一枚举类型的实例作为键值,并且由于枚举类型实例的数量相对固定并且有限,所以 EnumMap 使用数组来存放与枚举类型对应的值,使得 EnumMap 的效率非常高。

      EnumSet
      • EnumSet 是枚举类型的高性能 Set 实现,它要求放入它的枚举常量必须属于同一枚举类型。EnumSet 提供了许多工厂方法以便于初始化。
      • allOf(Class element type) 创建一个包含指定枚举类型中所有枚举成员的 EnumSet 对象
      • complementOf(EnumSet s) 创建一个与指定 EnumSet 对象 s 相同的枚举类型 EnumSet 对象,并包含所有 s 中未包含的枚举成员
      • copyOf(EnumSet s) 创建一个与指定 EnumSet 对象 s 相同的枚举类型 EnumSet 对象,并与 s 包含相同的枚举成员
      • noneOf(
      • of(E first,e…rest) 创建包含指定枚举成员的 EnumSet 对象
      • range(E from ,E to) 创建一个 EnumSet 对象,该对象包含了 from 到 to 之间的所有枚举成员
      静态导入 理解

      在一个类中使用其它类的静态属性和静态方法时,需要静态导入。

      使用

      直接在前面用 import static 包名;导入,或者类名点去直接调用

      不推荐使用,有的时候同包不同类的同名函数或者同名参数不太好处理

      lambda表达式 简介 概念:

      lambda,其实是数学符号中的 λ,一个希腊字母。拉姆达 Lambda(大写Λ,小写λ),是第十一个希腊字母;在计算机术语中,Lambda 多表达式”是一个匿名函数,可以包含表达式和语句,并且可用于创建委托或表达式目录树类型。Java 8 引入的 Lambda 表达式的主要作用就是简化部分的写法。

      理解:
      • Lambda表达式本身就是一个接口的实现
      • 把“一块代码”赋给了一个变量。而“这块代码”,或者说“这个被赋给一个变量的函数”,就是一个Lambda表达式。

      以Lambda语法创建线程和匿名内部类创建线程的区别:

      @FunctionalInterface
      public interface Runnable {
          
          public abstract void run();
      }
      
      public static void main(String[] args) {
          // 用匿名内部类的方式来创建线程
          new Thread(new Runnable() {
              @Override
              public void run() {
                  System.out.println("我是一个线程啊");
              }
          });
      
          // 使用Lambda来创建线程
          new Thread(() -> System.out.println("我是一个线程啊"));
      }
      
      使用 接口的实现
      • 1.new实现类
      • 2.new接口自己匿名类借助
      • 3.lambda表达式【只能去实现一个抽象方法的接口,用 @FunctionalInterface 注解的接口】
      语法
      • 语法:(方法参数) -> {方法要实现的内容}

      • 1.语法格式一:无参,无返回值,Lambda 体只需一条语句。

        示例:

        Runnable r1 = () -> System.out.println("Hello Lambda!"); 
        

        2.语法格式二:Lambda 需要一个参数。

        示例:

        Consumer con = (x) -> System.out.println(x);
        

        3.语法格式三:Lambda 只需要一个参数时,参数的小括号可以省略。

        示例:

        Consumer con = x -> System.out.println(x);
        

        4.语法格式四:Lambda 需要两个参数,并且有返回值。

        示例:

        Comparator com = (x, y) -> {
           System.out.println("函数式接口");
           return Integer.compare(x, y);
        };
        

        5.语法格式五:当 Lambda 体只有一条语句时,return 与大括号可以省略。

        示例:

        Comparator com = (x, y) -> Integer.compare(x, y);
        

        6.Lambda的表达式的参数不用去显示声明类型,jvm ”上下文推断出“类型

      • 使用Labmda表达式需要函数式编程接口,接口上加上 @FunctionalInterface注解(标记着这个接口只有一个抽象方法)

      函数式编程接口

      接口上加上 @FunctionalInterface注解(标记着这个接口只有一个抽象方法)

      内部的函数式编程接口的学习和Stream流一起

      lambda表达式的特征
      • 可选的类型声明:不需要声明参数类型,编译器可以自动识别参数类型。
      • 可选的参数圆括号:一个参数无须使用圆括号,但多个参数则需要使用圆括号。
      • 可选的花括号:如果函数体只有一条语句,则不需要使用花括号。
      • 可选的返回关键字:如果函数体只有一条语句,则编译器会自动返回该语句执行的结果;如果有多条语句且有返回值,那么在花括号中需要使用return语句来返回结果。

      Lambda结合FunctionalInterface Lib, forEach, stream(),method reference等新特性可以使代码变的更加简洁!后面再来

      可变参数: 定义
      • A、 可变参数:适用于参数个数不确定,类型确定的情况,java把可变参数当做数组处理。
      • B、 注意:可变参数必须位于最后一项。
      特点
      • A、 只能出现在参数列表的最后;
      • B、 …位于变量类型和变量名之间,前后有无空格都可以;
      • C、 调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法体中以数组的形式访问可变参数。
      package com.bigdata.practice1011;
      
      public class ChangeParam {
      
      	public static void main(String[] args) {
      		append(25, new String[] {"AA", "Cc"});
      		append(34, "AA", "BB");
      	}
      	
      		
      	public static void append(int a, String... strs) {
      		StringBuilder sb = new StringBuilder();
      		for (int i = 0; i < strs.length; i++) {
      			System.out.println(strs[i]);
      			sb.append(strs[i]);
      		}
      		System.out.println(sb.toString());
      	}
      }
      

      调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法体中以数组的形式访问可变参数。

      package com.bigdata.practice1011;
      
      public class ChangeParam {
      
      	public static void main(String[] args) {
      		append(25, new String[] {"AA", "Cc"});
      		append(34, "AA", "BB");
      	}
      	
      		
      	public static void append(int a, String... strs) {
      		StringBuilder sb = new StringBuilder();
      		for (int i = 0; i < strs.length; i++) {
      			System.out.println(strs[i]);
      			sb.append(strs[i]);
      		}
      		System.out.println(sb.toString());
      	}
      }
      
      转载请注明:文章转载自 www.mshxw.com
      我们一直用心在做
      关于我们 文章归档 网站地图 联系我们

      版权所有 (c)2021-2022 MSHXW.COM

      ICP备案号:晋ICP备2021003244-6号