Java advanced --- the use of generics

1. The concept of generics

1. What is generic, as it seems on the surface, generic refers to a wide and common type
2. The so-called generic type allows you to indicate the type of a certain attribute in a class or a certain type through a round mark when defining a class or interface The return value and parameter type of each method.

This parameter type will be determined when it is used.

What are the benefits of using generics

(1) First, just like the above example, the use of generics can limit the types of elements in a collection, such as List and Set, to ensure that there is only one type in a collection.
(2) The program can also be more robust (as long as there is no warning during compilation, then there will be no ClassCastException during runtime)

Second, the use of generics

1. New features in jdk5.0

2. Use generics in collections

① In the collection interface or collection class in jdk5.0 are modified to a structure with generics.
② when instantiating collection classes, can specify the type of generic
③ After specified, when all classes and interfaces defined, to use the position of the internal structure of the generic class in the class or interface in the set, are specified when instantiated The generic type of For
example: add (E e) -----> add (Integer e) after instantiation
④Generic type must be a class, not a basic data type Use it when you need to use a basic data type The packaging class
⑤ If you do not specify a generic type when instantiating, the default is Object type

3. Custom generic structure: generic class, generic interface, generic method

4. Note on custom generics

Before using generics in a collection:

 ArrayList list  = new ArrayList();

        list.add(10);
        list.add(20);
        list.add(30);
        list.add(40);
        list.add(50);
        //其他类型出现
        //问题一、类型不安全
//        list.add("Tom");

        for (Object score : list){
            //问题2:出现异常,ClassCastException
            int stuScore = (int)score;
            System.out.println(stuScore);
        }

When using generics in a collection:

Generic is a type, but it cannot be a basic data type, so you need to use a wrapper class

 ArrayList<Integer> list = new ArrayList<Integer>();

        list.add(60);
        list.add(70);
        list.add(80);
        list.add(90);
        list.add(100);
        //编译时,就会进行类型检查,保证数据的安全性
//        list.add("Tom");
        //方式一
        for (Integer score:list){
            //避免了强转出现的异常
            int stuScore = score;
        }
        //方式二
        Iterator<Integer> iterator = list.iterator();
        while (iterator.hasNext()){
//            System.out.println(iterator.next());
            int next = iterator.next();
            System.out.println(next);
        }

The use of generics in collections: take HashMap as an example

 Map<String,Integer> map = new HashMap<String ,Integer>();

        map.put("Tom",123);
        map.put("Tom1",123);
        map.put("Tom2",456);
        map.put("Tom3",789);
        map.put("Tom4",159);
        //编译错误
        //        map.put(741,"Tmo5")

        //泛型的嵌套Entry为Map的内部接口
        Set<Map.Entry<String, Integer>> entries = map.entrySet();

        Iterator<Map.Entry<String, Integer>> iterator = entries.iterator();

        while (iterator.hasNext()){
            Map.Entry<String, Integer> next = iterator.next();
            System.out.println(next);//Tom=123键值
            String key = next.getKey();
            Integer value = next.getValue();
            System.out.println("key = " + key + ",value = " + value);//key = Tom,value = 123 键和值
        }

Three, custom generic class

Note:
Insert picture description here
Insert picture description here
custom generic class

public class Order<T> {
    String orderName;
    int orderId;
    //类的内部结构,就可以使用类的泛型

    T orderT;
    public Order(){
        //编译不通过
//        T[] arr =   new T[20]
    }

    public Order(String orderName,int orderId,T orderT){
        this.orderName =orderName;
        this.orderId =orderId;
        this.orderT = orderT;
    }

    public String getOrderName() {
        return orderName;
    }

    public void setOrderName(String orderName) {
        this.orderName = orderName;
    }

    public int getOrderId() {
        return orderId;
    }

    public void setOrderId(int orderId) {
        this.orderId = orderId;
    }

    //如下的三个方法都不是泛型方法
    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 static void show(T orderT){
//        System.out.println(orderT);
//    }
    public void show(){
        //编译不通过,泛型不能时异常类型
//        try {
//
//        }catch (T t){
//
//        }
    }
    //泛型方法,在方法中出现了泛型的结构,泛型的参数与类的泛型参数没有任何关系。
//    public static  <E> List<E> copy(E[] arr){}
    //泛型方法,在不在泛型类中都没有关系
    //泛型方法可以是静态的:原因:泛型参数是在调用时确定的,并不是在实例化时确定的。
    public static <E> List<E> copy(E[] arr){
        ArrayList<E> list = new ArrayList<>();
        for (E e:arr){
            list.add(e);
        }
        return list;
    }
}


Not a generic class but just inherited the generic

public class SubOrder extends Order<Integer> {//不是泛型类
    //泛型方法,在不在泛型类中都没有关系
    public static <E> List<E> copy(E[] arr){
        ArrayList<E> list = new ArrayList<>();
        for (E e:arr){
            list.add(e);
        }
        return list;
    }
}

This is also a generic class

public class SubOrder1 extends Order {// generic class
}

1. If a generic class is defined and the generic type of the class is not specified during instantiation, the type of the generic type is considered to be Object
//        Order order = new Order();
//        order.setOrderT(123);
//        order.setOrderT("ABC");

