Han Shunping Java33 -- Generic

Posted by dsantamassino on Wed, 26 Jan 2022 13:33:39 +0100

generic

In a nutshell -- generics are data types that accept data types

1. Export of generic

 

 

  • Traditional methods:
package test;

import java.util.ArrayList;

/**
 * @author Purple English
 * @version 1.0
 */
public class Test {
    public static void main(String[] args) {

        ArrayList arrayList = new ArrayList();
        arrayList.add(new Dog_("Wangcai",5));
        arrayList.add(new Dog_("chinese rhubarb",3));//ergodic
        for (Object o : arrayList) {
            //Transition down first
            Dog_ d=(Dog_) o;
            System.out.println("name" + d.getName() + "Age:" + d.getAge());

        }
    }

}

class Dog_ {
    String name;
    int age;

    @Override
    public String toString() {
        return "Dog_{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    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 Dog_(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
class Cat{
    String name;
    int age;

    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 Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

At this time, we must transform downward during traversal instead of directly writing into Dog type:

 

At this time, if we accidentally add a cat, there will be no error during compilation, but the following exceptions will be reported during running traversal:

//At this time, if the programmer accidentally adds a cat
        arrayList.add(new Cat("Mimi",2));

 

 

Because we just made a downward transformation here, but Cat cannot be forcibly converted to Dog type:

 

Summarize the problems we encountered:

 

 

If there is a large amount of data, it is troublesome to make a downward transformation for each traversal. At this time, generics can be introduced.

Let's use generics to perform the operation just now:

ArrayList<Dog_> arrayList = new ArrayList<>();

You can see that the two previous pain points have been perfectly solved. When adding a Cat instance, an error is reported during compilation, and you can traverse directly without downward transformation (nice!)

 

 

 

 

2. Benefits of generics

 

 

 

3. Introduction to generics

 

 

For example, the Dog here is not a generic type, but a generic type (a generic type can be understood as a type of data type). This Dog will be passed to E

 

 

 

 

Note: it is particularly emphasized that the specific data type of E is specified when defining the Person object, that is, the type of E is determined during compilation

 

 

 

4. Generic syntax

 

 

 

  • Exercise 1:

package generic;

import java.util.*;

/**
 * @author Purple English
 * @version 1.0
 * @discription
 */
public class Generic02 {
    public static void main(String[] args) {
        Student jack = new Student("jack", 15);
        Student marry = new Student("marry", 14);
        Student tom = new Student("tom", 11);
        HashSet<Student> students = new HashSet<Student>();
        /*
        public class HashMap<K,V>
         */
        students.add(jack);
        students.add(marry);
        students.add(tom);
        for (Student student : students) {
            System.out.println(student);
        }
        HashMap<String, Student> stuMap = new HashMap<String, Student>();
        stuMap.put("jack",jack);
        stuMap.put("marry",marry);
        stuMap.put("tom",tom);
        Set<String> keySet = stuMap.keySet();
        for (String s : keySet) {
            System.out.println("name:" + s +" "+ "age:" + stuMap.get(s));
        }

        System.out.println("=======Iterator traversal=======");
        Set<Map.Entry<String, Student>> entries = stuMap.entrySet();
        /*
        public Set<Map.Entry<K,V>> entrySet() {
        Set<Map.Entry<K,V>> es;
        return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;
    }
         */
        Iterator<Map.Entry<String, Student>> iterator = entries.iterator();
        /*
        public final Iterator<Map.Entry<K,V>> iterator() {
            return new EntryIterator();
        }
         */
        while (iterator.hasNext()) {
            Map.Entry<String, Student> m =  iterator.next();
            System.out.println("name:"+m.getKey()+" "+ "age:" + m.getValue());
        }
    }
}
class Student{
    public String name;
    public int age;

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

 

5. Precautions and use details

Example:

public class Generic03 {
    public static void main(String[] args) {
        HashSet<Animal> animals = new HashSet<>();
        //After specifying a specific type for a generic type, you can pass in the type or its subtypes
        animals.add(new Pig<String>("pig"));
        HashSet<Pig> pigs = new HashSet<>();
        //The right side can be omitted
    }
}
class Animal{}
class Pig <E>extends Animal{
    E e;

    public Pig(E e) {
        this.e = e;
    }
}

 

  • Exercise 2

 

 

 

package generic;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.Comparator;

/**
 * @author Purple English
 * @version 1.0
 * @discription
 */
public class Generic04 {
    public static void main(String[] args) {
        Employee jack = new Employee("jack", 15000, new MyDate(2000, 12, 26));
        Employee jack1 = new Employee("jack", 14000, new MyDate(2000, 12, 26));
        Employee jack2 = new Employee("jack", 14000, new MyDate(1998, 11, 25));
//        Employee jack3 = new Employee("jack", 14000, new MyDate(2010, 11, 26));
        Employee marry = new Employee("marry", 16000, new MyDate(1999, 1, 4));
        ArrayList<Employee> employees = new ArrayList<>();
        employees.add(jack);
        employees.add(jack1);
        employees.add(jack2);

        employees.add(marry);
        employees.sort(new Comparator<Employee>() {
            @Override
            public int compare(Employee o1, Employee o2) {
                if (!(o1.getName().equals(o2.getName()))) {
                    return o1.getName().compareTo(o2.getName());
                } else {
                    return o1.getBirthday().compareTo(o2.getBirthday());
                }
            }
        });
        for (Employee employee : employees) {
            System.out.println(employee);
        }

    }
}

class Employee {
    private String name;
    private double sal;
    private MyDate birthday;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getSal() {
        return sal;
    }

    public void setSal(double sal) {
        this.sal = sal;
    }

    public MyDate getBirthday() {
        return birthday;
    }

    public void setBirthday(MyDate birthday) {
        this.birthday = birthday;
    }

    public Employee(String name, double sal, MyDate birthday) {
        this.name = name;
        this.sal = sal;
        this.birthday = birthday;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", sal=" + sal +
                ", birthday=" + birthday +
                '}';
    }
}

class MyDate implements Comparable<MyDate> {
    private int year;
    private int month;
    private int day;

    public MyDate(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public int getMonth() {
        return month;
    }

    public void setMonth(int month) {
        this.month = month;
    }

    public int getDay() {
        return day;
    }

    public void setDay(int day) {
        this.day = day;
    }

    @Override
    public String toString() {
        return "{" +
                year +
                "-" + month +
                "-" + day +
                '}';
    }


    @Override
    public int compareTo(@NotNull MyDate date) {
        //Intermediate variables store incoming data
        int year1 = (date).getYear();
        int yearMin = year - year1;
        int month1 = (date).getMonth();
        int monthMin = month - month1;
        int day1 = (date).getDay();
        int dayMin = day - day1;
        if (yearMin != 0) {
            return yearMin;
        } else if (monthMin != 0) {
            return monthMin;
        } else return dayMin;


    }
}

 

6. Custom generics

  • 6.1 custom generic classes

 

 

Note: T, R, etc. are generic identifiers, usually one capital letter

Generic arrays cannot be initialized because they do not know how much memory to open up

Static methods and attributes cannot use generics because static needs to be determined when the class is loaded, while generics are determined when the object is created, and the order is inconsistent (static precedes generics)

Exercise: a generic class is added after Tiger class, which we call custom generic class

 

 

 

  • 6.2 custom generic interface

 

Note here: the methods and properties in the interface are abstract. The properties are public static final and the methods are public abstract. Therefore, the properties of generic types cannot be defined.  

 

 

 

  • 6.3 custom generic methods

 

 

 

 

 

 

 

Small exercise:

 

 

 

 

7. Generic inheritance and wildcards

 

1) error: there is no inheritance between generic types (although String is a subclass of Object)

Writing method: