泛型:就是可以将类型作为参数进行传递。
/**
*
* @param
* <T>:表示当前类是一个泛型类
*/
class Person{
}
class MyArray<T>{
// public Object[] array = new Object[10];
//因为不能直接实例化一个泛型数组
//将Object类型的数组转换成T[]类型
public T[] array = (T[])new Object[10];
public void setValue(int pos , T val){
array[pos] = val;
}
public T getValue(int pos){
return array[pos];
}
}
public class Test {
//目标:存放指定元素
public static void main(String[] args) {
MyArray<String> myArray = new MyArray<>();
myArray.setValue(0,"Kevin");
myArray.setValue(1,"Alex");
myArray.setValue(2,"Aileen");
String str = myArray.getValue(2);
System.out.println(str);
// =================================================
MyArray<Integer> myArray2 = new MyArray<>();
myArray2.setValue(0,1);
myArray2.setValue(1,99);
int val = myArray2.getValue(1);
System.out.println(val);
// =================================================
MyArray<Person> myArray3 = new MyArray<>();
// //因为我的getvalue返回的是Object类型,所以要通过(Srtring)进行强制转换
// String str = (String) myArray.getValue(2);
}
<>
内不能是基本数据类型,只能是引用类型。
class 泛型类名称<类型参数列表>{
//类型参数
}
class ClasssName<T,T2,T3,...,Tn>{
}
<T>
代表占位符,表示当前类是一个泛型类。类型形参一般使用一个大写字母表示,常用的名称有:符号 | 含义 |
---|---|
E | Element |
K | Key |
V | Value |
N | Number |
T | Type |
S, U, V等 | 第二、第三、第四个类型 |
泛型
是在编译时的一种机制(擦除机制),这意味着在运行的时候没有泛型的概念,并且在JVM中没有泛型的概念。所以不能new
泛型类型的数组。<Integer>
指定类型,这就可以使得我们后面调用对应的方法的时候无需进行强转,因为他已经自动帮我们强制转换好了。MyArray<Integer> list = new MyArray<Integer>();
MyArray<Integer> list = new MyArray<>();
<>
里面的类型可省略,因为编译器会根据前面的<>
中的类型自动推导出后面的类型。<>
只能放引用数据类型,不能放基本数据类型。MyArray list = new MyArray();
<>
省略掉。最好不要使用,因为这是为了兼容老版本的API保留的机制。🏷️小结:泛型的优点:将数据类型参数化,编译时自动进行类型检查和转换。
class MyArray<T> {
public T[] array = (T[])new Object[10];
public T getPos(int pos) {
return this.array[pos];
}
public void setVal(int pos, T val) {
this.array[pos] = val;
}
public T[] getArray() {
return array;
}
}
public class Main {
public static void main(String[] args) {
MyArray<Integer> myArray1 = new MyArray<>();
Object[] strings1 = myArray1.getArray();
System.out.println(strings1);
Integer[] strings2 = myArray1.getArray(); // 这里会出现类型转换警告
System.out.println(strings2);
}
}
Integer
修改为Object
报错即可消失。 public Object[] array = new Object[10];
public void setValue(int pos , T val){
array[pos] = val;
}
public T getValue(int pos){
return (T)array[pos];//返回值通过(T)强转成Object类型
}
public class Test {
//目标:存放指定元素
public static void main(String[] args) {
MyArray<String> myArray4 = new MyArray<>();
MyArray<Integer> myArray5 = new MyArray<>();
}
}
// 定义一个泛型类,其类型参数E限定为Number的子类型
public class MyArray<E extends Number> {
// 类的其余部分
}
// 正确的使用,因为Integer是Number的子类型
MyArray<Integer> l1;
// 错误的使用,因为String不是Number的子类型,会导致编译错误
MyArray<String> l2;
// 编译错误信息示例
/*
error: type argument String is not within bounds of type-variable E
MyArrayList<String> l2;
^
where E is a type-variable:
E extends Number declared in class MyArrayList
*/
/*写一个泛型类,求一个数组中的最大值*/
class Alg<T extends Comparable<T> >{//①传入的T一定是实现这个comparable接口的。
public T findMaxVal(T[] array){
// 假设第一个就是最大的
T max = array[0];
for (int i = 0; i < array.length; i++) {//通过循环遍历找到array数组中最大的值
if(array[i].compareTo(max) > 0){//②所以这里的comparable接口的compareTo能够在这里调用
max = array[i];
}
}
return max;//将最大值赋值给max并返回
}
}
public class Test {
public static void main(String[] args) {
Integer[] array = {1,4,3,8,7,5};
Alg<Integer> alg = new Alg<>();
//因为Integer实现了Comparable接口所以可以直接创建对象
// 现在这个Integer就是上面的T
System.out.println(alg.findMaxVal(array));
}
T
为Integer
时,由于它已经实现了comparable这个接口,所以可以直接使用这个接口,不需要重写compareTo这个方法T extends Comparable<T>
/*写一个泛型类,求一个数组中的最大值*/
class Person implements Comparable<Person>{
public int age ;
// 构造函数,用于初始化Person对象的age属性,这才能使得你在后面调用这个方法去进行不同年龄的比较
public Person(int age) {
this.age = age;
}
@Override
public int compareTo(Person o) {
return this.age - o.age;
}
}
//---------------------------------------------------------------------------------
class Alg<T extends Comparable<T> >{//①传入的T一定是实现这个comparable接口的。
public T findMaxVal(T[] array){
// 假设第一个就是最大的
T max = array[0];
for (int i = 0; i < array.length; i++) {//通过循环遍历找到array数组中最大的值
if(array[i].compareTo(max) > 0){//②所以这里的comparable接口的compareTo能够在这里调用
max = array[i];
}
}
return max;//将最大值赋值给max并返回
}
}
//---------------------------------------------------------------------------------
public class Test {
public static void main(String[] args) {
Person[] array2 = {new Person(77),new Person(99),new Person(66)};
Alg<Person> alg2 = new Alg<>();
//当T为Person作为参数传入时
// 由于它并没有实现comparable这个接口所以他会报错
//解决办法:
// 创建Person这个类,然后去实现comparable这个接口
// 最后重写compareTo这个方法。
System.out.println(alg2.findMaxVal(array2).age);
}
/*写一个泛型类,求一个数组中的最大值*/
class Person implements Comparable<Person>{
private int age ;
// 构造函数,用于初始化Person对象的age属性,这才能使得你在后面调用这个方法去进行不同年龄的比较
public Person(int age) {
this.age = age;
}
public int getAge() {
return age;
}
@Override
public int compareTo(Person o) {
return this.age - o.age;
}
}
//---------------------------------------------------------------------------------
class Alg<T extends Comparable<T> >{//①传入的T一定是实现这个comparable接口的。
public T findMaxVal(T[] array){
// 假设第一个就是最大的
T max = array[0];
for (int i = 0; i < array.length; i++) {//通过循环遍历找到array数组中最大的值
if(array[i].compareTo(max) > 0){//②所以这里的comparable接口的compareTo能够在这里调用
max = array[i];
}
}
return max;//将最大值赋值给max并返回
}
}
public class Test {
public static void main(String[] args) {
Person[] array2 = {new Person(77),new Person(70),new Person(66)};
Alg<Person> alg2 = new Alg<>();
//当T为Person作为参数传入时
// 由于它并没有实现comparable这个接口所以他会报错
//解决办法:
// 创建Person这个类,然后去实现comparable这个接口
// 最后重写compareTo这个方法。
System.out.println(alg2.findMaxVal(array2).getAge());
}
方法限定符 <类型形参列表> 返回值类型 方法名称(形参列表) { ... }
public<T extends Comparable<T>> T findMaxVal(T[] array){ }
/*泛型方法*/
class Alg2{
public<T extends Comparable<T>> T findMaxVal(T[] array){
// 假设第一个就是最大的
T max = array[0];
for (int i = 0; i < array.length; i++) {//通过循环遍历找到array数组中最大的值
if(array[i].compareTo(max) > 0){//②所以这里的comparable接口的compareTo能够在这里调用
max = array[i];
}
}
return max;//将最大值赋值给max并返回
}
}
public class Test {
public static void main(String[] args) {
Alg2 alg2 = new Alg2();
Integer[] array = {1,4,3,8,7,5};
// 调用方法的两种写法
// 写法①
System.out.println(alg2.<Integer>findMaxVal(array));
// 写法②:省略<Integer>
System.out.println(alg2.findMaxVal(array));//根据实参array的值知道T是什么
}
/*泛型方法*/
class Alg3{
public static <T extends Comparable<T>> T findMaxVal(T[] array){
// 假设第一个就是最大的
T max = array[0];
for (int i = 0; i < array.length; i++) {//通过循环遍历找到array数组中最大的值
if(array[i].compareTo(max) > 0){//②所以这里的comparable接口的compareTo能够在这里调用
max = array[i];
}
}
return max;//将最大值赋值给max并返回
}
}
public class Test {
public static void main(String[] args) {
Integer[] array = {1,4,3,10,7,5};
// 调用方法的两种写法
// 写法①
System.out.println(Alg3.<Integer>findMaxVal(array));
// 写法②:省略<Integer>
System.out.println(Alg3.findMaxVal(array));//根据实参array的值知道T是什么
}
Alg2
,静态方法Alg3
少了类对象的创建。