2021-11-05 XIV. Generic

1. Basic introduction to generics

Generics are equivalent to tags
For example:
In the traditional Chinese medicine store, there are labels on the outside of each drawer
There are many bottles on the supermarket shelves. What is in each bottle and there are labels.

1.1 design background of generics

The collection container class cannot determine what type of objects actually exist in this container in the design phase / declaration phase, so before JDK1.5, the element type can only be designed as Object, and after JDK1.5, generics can be used to solve it. At this time, except the element type is uncertain, other parts are determined, such as how to save and manage the element. Therefore, the element type is designed as a parameter, which is called genericity. Collection, List and ArrayList are type parameters, that is, generics.

The so-called genericity is to allow an identifier to represent the type of an attribute in a class or the return value and parameter type of a method when defining a class or interface. This type parameter will be determined when it is used (for example, inherit or implement this interface, declare variables and create objects with this type ID. it can only be determined when the actual type parameter (type argument) is passed in).
Since JDK1.5, Java has introduced the concept of "parameterized type", which allows us to specify the type of collection elements when creating a collection, such as: List < string >, which indicates that the list can only save objects of string type.
JDK1.5 rewrites all interfaces and classes in the collection framework and adds generic support for these interfaces and classes, so that type arguments can be passed in when declaring collection variables and creating collection objects.

1.2 why generics

So why do we need generics? Can direct objects also store data?

  1. Solve the security problem of element storage, such as commodity and drug labels.
  2. To solve the problem of type coercion when obtaining data elements, for example, you don't have to identify goods and drugs every time you get them.
  3. Java generics can ensure that ClassCastException exceptions will not be generated at runtime if the program does not issue a warning at compile time. At the same time, the code is more concise and robust.
import org.junit.Test;

import java.util.ArrayList;

public class GenericTest {

    //Before using generics in a collection:
    @Test
    public void test(){
        ArrayList list = new ArrayList();
        //Requirements: store students' grades
        list.add(78);
        list.add(49);
        list.add(72);
        list.add(81);
        list.add(89);
        //Problem 1: unsafe type
//        list.add("Tom");

        for(Object score : list){
            //Problem 2: type conversion exception may occur during forced conversion
            int stuScore = (Integer)score;

            System.out.println(stuScore);
        }
    }
}

2. Use generics in Collections

① The collection interface or collection class is modified to a generic structure in JDK 5.0. (see the source code for this)
② When instantiating a collection class, you can specify the specific generic type, for example: List < string >
③ After specifying, when defining a class or interface in a collection class or interface, the location where the generic type of the class is used by the internal structure (such as method, constructor, attribute, etc.) is specified as the instantiated generic type. For example: add (E) = > after instantiation: add(String e)
④ The type of a generic type must be a class, not a basic data type. Where the basic data type needs to be used, replace it with a wrapper class
⑤ If the generic type is not specified when instantiating. The default type is java.lang.Object.

Example

import org.junit.Test;

import java.util.*;

public class GenericTest {

    //Using generics in Collections: take ArrayList as an example
    @Test
    public void test2(){
        ArrayList<Integer> list = new ArrayList<Integer>();

        list.add(78);
        list.add(49);
        list.add(72);
        list.add(81);
        list.add(89);
        //When compiling, type checking will be carried out to ensure the safety of data
//        list.add("Tom");

        //Mode 1:
//        for(Integer score :list){
//            //The operation of forced rotation is avoided
//            int stuScore = score;
//
//            System.out.println(stuScore);
//        }

        //Mode 2:
        Iterator<Integer> iterator = list.iterator();
        while(iterator.hasNext()){
            int stuScore = iterator.next();
            System.out.println(stuScore);
        }
    }

    //Using generics in Collections: take HashMap as an example
    @Test
    public void test3(){
//        Map<String,Integer> map = new HashMap<String,Integer>();
        //jdk7 new feature: type inference
        Map<String,Integer> map = new HashMap<>();

        map.put("Tom",87);
        map.put("Tone",81);
        map.put("Jack",64);

//        map.put(123,"ABC");

        //Nesting of generics
        Set<Map.Entry<String,Integer>> entry = map.entrySet();
        Iterator<Map.Entry<String, Integer>> iterator = entry.iterator();

        while(iterator.hasNext()){
            Map.Entry<String, Integer> e = iterator.next();
            String key = e.getKey();
            Integer value = e.getValue();
            System.out.println(key + "----" + value);
        }
    }

}

