了解泛型的使用

目录

1.泛型类的定义

1.1 语法

1.2 简单实例

1.3 加入静态内部类的示例

1.4 加入继承或实现的示例

2. 泛型类的使用

2.1 语法

2.2 示例

2.3 类型推导(Type Inference)

3. 泛型类的定义——类型边界

4.1 语法

 4.2 示例

5. 泛型类的使用——通配符

5.1 基本使用

5.2 通配符——上界

5.3 通配符——下界

6. 泛型中的父子类型

 7. 泛型方法

7.1 语法


1.泛型类的定义

1.1 语法

class 泛型类名称<类型形参列表> { 
// 这里可以使用类型参数

}

class ClassName<T1, T2, ..., Tn> { 
}
class 泛型类名称 < 类型形参列表 > extends 继承类 /* 这里可以使用类型参数 */ {
// 这里可以使用类型参数
}
class ClassName<T1, T2, ..., Tn> extends ParentClass<T1> { 
// 可以只使用部分类型参数
}

 规范:类型形参一般使用一个大写字母表示,常用的名称有:

E 表示 Element

K 表示 key

V 表示 Value

N 表示 Number

T 表示 Type

S,U,V 表示第二、第三、第四个类型

1.2 简单实例

//<E>为泛指,自己定义类型
//输出时自动对类型强制转换,不许自己转
class ArrayList<E> {

    private E[] elem;
    private int size;

    public ArrayList() {
        //this.elem = new E[10];//泛型不能实例化
        this.elem = (E[])new Object[10];
    }
    public void add(E val) {
        this.elem[size] = val;
        size++;
    }
    public E get(int pos) {

        return this.elem[pos];
    }

}
public class Test {
    public static void main(String[] args) {
        //通过泛型,可以点击new一个直接想要的类型对象
        ArrayList<String> arrayList1 = new ArrayList<>();
        arrayList1.add("fly");
        String ret1 = arrayList1.get(0);
        System.out.println(ret1);
        System.out.println("-------------");
        ArrayList<Integer> arrayList2 = new ArrayList<>();
        arrayList2.add(12);
        int ret2 = arrayList2.get(0);
        System.out.println(ret2);
        System.out.println("-------------");
        ArrayList<Boolean> arrayList3 = new ArrayList<>();
        arrayList3.add(true);
        boolean flg = arrayList3.get(0);
        System.out.println(flg);


    }
}

上诉代码定义了三个类型:string 、Integer 、boolean,然后调用泛型类即可。

1.3 加入静态内部类的示例

定义一个泛型类链表

public class MyLinkedList<E> {
    static class Node<E> {
        private E value;
        private Node<E> next;

        private Node(E e) {
            value = e;
            next = null;
        }
    }
    private Node<E> head;
    private int size;

    public MyLinkedList() {
        head = null;
        size = 0;
    }

    //头插
    public void pushFront(E e) {
        Node<E> node = new Node<>(e);
        node.next = head; head = node;
        size++;
    }
    //尾插
    public void pushBack(E e) {
        if (size == 0) {
            pushFront(e);
            return;
        }
        Node<E> cur = head;
        while (cur.next != null) {
            cur = cur.next;
        }
        cur.next = new Node<E>(e);
        size++;
    }
}

1.4 加入继承或实现的示例

public interface MyList<E> { 
    // 尾插 void add(E e); 
    // 尾删 E remove();
}
public class MyArrayList<E> implements MyList<E> { 
    // 
}

2. 泛型类的使用

2.1 语法

泛型类<类型实参> 变量名; //定义一个泛型类引用

new 泛型类<类型实参> (构造方法实参);//实例化一个泛型类对象

2.2 示例

MyLinkedList<String> list = new MyLinkedList<String>();

2.3 类型推导(Type Inference)

当编译器可以根据上下文推导出类型实参时,可以省略类型实参的填写,直接强转为需要的类型
MyLinkedList<String> list = new MyLinkedList<String>();

3. 泛型类的定义——类型边界

在定义泛型类时,有时需要对传入的类型变量做一定的约束,可以通过类型边界来约束。

4.1 语法

class 泛型类名称<类型形参 extends 类型边界> {

}

 4.2 示例

1)

public class MyArrayList<E extends Number> {

}
只接受 Number 的子类型作为 E 的类型实参
MyArrayList<Integer> l1; // 正常,因为 Integer 是 Number 的子类型 
MyArrayList<String> l2; // 编译错误,因为 String 不是 Number 的子类型

2)求数组最大值

class Alg<T extends Comparable<T>> {
    public T findMax(T[] array) {
        T max = array[0];
        for (int i = 0; i < array.length-1; i++) {
            if (max.compareTo(array[i]) < 0) {
                max = array[i];
            }
        }
        return max;
    }
}
public class TestDemo {
    public static void main(String[] args) {
        
        Alg<Integer> alg = new Alg<>();
        Integer[] array = {2,4,1,23,2};
        System.out.println(alg.findMax(array));

    }
}

5. 泛型类的使用——通配符

5.1 基本使用

?用于在泛型的使用,即为通配符

示例

public class MyArrayList<E> {...}
// 可以传入任意类型的 
MyArrayList public static void printAll(MyArrayList<?> list) { ... }
// 以下调用都是正确的 
printAll(new MyArrayList<String>());
 printAll(new MyArrayList<Integer>());
printAll(new MyArrayList<Double>()); 
printAll(new MyArrayList<Number>()); 
printAll(new MyArrayList<Object>());

5.2 通配符——上界

<? extends 上界 >

示例

// 可以传入类型实参是 Number 子类的任意类型的 MyArrayList 
public static void printAll(MyArrayList<? extends Number> list {
//....
}

//以下调用是正确的
printAll(new MyArrayList<Integer>()); 
printAll(new MyArrayList<Double>());
 printAll(new MyArrayList<Number>());

//以下调用是错误的
printAll(new MyArrayList<String>());
printAll(new MyArrayList<Object>());

5.3 通配符——下界

语法

<? super 下界>

示例

// 可以传入类型实参是 Integer 父类的任意类型的 MyArrayList 
public static void printAll(MyArrayList<? super Integer> list) { ... }
// 以下调用都是正确的 
printAll(new MyArrayList<Integer>());
 printAll(new MyArrayList<Number>()); 
printAll(new MyArrayList<Object>()); 

// 以下调用是编译错误的 
printAll(new MyArrayList<String>());
printAll(new MyArrayList<Double>());

6. 泛型中的父子类型

public class MyArrayList<E> { ... } 


// MyArrayList<Object> 不是 MyArrayList<Number> 的父类型 
// MyArrayList<Number> 也不是 MyArrayList<Integer> 的父类型 

// 需要使用通配符来确定父子类型 
// MyArrayList<?> 是 MyArrayList<? extends Number> 的父类型
// MyArrayList<? extends Number> 是 MyArrayList<Integer> 的父类型 

 7. 泛型方法

7.1 语法

方法限定符 < 类型形参列表 > 返回值类型 方法名称 ( 形参列表 ) { ... }

示例 

public class Util { 
   public static <E> void swap(E[] array, int i, int j) { 
       E t = array[i];
       array[i] = array[j]; 
       array[j] = t; 
   } 
}

猜你喜欢

转载自blog.csdn.net/m0_60494863/article/details/125676068
今日推荐