泛型
泛型其实质就是将数据的类型参数化。通过为类、接口、及方法设置类型参数来定义泛型。泛型使一个类或一个方法可在多种不同类型的对象上进行操作。运用泛型就是编写的代码可被多种类型不同的对象重用,从而减少数据类型转换的潜在错误。
泛型的概念
泛型是在定义类、接口、或方法时通过为其增加“类型参数”来实现的。即泛型所操作的数据类型被指定为一个参数,这个参数被称为类型参数,当这种类型参数用在类、接口以及方法的声明中时,分别称为泛型类、泛型接口、泛型方法。定义格式如下:
泛型类:[修饰符] class 类名
泛型接口:[public] interface 接口名
泛型方法:[public] [static] 返回值类型 方法名(T参数)
泛型类及应用
调用泛型类的方法传递或返回数据类型时可以不用进行类型转换,直接用T作为类型来代替参数类型或返回值类型。
在实例化泛型类的过程中,实际类型必须是引用类型,即必须是类类型,不能用如int、double、char等这样的基本类型来替换类型参数T
public class App1 <T>{ //定义泛型类,T是类型参数
private T obj; //定义泛型类的成员变量
public T getObj(){ //定义泛型类的方法
return obj;
}
public void setObj(T obj){
this.obj=obj;
}
public static void main(String[] args) {
App1<String> name=new App1<String>();
App1<Integer> age=new App1<Integer>();
name.setObj("张 三");
String newname= name.getObj();
System.out.println("姓名:"+newname);
age.setObj(22);
int newage= age.getObj();
System.out.println("年龄:"+newage);
}
}
泛型方法
一个方法是否是泛型方法与其所在的类是否是泛型类没有关系,在Java中任何方法都可声明为泛型方法。定义泛型方法,只需将放在方法返回值类型前即可。
Java泛型方法广泛使用在方法返回值和参数均是容器类对象的情况。
一个static方法,无法访问泛型类的类型参数,若要使用泛型能力必须使其成为泛型方法
public class App2 {
public static void main(String[] args) {
Integer[]num={1,2,3,4,5};
String []str={"红","黄","蓝","绿","紫"};
App2.display(num);
App2.display(str);
}
public static <E> void display(E[] list){
for (int i=0;i< list.length;i++){
System.out.print(list[i]+" ");
}
System.out.println();
}
}
限制泛型的可用类型
在定义泛型类时,默认可以使用任何类型来实例化一个泛型类对象,但Java语言也可以在用泛型类创建对象时对数据类型做出限制。语法如下:
class ClassName
其中 anyclass是指某个类或接口。
T有一个限制,必须是anyclass类或是继承了anyclass类的子类或是实现了anyclass接口的类,无论anyclass是啥,都必须使用extends关键字
class GeneralType<T extends Number>{
T obj;
public GeneralType(T obj){
this.obj=obj;
}
public T getObj() {
return obj;
}
}
public class App3 {
public static void main(String[] args) {
GeneralType<Integer>num=new GeneralType<Integer>(5);
System.out.println("给出的参数是:"+num.getObj());
//下面两行代码是错误的,因为String不是Number或其子类
//GeneralType<String>s=new GeneralType<String>("hello");
//System.out.println("给出的参数是:"+s.getObj());
}
}
泛型的类型通配符和泛型数组的应用
通配符“?“的主要作用一是用于创建可重新赋值但不可修改其内容的泛型对象;二是用在方法的参数中,限制传入不想要的类型实参。当需要在一个程序中使用同一个泛型对象名去引用不同的泛型对象时,就要使用通配符”?“创建泛型类对象,但条件是被创建的这些不同泛型对象的类型实参必须是某个类或是继承该类的子类或是实现某个接口的类。
类型通配符”?“的使用方法:
class GeneralType1<T>{
T obj;
public T getObj() {
return obj;
}
public void setObj(T obj) {
this.obj = obj;
}
public static void showObj(GeneralType1<? extends String> o){
System.out.println("给出的值是:"+o.getObj());
}
}
public class App4 {
public static void main(String[] args) {
GeneralType1<String>n=new GeneralType1<String>();
n.setObj("李 四");
GeneralType1.showObj(n);
GeneralType1<Double>num=new GeneralType1<Double>();
num.setObj(2.0);
System.out.println(num.getObj());
}
}
定义泛型类声明数组
public class App4_1 <T>{
private T[] array;
public T[] getArray() {
return array;
}
public void setArray(T[] array) {
this.array = array;
}
public static void main(String[] args) {
App4_1<String>a=new App4_1<String>();
String[] array={"红色","黄色","蓝色","绿色","紫色"};
a.setArray(array);
for (int i=0;i<a.getArray().length;i++){
System.out.print(a.getArray()[i]+" ");
}
}
}
继承泛型类与实现泛型接口
public class ExtendClass{} 定义泛型类
class SubClass<T1,T2,T3>extendClass{} 泛型类被继承
interface Facee{} 定义泛型接口
class SubClass<T1,T2>implements Face{} 泛型接口被实现
容器类
容器类是数据结构,是Java以类库的形式供用户开发程序时可直接使用。
数据结构是以某种方式将数据组织在一起,并存储在计算机中。它不仅可以存储数据还支持访问和处理数据的操作。在面向对象思想里,一种数据结构被认为是一个容器。数组是一种简单的数据结构,出数组外Java还提供了许多其他数据结构,通常被称为容器类或集合类
容器接口Collection
该容器接口Collection通常不能直接使用,但该接口提供了添加、删除元素、管理数据的方法。Set接口和List接口都继承了Collection接口,所有这些方法对他俩也是通用的。
列表接口List
它是一种包含有序元素的线性表,其中元素必须按顺序存放,且可重复也可是空值null。元素的顺序关系由添加到列表的先后或元素值大小来决定。List接口使用下标来访问元素。
实现List接口的类主要有两个:链表类LinkedList和数组列表类ArrayList。它们都是线性表。如何选用这两种线性表,通常的原则是:若要通过下标随机访问元素,但除了在末尾处之外,不在其他位置插入或删除元素,则应该选择ArrayList类;但若需要在线性表的任意位置上进行插入或删除操作,则应选择LinkedList类。