Exercise 1

import org.junit.Test;

import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;

/**
 * MyDate Class contains:
 * private Member variables year,month,day; And define getter and setter methods for each attribute;
 *
 */
 class MyDate implements Comparable<MyDate> {
    private int year;
    private int month;
    private int 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;
    }

    public MyDate() {
    }

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

    @Override
    public String toString() {
        return "MyDate{" +
                "year=" + year +
                ", month=" + month +
                ", day=" + day +
                '}';
    }
	//How to write without specifying generics
//    @Override
//    public int compareTo(Object o) {
//        if(o instanceof MyDate){
//            MyDate m = (MyDate)o;
//
//            //Comparative year
//            int minusYear = this.getYear() - m.getYear();
//            if(minusYear != 0){
//                return minusYear;
//            }
//            //Comparison month
//            int minusMonth = this.getMonth() - m.getMonth();
//            if(minusMonth != 0){
//                return minusMonth;
//            }
//            //Comparison day
//            return this.getDay() - m.getDay();
//        }
//
//        throw new RuntimeException("inconsistent data type passed in!");
//
//    }

    @Override
    public int compareTo(MyDate m) {
        //Comparative year
        int minusYear = this.getYear() - m.getYear();
        if(minusYear != 0){
            return minusYear;
        }
        //Comparison month
        int minusMonth = this.getMonth() - m.getMonth();
        if(minusMonth != 0){
            return minusMonth;
        }
        //Comparison day
        return this.getDay() - m.getDay();
    }
}
/**
 * Define an Employee class.
 * This class contains: private member variables name,age,birthday,
 * Where birthday is the object of MyDate class;
 * And define getter and setter methods for each attribute;
 * And override the toString method to output name, age and birthday
 *
 */
class Employee implements Comparable<Employee> {
    private String name;
    private int age;
    private MyDate birthday;

    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 MyDate getBirthday() {
        return birthday;
    }

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

    public Employee() {
    }

    public Employee(String name, int age, MyDate birthday) {
        this.name = name;
        this.age = age;
        this.birthday = birthday;
    }

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

    //How to write without specifying generics
    //Sort by name
//    @Override
//    public int compareTo(Object o){
//        if(o instanceof Employee){
//            Employee e = (Employee)o;
//            return this.name.compareTo(e.name);
//        }
        return 0;
//        throw new RuntimeException("the incoming data type is inconsistent");
//    }

    //Indicates how generics are written
    @Override
    public int compareTo(Employee o) {
        return this.name.compareTo(o.name);
    }
}

public class EmployeeTest {
  //Question 1: use natural sorting
    @Test
    public void test(){
        TreeSet<Employee> set = new TreeSet<Employee>();

        Employee e1 = new Employee("wangxianzhi",41,new MyDate(334,5,4));
        Employee e2 = new Employee("simaqian",43,new MyDate(-145,7,12));
        Employee e3 = new Employee("yanzhenqin",44,new MyDate(709,5,9));
        Employee e4 = new Employee("zhangqian",51,new MyDate(-179,8,12));
        Employee e5 = new Employee("quyuan",21,new MyDate(-340,12,4));

        set.add(e1);
        set.add(e2);
        set.add(e3);
        set.add(e4);
        set.add(e5);

        Iterator<Employee> iterator = set.iterator();
        while (iterator.hasNext()){
            Employee next = iterator.next();
            System.out.println(next);
        }
    }
    //Question 2: sort by birthday date
    @Test
    public void test2(){
        TreeSet<Employee> set = new TreeSet<>(new Comparator<Employee>() {
            //Writing after using generics
            @Override
            public int compare(Employee o1, Employee o2) {
                MyDate b1 = o1.getBirthday();
                MyDate b2 = o2.getBirthday();

                return b1.compareTo(b2);
            }

            //Writing before using generics
/*            @Override
            public int compare(Object o1, Object o2) {
                if (o1 instanceof Employee && o2 instanceof Employee) {
                    Employee e1 = (Employee) o1;
                    Employee e2 = (Employee) o2;

                    MyDate b1 = e1.getBirthday();
                    MyDate b2 = e2.getBirthday();
                    //Mode 1:
                    //Comparative year
                    int minusYear = b1.getYear() - b2.getYear();
                    if (minusYear != 0) {
                        return minusYear;
                    }
                    //Comparison month
                    int minusMonth = b1.getMonth() - b2.getMonth();
                    if (minusMonth != 0) {
                        return minusMonth;
                    }
                    //Comparison day
                    return b1.getDay() - b2.getDay();

                    //Method 2: directly use compareTo of MyDate
                    return b1.compareTo(b2);

                }
                throw new RuntimeException("The data type passed in is inconsistent! ");
            }*/
        });

        Employee e1 = new Employee("liudehua",55,new MyDate(1965,5,4));
        Employee e2 = new Employee("zhangxueyou",43,new MyDate(1987,5,4));
        Employee e3 = new Employee("guofucheng",44,new MyDate(1987,5,9));
        Employee e4 = new Employee("liming",51,new MyDate(1954,8,12));
        Employee e5 = new Employee("liangzhaowei",21,new MyDate(1978,12,4));

        set.add(e1);
        set.add(e2);
        set.add(e3);
        set.add(e4);
        set.add(e5);

        Iterator<Employee> iterator = set.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
}

3. Custom generic structure

3.1 custom generic classes

In actual development and use, we can also customize generic classes to extract common parts as components

Custom generic class: if < T > is declared after the class name, the T symbol can be used as a generic class

public class OrderTest<T> {

