使用泛型

使用泛型

廖雪峰

资深软件开发工程师,业余马拉松选手。

使用ArrayList时,如果不定义泛型类型时,泛型类型实际上就是Object:

// 编译器警告:

List list = new ArrayList();

list.add("Hello");

list.add("World");

String first = (String) list.get(0);

String second = (String) list.get(1);

此时,只能把当作Object使用,没有发挥泛型的优势。

当我们定义泛型类型后,List的泛型接口变为强类型List

// 无编译器警告:

List list = new ArrayList();

list.add("Hello");

list.add("World");

// 无强制转型:

String first = list.get(0);

String second = list.get(1);

当我们定义泛型类型后,List的泛型接口变为强类型List

List list = new ArrayList();

list.add(new Integer(123));

list.add(new Double(12.34));

Number first = list.get(0);

Number second = list.get(1);

编译器如果能自动推断出泛型类型,就可以省略后面的泛型类型。例如,对于下面的代码:

List list = new ArrayList();

编译器看到泛型类型List就可以自动推断出后面的ArrayList的泛型类型必须是ArrayList,因此,可以把代码简写为:

// 可以省略后面的Number,编译器可以自动推断泛型类型:

List list = new ArrayList<>();

泛型接口

除了ArrayList使用了泛型,还可以在接口中使用泛型。例如,Arrays.sort(Object[])可以对任意数组进行排序,但待排序的元素必须实现Comparable这个泛型接口:

public interface Comparable {

/**

* 返回负数: 当前实例比参数o小

* 返回0: 当前实例与参数o相等

* 返回正数: 当前实例比参数o大

*/

int compareTo(T o);

}

可以直接对String数组进行排序:

// sort

import java.util.Arrays;

public class Main {

public static void main(String[] args) {

String[] ss = new String[] { "Orange", "Apple", "Pear" };

Arrays.sort(ss);

System.out.println(Arrays.toString(ss));

}

}

这是因为String本身已经实现了Comparable接口。如果换成我们自定义的Person类型试试:

// sort

import java.util.Arrays;

public class Main {

public static void main(String[] args) {

Person[] ps = new Person[] {

new Person("Bob", 61),

new Person("Alice", 88),

new Person("Lily", 75),

};

Arrays.sort(ps);

System.out.println(Arrays.toString(ps));

}

}

class Person {

String name;

int score;

Person(String name, int score) {

this.name = name;

this.score = score;

}

public String toString() {

return this.name + "," + this.score;

}

}

运行程序,我们会得到ClassCastException,即无法将Person转型为Comparable。我们修改代码,让Person实现Comparable接口:

// sort

import java.util.Arrays;

public class Main {

public static void main(String[] args) {

Person[] ps = new Person[] {

new Person("Bob", 61),

new Person("Alice", 88),

new Person("Lily", 75),

};

Arrays.sort(ps);

System.out.println(Arrays.toString(ps));

}

}

class Person implements Comparable {

String name;

int score;

Person(String name, int score) {

this.name = name;

this.score = score;

}

public int compareTo(Person other) {

return this.name.compareTo(other.name);

}

public String toString() {

return this.name + "," + this.score;

}

}

运行上述代码,可以正确实现按name进行排序。

也可以修改比较逻辑,例如,按score从高到低排序。请自行修改测试。

小结

使用泛型时,把泛型参数替换为需要的class类型,例如:ArrayList,ArrayList等;

可以省略编译器能自动推断出的类型,例如:List list = new ArrayList<>();;

不指定泛型参数类型时,编译器会给出警告,且只能将视为Object类型;

可以在接口中定义泛型类型,实现此接口的类必须实现正确的泛型类型。

相关推荐

DNF高增幅卡巴拉记忆对智力加成到底有多恐怖?
人人都爱孔方兄,“钱”的九种别名你知道几个?
姜子牙的老婆叫什么?姜子牙老婆马氏被封什么神
i56200u处理器(揭秘i56200u处理器在游戏中的表现及性能优势)
告别模糊画面!Windows 10轻松调至2K分辨率,解锁清晰视界全攻略!
cheerleader是什麼意思,cheerleader的意思翻譯、用法、同義詞、例句