JAVA泛型

JAVA泛型

为什么要有泛型

在这里插入图片描述

集合不限制类型的问题:

public void test1(){
    ArrayList list = new ArrayList();

    list.add(78);
    list.add(76);
    list.add(77);
    list.add(99);
    //问题一:类型不安全
    list.add("sss");
    for (Object score:list){
        //问题二:强制转换时会出异常:ClassCastException
        int stuScore = (int) score;
        System.out.print(stuScore+"   ");
    }//78   76   77   99 
}
  • 使用泛型之后:(泛型不能用基本数据类型)
    public void test2() {
        ArrayList<Integer> list = new ArrayList<Integer>();

        list.add(78);
        list.add(76);
        list.add(77);
        list.add(99);
        //编译时就会进行类型检查,保证数据安全
        //list.add("sss");//此处会报错
        for (Integer score : list) {
            int stuScore = score;
            System.out.print(stuScore + "   ");
        }
        System.out.println();
        Iterator<Integer> iterator = list.iterator();
        while(iterator.hasNext()){
            int stuScore = iterator.next();
            System.out.print(stuScore + "   ");
        }
    }
  • Map中的泛型

    public void test3() {
        HashMap<String, Integer> map = new HashMap<String, Integer>();
        map.put("Meiko",99);
        map.put("Scout",80);
        map.put("Viper",80);
        map.put("Flandre",88);
        map.put("Jiejie",90);
        //map.put(11,"1esa");//报错
    
        Set<Map.Entry<String, Integer>> entry = map.entrySet();
        Iterator<Map.Entry<String, Integer>> iterator = entry.iterator();
        while (iterator.hasNext()){
            Map.Entry<String, Integer> entry1 = iterator.next();
            String key = entry1.getKey();
            Integer value = entry1.getValue();
            System.out.print(key+ " = " + value + "    ");
        }
    }
    

自定义泛型类

  • Order泛型类

    public class Order<T>  {
        String orderName;
        int orderId;
        //类的内部结构就可以使用类的泛型
        T orderT;
        public Order() {
        }
    
        public Order(String orderName, int orderId, T orderT) {
            this.orderName = orderName;
            this.orderId = orderId;
            this.orderT = orderT;
        }
    
        public T getOrderT() {
            return orderT;
        }
    
        public void setOrderT(T orderT) {
            this.orderT = orderT;
        }
    
        @Override
        public String toString() {
            return "Order{" +
                    "orderName='" + orderName + '\'' +
                    ", orderId=" + orderId +
                    ", orderT=" + orderT +
                    '}';
        }
    }
    
  • 测试

    public void test4() {
        //如果定义了泛型类,实例化没有指明类的泛型,则认为泛型的典型类型为Object类型
        Order<String> order = new Order<String>("AA",001,"333");
        System.out.println(order);
        //Order{orderName='AA', orderId=1, orderT=333}
    
    
    }
    
  • 子类继承父类

    public class SubOrder extends Order<Integer>{
    
    }
    
    public class SubOrder1<T> extends Order<T>{
    
    }
    
  • 测试

    public void test5() {
        SubOrder subOrder = new SubOrder();
        //由于子类在继承带泛型的父类时,指明了泛型类型,则实例化时不需要指明泛型
        //如:public class SubOrder extends Order<Integer>
        subOrder.setOrderT(1122);
        //subOrder.setOrderId("12321");//此处会报错
    
        //如果不指名泛型类型则需要指明
        //如:public class SubOrder1<T> extends Order<T>
        SubOrder1<String> subOrder1 = new SubOrder1<>();
        subOrder1.setOrderT("123");
        //subOrder1.setOrderT(123);//会报错
    
    
    }
    
  • 注意事项

在这里插入图片描述
在这里插入图片描述

自定义泛型方法:

在方法中出现了泛型的结构,泛型参数与类的泛型参数没有任何关系

