目录
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> {
}
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;
}
}