    String orderName;
    int orderId;

    //The internal structure of the class can use the generics of the class
    T orderT;

    public OrderTest(){

    };

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

    @Override
    public String toString() {
        return "Order{" +
                "orderName='" + orderName + '\'' +
                ", orderId=" + orderId +
                ", orderT=" + orderT +
                '}';
    }
    
}

3.1.1 inheritance relationship of generic classes

The parent class has a generic type, and the child class can choose to keep the generic type or specify the generic type:

  1. Subclasses do not retain the genericity of the parent class: on-demand implementation
    If there is no type, it will be erased
    Specific type
  2. Subclasses retain the genericity of the parent class: generic subclasses
    remove none
    Partial retention
  3. Subclasses can be expanded on the basis of parent classes
class Father<T1, T2> {}
// Subclasses do not retain the generics of the parent class
// 1) If there is no type, it will be erased
class Son1 extends Father {// Equivalent to class son extends father < object, Object > {}
}
//Class son1 < A, b > extends father {/ / two generic types are specified on the basis of father < object, Object >
//}
// 2) Specific type
class Son2 extends Father<Integer, String> {}
// Subclasses retain the generics of the parent class
// 1) Keep all
class Son3<T1, T2> extends Father<T1, T2> {}
// 2) Partial retention
class Son4<T2> extends Father<Integer, T2> {}
// Expand
class Son5<T2, T3> extends Father<Integer,T2>{}

Example

import org.junit.Test;

//SubOrder: is not a generic class
class SubOrder extends OrderTest<Integer> {   
}
//Suborder1 < T >: still generic class
class SubOrder1<T> extends OrderTest<T> {
}
public class GenericTest1 {

    @Test
    public void test(){
        /**
         * If a generic class is defined and the instantiation does not specify the generic type of the class, the generic type is considered to be Object type
         * Requirement: if you have defined that the class is generic, it is recommended to specify the generic type of the class when instantiating.
         */
        OrderTest order = new OrderTest();
        order.setOrderT(123);
        order.setOrderT("ABC");

        //Suggestion: specify the generic type of the class when instantiating
        OrderTest<String> order1 = new OrderTest<String>("orderAA",1001,"order:AA");

        order1.setOrderT("AA:hello");
    }

    @Test
    public void test2(){
        SubOrder sub1 = new SubOrder();
        //Since the subclass indicates the generic type when inheriting the parent class with generic type, it is no longer necessary to specify the generic type when instantiating the subclass object.
        sub1.setOrderT(1122);

        SubOrder1<String> sub2 = new SubOrder1<>();
        sub2.setOrderT("order2...");
    }
}

The embodiment of generics in inheritance
For example, class A is the parent of class B, but g < a > and G < b > do not have child parent relationship, and they are juxtaposed.
In addition, class A is the parent of class B, and class A It's B Parent class of

import org.junit.Test;

import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;

public class GenericTest {
    @Test
    public void test(){
		// In retrospect, the following are possible
        Object obj = null;
        String str = null;
        obj = str;

        Object[] arr1 = null;
        String[] arr2 = null;
        arr1 = arr2;
        //Compilation failed
//        Date date = new Date();
//        str = date;
		
		
		//At this time, the types of list1 and list2 do not have a child parent relationship
        List<Object> list1 = null;
        List<String> list2 = new ArrayList<String>();
        //Compilation failed
//        list1 = list2;
        /**
         * Counter evidence:
         *   Assume list1 = list2;
         *      list1.add(123);This caused an error in mixing non String data.
         */
        show(list1);
        show2(list2);
    }