        //要求,如果定义了为带泛型的类,建议在实例化时要指明泛型的类型
//        Order<Integer> order = new Order<Integer>();
//        order.setOrderT(123);
        //带上泛型后,指明了类型
//        order.setOrderT("ABC");

        Order<String> order = new Order<>("orderAA", 1001, "order:AA");
        order.setOrderT("AA:hello");
//        order.setOrderT(123);
2. Since the subclass specifies the type of the generic when inheriting the parent class with generics, it is no longer necessary to specify the type of the generic when the subclass is instantiated
	    SubOrder subOrder = new SubOrder();
        subOrder.setOrderId(123);

        SubOrder1<Integer> subOrder1 = new SubOrder1<Integer>();
//        subOrder1.setOrderT("AA");
        subOrder1.setOrderT(123);
3. References with different generic types cannot be copied from each other
    ArrayList<Integer>  list1 = null;
    ArrayList<String >  list2 = null;
    //编译报错,类型不同

// list1 = list2;

4. Test Generic Methods
 Order<String> order = new Order<>();
        Integer[] arr = new Integer[]{1,2,3,4};
        //泛型方法在调用时,指明泛型参数的类型
        List<Integer> copy = order.copy(arr);//自定义泛型类中有该方法
        System.out.println(copy);//[1, 2, 3, 4]

Fourth, the embodiment of generics in inheritance

Although class A is the parent class of class B, both G <A> and G <B> are not parent classes, and they are in a parallel relationship.
Class A is the parent class of class B.

 @Test
   public void test(){
       Object obj = null;
       String str = null;
       obj = str;

       List<Object> list1 = null;
       List<String> list2 = null;
       //编译错误,类型不具备子父的关系
//        list1 = list2

       show(list1);
       show1(list2);

   }
   public void show(List<Object> list){
   }
   public void show1(List<String> list){
   }

The same type, no error will be reported when compiling

    List<String > list = null;
    ArrayList<String> list1 = null;
   
       list = list1;
Use wildcards:?

Class A is the parent class of class B, but G <A> and G <B> are in a parallel relationship, and the common parent class for both is G <?>

  List<Object> list1 = null;
        List<String> list2 = null;

        List<?> list = null;

        list = list1;
        list = list2;
        //编译通过
//        print(list1);
//        print(list2);

        //使用通配符后,数据的读写要求
        List<String > list3 = new ArrayList<>();
        list3.add("AA");
        list3.add("BB");
        list3.add("CC");

        list =list3;
        //添加(写入)报错,对于List<?>就不能向其内部添加数据,除了null以外
//        list.add("DD");
          list.add(null);

        //获取(读取):允许读取数据,读取的类型为Object
        Object o = list.get(0);
        System.out.println(o);
        
 public void print(List<?> list){
        Iterator<?> iterator = list.iterator();
        while (iterator.hasNext()){
            Object next = iterator.next();
            System.out.println(next);
        }
    }
Use of wildcards with restrictions

Student class inherits from Person
? Extends Person
? Super Student

? extends A: G <? extends A> can be regarded as the parent class of G <A> and G <B>, where B is a subclass of A
? super A: G <? super A> can be used as G <A> and The parent class of G <B>, where B is a subclass of A

Practice, if traversing the key set, value set, key-value set of Map, use the generic
  Map<String,Integer> map = new HashMap<String ,Integer>();
        map.put("Tom",123);
        //获取key集
        Set<String> strings = map.keySet();
        for (String key:strings){
            System.out.println(key);
        }
        //遍历value集
        Collection<Integer> values = map.values();
        Iterator<Integer> iterator = values.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
        //遍历key-value集
        Set<Map.Entry<String, Integer>> entries = map.entrySet();
        Iterator<Map.Entry<String, Integer>> iterator1 = entries.iterator();
        while (iterator1.hasNext()){
            Map.Entry<String, Integer> next = iterator1.next();
            String key = next.getKey();
            Integer value = next.getValue();
            System.out.println(key +" +++++++++ " + value);
        }


        //提供一个方法用于遍历获取HashMap<String,String>中的所有value,并存放到list集合中返回,使用泛型
        public List<String> getValueList(HashMap<String,String> map){
        ArrayList<String > valueList = new ArrayList<>();
        Collection<String> values =map.values();
        for (String value :values){
            valueList.add(value);
        }
        return valueList;
    }

Fifth, the use scenarios of generics in development

DAO: data (base) access object

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;
    }
}

Published 19 original articles · praised 0 · visits 477

Guess you like

Origin blog.csdn.net/weixin_43244120/article/details/105604520
Recommended