可以被自定义的———泛型

 

1、使用泛型的意义?

ArrayList集合类的定义:

————ArrayList底层是使用数组的方式实现List集合的。——>做大量的访问员说或修改元素,它的效率高

           ArrayList集合元素定义的是Object数组。该数组中可以存放任何类型的对象。所以,我们并不清楚集合元素,到底指向的是什么样的对象。所以,在使用集合元素时,会先进行类型转换,再调用方法。这时,如果不清楚集合中存放元素的类型,那么,就很容易抛出java.lang.ClassCastException类型转换异常。

那么能不能规定,集合中只能存放什么类型的元素,从而在使用集合元素时,开发者可以清晰的知道集合元素的类型,因此避免这样的类型转换异常呢?泛型,可以解决这些问题。

2、什么是泛型?

泛型:——>是用来限制集合容器只能存放某种数据类型的。泛型可以省略,如果省略,默认泛型是Object类型。

泛型是在JDK1.5中提出的。语法:集合类类名<元素类型>集合对象名 = new 集合类类名<元素类型>();

其中< >里面只能写一种数据类型,且必须是引用数据类型。

声明变量的< >必须与new后面的< >保持一致。

ArrayList<String> strLst = new ArrayList<String>();


ArrayList<String> strLst = new ArrayList<>();//JDK1.7才有的钻石语法

strLst.add(“hello”);
String str = strLst.get(0);

泛型,大家也可以理解为“参数化类型”。也就是,可以将一个类中的某些属性的数据类型、方法参数类型、返回类型,都以变量方式表示。在使用/调用时传入具体的类型。

我们来看一下,集合中是如何规定集合元素类型的

 
public class ArrayList<E>{

……

public E get(int index) {……}

public boolean add(E e) {……}

……

}

 

注意这个E。这可以看做是参数化的类型,ArrayList中采用泛型化定义之后,中的E表示类型形参,可以接收具体的类型实参,凡是出现E的地方,均表示相同的接受自外部的类型实参。换句话说,在定义ArrayList对象时,规定是什么类型,那么凡是引用类型变量E的地方,就是什么类型。

例如:

 

1

2

3

4

5

6

7

8

 

//定义了E参数的类型为String

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

//添加元素时,add方法参数为E变量类型。由于定义list对象时,定义了类型为String,那么add方法形参变量类型就是String类型

list.add("abc");

//编译错误,定义list对象时,泛型为String,只能添加String对象

list.add(new JFrame());

//get方法返回的是E变量类型。由于定义list对象时,定义了类型为String,那么get方法返回的就是String类型

String str = list.get(0);

集合中解决类型转换异常的思路是:通过对象中泛型的定义,在添加元素时,规定只能添加某个类型的元素。如果添加其他类型的对象,那么编译错误。这样,取集合元素时,当然也只能取出同一类型的对象。这样就避免了类型转换异常。

所以,从在加上泛型定义的集合中取出元素时,无需进行类型转换,直接可以定义泛型变量接收集合元素。同样的两个ArrayList集合,也可以通过不同泛型的定义,从而规定存放集合的元素类型。

 

1

2

 

ArrayList<String> slist = new ArrayList<String>(); //只能存放String对象

ArrayList<Integer> ilist = new ArrayList<Integer>();//只能存放Integer对象

我们也可以给一个类或一个接口,定义多个泛型参数。

Map集合定义:集合中的元素是以键值对的形式成对出现的。

键值对(K-V),K-Key,V-Value;

每一个元素在放置到容器中的时候,除了要放置它本身以外,还需要指定它的键是多少;一个容器中的每个元素的键不能重复。

定义Map对象时,我们可以给其中的键对象K,和值对象V,指明具体的类型。那么,凡是引用K类型的属性类型、方法参数,方法返回类型,就必须和定义Map对象时的K类型一致。同样,凡是引用V类型的属性类型、方法参数、方法返回类型,也必须和定义Map对象时的V类型一致。

3、自定义泛型

泛型不限于定义在集合框架,是还有比如需要定义类型参数的类、接口、方法都可以。

集合框架中有一个工具类:Collections。该类中提供了一个sort排序方法,定义如下:

 

1

2

3

 

public class Collections{

public static void sort(List<T> list, Comparator<T> c){……}

}

sort方法在给集合元素排序时,需要由开发者定义排序的规则。这样,要由开发者实现Comparator接口,从而定义集合元素的比较规则。

不过,开发者在实现Comparator接口时,需要指出,是给什么样类型元素定义比较规则。

Comparator接口定义如下:

 

1

2

3

 

public interface Comparator<T> {

public int compare(T o1, T o2);

}

开发者在实现接口时,定义了Comparator比较器泛型类型后,compare方法参数的类型,就变成了定义比较器泛型的类型。

 

1

2

3

4

5

6

7

 

new Comparator<Student>(){

public int compare(Student o1, Student o2) {

return 0;

}

};

开发者在重写compare()方法时,就可以定义两个Student对象比较的规则了。

接口、类和方法都可以使用泛型去定义。

在具体使用时,可以分为泛型接口、泛型类和泛型方法。

在实际开发中,我们也可以通过泛型的定义,来规范一些属性、方法参数,以及返回类型。

 

总结:

1、泛型,表示参数化类型。可以将一个类中的某些属性的数据类型、方法参数类型、返回类型,都以变量方式表示。在使用/调用时传入具体的类型。
2、可以给一个类或一个接口,定义一个或多个泛型参数。使用的类型和泛型定义的类型一致。
3、泛型,我们也可以根据业务需要进行自定义。接口、类和方法也都可以使用泛型去定义。

4、泛型的好处:1、省略了强转的代码;2、可以吧运行时的问题提前到编译期。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值