    public void show2(List<String> list){

    }

    public void show(List<Object> list){

    }

    @Test
    public void test2(){
    	// The following is the parent-child relationship
        AbstractList<String> list1 = null;
        List<String> list2 = null;
        ArrayList<String> list3 = null;

        list1 = list3;
        list2 = list3;

        List<String> list4 = new ArrayList<>();
    }

}

3.1.2 considerations for customizing generic classes / interfaces

be careful:

  1. A generic class may have multiple parameters. In this case, multiple parameters should be put together in angle brackets. For example: < E1, E2, E3 >
  2. Constructor of generic class is consistent with that of ordinary class: public GenericClass() {}. Error example: public genericclass < T > () {}
  3. After instantiation, the structure of the original generic location must be consistent with the specified generic type.
  4. Instance references of different generics cannot be assigned to each other.
  5. If a generic type is not specified, it will be erased. The types corresponding to the generic type are treated as Object, but they are not equivalent to Object.
    Experience: generics should be used all the way. No, not all the way.
  6. If the generic structure is an interface or abstract class, you cannot create an object of the generic class.
  7. Simplified operation of JDK1.7 generics: ArrayList flist = new ArrayList < > ();
  8. Basic data types cannot be used in the specification of generic types, but can be replaced by wrapper classes.
  9. The generic type declared on the class / interface represents a type in this class or interface, and can be used as the type of non static attribute, parameter type of non static method and return value type of non static method. However, class generics cannot be used in static methods (because static methods are loaded earlier than instances, static methods can only use generic methods).
  10. Exception class cannot be generic

Example

class OrderTest<T> {

    String orderName;
    int orderId;
    T orderT;

    public OrderTest(){
        //The compilation fails because the generic type is just a placeholder and there is no real class information, so there is no way to new (the compiler will erase the type information)
//        T[] arr = new T[10];
        //Compile passed
        T[] arr = (T[]) new Object[10];
    };
	// 2. The constructor of generic class is consistent with that of ordinary class: ` public GenericClass() {} '. Error example: ` public genericclass < T > () {}`
    public OrderTest(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 +
                '}';
    }

    //9. Class generics cannot be used in static methods.
//    public static void show(T orderT){
//        System.out.println(orderT);
//    }

    public void show(){
        //10. Exception class cannot be generic
//        try{
//
//
//        }catch(T t){
//
//        }
    }
}
import org.junit.Test;

import java.util.ArrayList;

public class GenericTest1 {

    @Test
    public void test3(){
        ArrayList<String> list1 = null;
        ArrayList<Integer> list2 = new ArrayList<Integer>();
        //4. References with different generics cannot be assigned to each other.
        //list1 = list2;

        Person p1 = null;
        Person p2 = null;
        p1 = p2;
    }
}

3.2 custom generic methods

Methods can also be generalized, regardless of whether the class defined in them is a generic class or not. Generic parameters can be defined in generic methods. In this case, the type of parameter is the type of incoming data.
Generic method: the generic structure appears in the method, and the generic parameters have nothing to do with the generic parameters of the class. (that is, the generic parameter of a generic method may not be the generic parameter of a class)
Generic methods that can be declared static. Reason: generic parameters are determined when the method is called. Not determined when instantiating a class.

Format:

[Access rights] <generic paradigm> Return type method name([Generic identity parameter name]) Exception thrown
 For example: public static <E>  List<E> copyFromArrayToList(E[] arr) throws  Exception{  }
class OrderTest<T> {

    String orderName;
    int orderId;

    //The internal structure of the class can use the generics of the class
    T orderT;

    public OrderTest(){

    };

    public OrderTest(String orderName,int orderId,T orderT){
        this.orderName = orderName;
        this.orderId = orderId;
        this.orderT = orderT;
    }
	// Static generic method, customized E as generic parameter
    public static <E>  List<E> copyFromArrayToList(E[] arr){
        ArrayList<E> list = new ArrayList<>();

        for(E e : arr){
            list.add(e);
        }
        return list;
    }
    // Non static generic method
    public <K> List<K> Array2List(K[] arr) {
        ArrayList<K> list = new ArrayList<>();

        for(K e : arr){
            list.add(e);
        }
        return list;
    }
    //None of the following three methods are generic methods
    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 +
                '}';
    }
}
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;