即泛型方法所属的类是不是泛型类都没有关系

  • 定义示例:可以是静态方法

    原因:泛型方法中的泛型参数是在调用方法时确定的,并非是实例化时确定的,所以可以是静态方法

    public static <E> List<E> copyFromArrayToList(E[] arr){    //将此方法加在之前Order类的里面,可以是静态方法    ArrayList<E> list = new ArrayList<>();    for(E e:arr){        list.add(e);    }    return  list;}
    
  • 调用示例:泛型方法调用时,指明泛型参数的类型

    //测试泛型方法public void test5() {    Order<String> order = new Order<>();    Integer[] arr  = new Integer[]{1,2,3,4};    List<Integer> list = order.copyFromArrayToList(arr);    System.out.println(list);//[1, 2, 3, 4]}
    

使用用泛型类、泛型方法的实际情景

  • DAO: data(base) access object 数据访问对象
import java.util.List;public class DAO<T> {    //添加一条记录    public void add(T t){    }    //删除一条记录    public boolean remove(int index){        return false;    }    //修改一条记录    public void update(int index,T t){    }    //查询一条记录    public T getIndex(int index){        return null;    }    //查询多条记录    public List<T> getForList(int index){        return null;    }}
  • Customer类(相当于一个表)
public class Customer {//此类对应数据库中的一个表}
  • CustomerDAO类:指定该类只能对Customer进行相关操作

    public class CustomerDAO extends DAO<Customer>{}
    
  • Student类:相当于另一个表

    public class Student {}
    
  • StudentDAO类:指定该类只能对Student进行相关操作

    public class StudentDAO extends DAO<Student>{}
    
  • 泛型方法

    //泛型方法//举例:获取表中一共有多条记录?获取最大的员工入职时间public <E> E getValue(){    return null;}
    

泛型在继承方面的体现

  • 虽然类A是类B的父类,但是G 和G 二者不具备父子关系,二者是并列关系

    public void test1(){
        Object obj = null;
        String str = null;
    
        obj = str;//多态,子类可以赋值给父类
    
        Object[] arr1 = null;
        String[] arr2 = null;
        arr1 = arr2;//多态,子类可以赋值给父类
    
        List<Object> list1 = null;
        List<String> list2 = null;
        //list1 = list2;//此处报错,不能赋值,list1和list2的类型不具有子父类关系
        
    }
    
  • 补充:类(接口)A是类(接口)B的父类,A 是B 的父类

    public void test2(){
        List<String> list1 = null;
        ArrayList<String> list2 = null;
        list1 = list2;
    
    }
    

通配符的使用

通配符:?

类A是类B的父类,但是G 和G 二者不具备父子关系,二者共同的父类是 G<?>

 public void test3(){
        List<Object> list1 = null;
        List<String> list2 = null;

        List<?> list = null;

        //下面的程序可以编译通过
//        myPrint(list1);
//        myPrint(list2);
//        list = list1;
//        list = list2;

        //添加操作:(写入)
        //对于List<?>就不能向其内部添加数据,除了添加null之外
        ArrayList<String> list3 = new ArrayList<>();
        list3.add("AA");
        list3.add("BB");
        list3.add("CC");
        list = list3;
        list.add(null);

        //获取(读取):
        Object o = list.get(0);
        System.out.println(o);//AA

    }
    public void myPrint(List<?> list){
        Iterator<?> iterator = list.iterator();
        while(iterator.hasNext()){
            Object obj = iterator.next();
            System.out.println(obj);
        }

    }

有限制条件的通配符使用

  • ?extends A: (理解: (-∞,A)) 相当于<=

    G<? extends A> 的意思是:可以作为G和G的父类,其中B是A的子类

  • ? super A: (理解:(A,+∞)) 相当于>=

    G<? super A> 的意思是:可以作为G和G的父类,其中B是A的父类

public void test4(){
    List<? extends Person> list1 = null;
    List<? super  Person> list2 = null;

    List<Student> list3 = new ArrayList<Student>();
    List<Person> list4 = new ArrayList<Person>();
    List<Object> list5 = new ArrayList<Object>();

    list1 = list3;
    list1 = list4;
    //list1 = list5;//会报错

    //list2 = list3;//会报错
    list2 = list4;
    list2 = list5;

    //读取数据
    list1 = list3;
    Person p = list1.get(0);
        //Student stu = list1.get(0);//会报错

    list2 = list4;
    Object o = list2.get(0);
        //Person p1 = list2.get(0);//会报错


    //写入数据
          //list1.add(new Student());
         //会报错,父类不能赋值给子类,list1有可能是比Student更小的继承Person的子类,
    list2.add(new Student());//不会报错
    list2.add(new Person());

}

练习

  • 自定义泛型类DAO
 import java.util.*;
 
 public class DAO<T> {
     private Map<String,T> map = new HashMap<String,T>();
 
     public DAO() {
     }
 
     public DAO(Map<String, T> map) {
         this.map = map;
     }
 
     //保存T类型的对象到Map成员变量中
     public void save(String id,T entity){
 
         this.map.put(id,entity);
     }
     //从map 中获取id对应的对象
     public T get(String id){
         return this.map.get(id);
     }
 
     //替换map中的key为id的内容,改为entity对象
     public void update(String id,T entity){
         if(this.map.containsKey(id)){//判断是否有这个id
             this.map.put(id, entity);
         }
     }
 
     //返回map中存放的所有T对象
     public List<T> list(){
         ArrayList<T> listValues = new ArrayList<>();
         Collection<T> values = this.map.values();
         //不能使用强转去返回List
         //例如:return (List<T> )values
         //原因:一般强转需要先new的对象就是List,之后才能强转
         //例如 Collection c = new ArrayList();
         // ArrayList listValues = (ArrayList) c;
         Iterator<T> iterator = values.iterator();
         while(iterator.hasNext()){
             listValues.add(iterator.next());
         }
         return listValues;
     }
     //删除指定的id对象
     public void delete(String id){
         this.map.remove(id);
     }
 }
 
  • 自定义类
  /*
  定义一个user类
   */
  public class User {
      private int id;
      private int age;
      private String name;
  
      public User() {
      }
  
      public User(int id, int age, String name) {
          this.id = id;
          this.age = age;
          this.name = name;
      }
  
      public int getId() {
          return id;
      }
  
      public void setId(int id) {
          this.id = id;
      }
  
      public int getAge() {
          return age;
      }
  
      public void setAge(int age) {
          this.age = age;
      }
  
      public String getName() {
          return name;
      }
  
      public void setName(String name) {
          this.name = name;
      }
  
      @Override
      public String toString() {
          return "User{" +
                  "id=" + id +
                  ", age=" + age +
                  ", name='" + name + '\'' +
                  '}';
      }
  
      @Override
      public boolean equals(Object o) {
          if (this == o) return true;
          if (o == null || getClass() != o.getClass()) return false;
  
          User user = (User) o;
  
          if (id != user.id) return false;
          if (age != user.age) return false;
          return name != null ? name.equals(user.name) : user.name == null;
      }
  
      @Override
      public int hashCode() {
          int result = id;
          result = 31 * result + age;
          result = 31 * result + (name != null ? name.hashCode() : 0);
          return result;
      }
  }
  • 测试类
  import java.util.List;
  
  public class DAOTest {
      public static void main(String[] args) {
          DAO<User> dao = new DAO<User>();
  
          dao.save("1001",new User(1001,23,"XiaoHu"));
          dao.save("1002",new User(1002,20,"Wei"));
          dao.save("1003",new User(1003,20,"Cryin"));
          dao.save("1004",new User(1004,19,"Gala"));
          dao.save("1005",new User(1005,22,"Ming"));
  
          List<User> list = dao.list();
          for (User user : list) {
              System.out.println(user);
          }
          /*
          User{id=1005, age=22, name='Ming'}
          User{id=1004, age=19, name='Gala'}
          User{id=1003, age=20, name='Cryin'}
          User{id=1002, age=20, name='Wei'}
          User{id=1001, age=23, name='XiaoHu'}
           */
          System.out.println();
          dao.update("1002",new User(1002,19,"Wei"));
          dao.delete("1003");
          System.out.println("1001号的信息为:"+dao.get("1001"));
          List<User> list1 = dao.list();
          System.out.println("删除1003号之后的全员信息为:");
          for (User user : list1) {
              System.out.println(user);
          }
          /*
          User{id=1005, age=22, name='Ming'}
          User{id=1004, age=19, name='Gala'}
          User{id=1002, age=19, name='Wei'}
          User{id=1001, age=23, name='XiaoHu'}
           */
  
      }
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值