public class GenericTest1 {

    //Test generic methods
    @Test
    public void test4(){
        OrderTest<String> order = new OrderTest<>();
        Integer[] arr = new Integer[]{1,2,3,4};
        //When a generic method is called, it indicates the type of generic parameter.
        List<Integer> list = order.copyFromArrayToList(arr);

        System.out.println(list);
    }
}

Using generic methods in non generic classes

import java.util.ArrayList;
import java.util.List;

public class SubOrder extends OrderTest<Integer>{   //SubOrder: is not a generic class
    
    public static <E> List<E> copyFromArrayToList(E[] arr){//Static generic method

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

        for(E e : arr){
            list.add(e);
        }
        return list;
    }
}

4. Usage scenarios of generics

As mentioned above, common parts can be extracted for reuse. For example, during CRUD operations on databases, basic methods can be encapsulated into generic classes and provided to different table operations

import java.util.List;

public class DAO<T> { //DAO for common operations of tables

    //Add a record
    public void add(T t){

    }

    //Delete a record
    public boolean remove(int index){

        return false;
    }

    //Modify a record
    public void update(int index,T t){

    }

    //Query a record
    public T getIndex(int index){

        return null;
    }

    //Query multiple records
    public List<T> getForList(int index){

        return null;
    }

    //generic method 
    //Example: how many records are there in the acquisition table? Get the maximum employee induction time?
    public <E> E getValue(){

        return null;
    }

}

class Customer { //This class corresponds to the customers table in the database
}
class Student {
}
class StudentDAO extends DAO<Student> {//You can only operate on the DAO of a table
}

class CustomerDAO extends DAO<Customer>{//You can only operate on the DAO of a table
}

import org.junit.Test;

import java.util.List;

public class DAOTest {

    @Test
    public void test(){
        CustomerDAO dao1 = new CustomerDAO();

        dao1.add(new Customer());
        List<Customer> list = dao1.getForList(10);


        StudentDAO dao2 = new StudentDAO();
        Student student = dao2.getIndex(1);
    }

}

5. Use of wildcards

Basic introduction
Wildcard:?
For example: List <? >, Map<?,?>
List<?> It is the parent class of list and various generic lists. Read list <? > It is always safe to use the elements in the list of objects, because no matter what the real type of the list is, it contains objects.

be careful:

  1. Add any element to the list except null <? > To which is not type safe
  2. Cannot be used on a generic declaration of a generic method
    Error example: public <? > void test(ArrayList<?> list) {}
    Correct example: public < T > void test (ArrayList <? > list) {}
  3. Cannot be used on declarations of generic classes
  4. Cannot be used on instantiation creation of objects
    public static void main(String[] args) {
    
        List<Object> list1 = null;
        List<String> list2 = null;
        List<?> list = null;
   		// Because you used it? Wildcard, so it is the parent class of list1 and list2
        list = list1;
        list = list2;

        final ArrayList<?> arrayList = new ArrayList<>();
        // Compile time error because we don't know the element type of c, we can't add objects to it.
        // The add method takes the type parameter E as the element type of the collection.
        // Any parameter we pass to add must be a subclass of an unknown type.
        // Because we don't know what type it is, we can't pass anything in.
        arrayList.add(new Object()); 
        // Allow to join
        arrayList.add(null);
        final Object o = arrayList.get(0);
    }

5.1 use of restricted wildcards

<?> Allow all generic reference calls
However, we can specify the upper and lower limits for wildcards

  1. Wildcard to specify the upper limit:
    Extensions: when used, the specified type must inherit a class or implement an interface, i.e<=
  2. Wildcard to specify lower limit
    super: the type specified when using cannot be less than the class of the operation, i.e. >=

give an example:

  1. < T extends Number > (infinitesimal, Number]
    Type T must be a subclass of Number
  2. < T super number > [number, infinity)
    Type T must be a parent of Number
  3. <T extends Comparable>
    Type T must implement the Comparable interface
  4. <T extends Comparable<? super T>>
    Type t must implement the Comparable interface, and the type of this interface is t or any parent class of T (the sizes of instances of T and instances of T's parent class can be compared with each other)

6. Use examples

interface Info{		// Only subclasses of this interface represent human information
}
class Contact implements Info{	// Indicates contact information
	private String address ;	// Contact address
	private String telephone ;	// contact information
	private String zipcode ;	// Postal Code
	public Contact(String address,String telephone,String zipcode){
		this.address = address;
		this.telephone = telephone;
		this.zipcode = zipcode;
	}
	public void setAddress(String address){
		this.address = address ;
	}
	public void setTelephone(String telephone){
		this.telephone = telephone ;
	}
	public void setZipcode(String zipcode){
		this.zipcode = zipcode;
	}
	public String getAddress(){
		return this.address ;
	}
	public String getTelephone(){
		return this.telephone ;
	}
	public String getZipcode(){
		return this.zipcode;
	}
	@Override
	public String toString() {
		return "Contact [address=" + address + ", telephone=" + telephone
				+ ", zipcode=" + zipcode + "]";
	}
}
class Introduction implements Info{
	private String name ;		// full name
	private String sex ;		// Gender
	private int age ;			// Age
	public Introduction(String name,String sex,int age){
		this.name = name;
		this.sex = sex;
		this.age = age;
	}
	public void setName(String name){
		this.name = name ;
	}
	public void setSex(String sex){
		this.sex = sex ;
	}
	public void setAge(int age){
		this.age = age ;
	}
	public String getName(){
		return this.name ;
	}
	public String getSex(){
		return this.sex ;
	}
	public int getAge(){
		return this.age ;
	}
	@Override
	public String toString() {
		return "Introduction [name=" + name + ", sex=" + sex + ", age=" + age
				+ "]";
	}
}
class Person<T extends Info>{
	private T info ;
	public Person(T info){		// Setting information property content through constructor
		this.info = info;
	}
	public void setInfo(T info){
		this.info = info ;
	}
	public T getInfo(){
		return info ;
	}
	@Override
	public String toString() {
		return "Person [info=" + info + "]";
	}
	
}
public class GenericPerson{
	public static void main(String args[]){
		Person<Contact> per = null ;		// Declaring a Person object
		per = new Person<Contact>(new Contact("Beijing","01088888888","102206")) ;
		System.out.println(per);
		
		Person<Introduction> per2 = null ;		// Declaring a Person object
		per2 = new Person<Introduction>(new Introduction("Li Lei","male",24));
		System.out.println(per2) ;
	}
}

Exercise 1

import java.util.*;

class DAO<T> {
    private Map<String,T> map = new HashMap<String,T>();
    //Save objects of type T into Map member variables
    public void save(String id,T entity){
        map.put(id,entity);
    }
    //Get the object corresponding to the id from the map
    public T get(String id){
        return map.get(id);
    }
    //Replace the content in the map where the key is id and change it to an entity object
    public void update(String id,T entity){
        if(map.containsKey(id)){
            map.put(id,entity);
        }
    }
    //Returns all T objects stored in the map
    public List<T> list(){
        //Wrong: the parent type should not be forcibly converted to a child type, which is prone to error
//        Collection<T> values = map.values();
//        return (List<T>) values;
        //correct:
        ArrayList<T> list = new ArrayList<>();
        Collection<T> values = map.values();
        for(T t : values){
            list.add(t);
        }
        return list;

    }
    //Deletes the specified id object
    public void delete(String id){
        map.remove(id);
    }
}
class User {
    private int id;
    private int age;
    private String 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;
    }

    public User(int id, int age, String name) {

        this.id = id;
        this.age = age;
        this.name = name;
    }

    public User() {

    }

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

/**
 * Create objects of DAO class and call save, get, update, list and delete respectively
 * Method to manipulate the User object, and use the Junit unit test class to test.
 */
public class DAOTest {
    public static void main(String[] args) {
        DAO<User> dao = new DAO<User>();

        dao.save("1001",new User(1001,34,"Jay Chou"));
        dao.save("1002",new User(1002,20,"Hannah "));
        dao.save("1003",new User(1003,25,"Cai Yilin"));

        dao.update("1003",new User(1003,30,"Fang Wenshan"));

        dao.delete("1002");

        List<User> list = dao.list();
//        System.out.println(list);
        list.forEach(System.out::println);
    }
}

EDG awesome!!

LastGeneral catalogueNext
13, AssembleJava basic directoryUnfinished to be continued

Tags: Java

Posted on Mon, 08 Nov 2021 15:19:11 -0500 by micmania1