泛型
来源:互联网 发布:java的编程工具 编辑:程序博客网 时间:2024/06/08 20:08
## generic 一般的;广泛类型的;
##输出字符串的长度功能
import java.util.*;class GenericDemo { public static void main(String[] args) { ArrayList al = new ArrayList(); al.add("java01"); al.add("java002"); al.add("java0003"); al.add("java00004"); Iterator it = al.iterator(); while(it.hasNext())//输出字符串的长度,要用到自付出的特有方法 { String s =(String)it.next();//由于多态,Object obj = it.next();父类中没有字符串长度特有方法,必须向下转型 System.out.println(s+"长度:"+s.length()); } }}
(1)集合中只能添加对象,但是1.6以后集合有了新特性,可以添加基本数据类型:
添加基本数据类型的原理:
基本数据类型包装类:自动装箱、自动拆箱
ArrayList al = new ArrayList(); al.add(4);//Integer i = 4;//这里4是一个对象,i是类类型引用指向这个常量对象
ArrayList al = new ArrayList();
al.add(4);//Integer i = 4;//这里4是一个对象,i是类类型引用指向这个常量对象
(2)发现问题,集合中传入字符串以后就不能传入其他类型的数据,会提示ClassCastException 类型转换异常
##这种问题在编译时期不会提示,在运行时期会提示异常,使用户无法解决
(3)为了避免这一安全问题,1.5增加了集合的新特性-“泛型”
泛型的概述:规定集合接收数据的数据类型,规定迭代器的接收类型
##切记:泛型的作用:“指定具体类型”
ArrayList<String> al = new ArrayList<String>(); Iterator<String> it = al.iterator(); ArrayList<String> al = new ArrayList<String>(); Iterator<String> it = al.iterator(); ##规定了泛型,如果输入其他类型数
据,在编译时就会提示报错
<>就是用来约束类型的,泛型<>中接收的一定是“引用数据类型”
(4)泛型的好处:
1.将运行时期的类型转换异常转移到了编译时期:
方便程序员解决问题,让运行时期问题减少,安全
2.避免了强制转换的麻烦(给迭代器规定泛型不用再强制转换)
7、泛型小练习:
//按照长度对字符串进行排序
import java.util.*;class LenComparator implements Comparator<String>{ public int compare(String o1,String o2) { int num = new Integer(o1.length()).compareTo(new Integer(o2.length()));//长度倒叙排列将对象互换 if(num==0) return o1.compareTo(o2);//长度倒叙排列将对象互换 return num; }}class GenericDemo2 { public static void main(String[] args) { TreeSet<String> ts = new TreeSet<String>(new LenComparator()); ts.add("java01"); ts.add("java02"); ts.add("java03"); ts.add("java004"); ts.add("java0005"); Iterator<String> it = ts.iterator(); while(it.hasNext()) { String s = it.next(); System.out.println(s); } }}
(1)集合可以定义泛型,迭代器可以定义泛型,比较器接口也可以定义泛型:
TreeSet<String> ts = new TreeSet<String>();//集合泛型 Iterator<String> it = ts.iterator();//迭代器泛型 class C implements Comparator<String>//实现比较器接口泛型 public int compare(String o1,String o2)//实现了接口泛型,复写的方法参数也必须是泛型数据类型
(2)基本数据包装类有compareTo()比较,用来比较两个数值的大小
o1.length()//得到的字符串长度是一个整数
new Integer()用来接收这个长度,这个整数对象就具有了compareTo()这个比较方法,可以比较两个数值的大小
o1.compareTo()//字符串的比较方法是用来比较两个字符串的自然顺序
##若想按长度从大到小输出,只需要把o1和o2两个比较对象兑换位置即可,因为二叉树>1的往右放,<1的往左放
8、泛型类:
class Student{ private String name; private int age; Student(String name,int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; }}class Utils<QQ>//这个就是反省类{ private QQ q; public void setObject(QQ q) { this.q=q; } public QQ getObject() { return q; }}class GenericClassDemo { public static void main(String[] args) { Utils<Student> u = new Utils<Student>();//新建一个反省类对象,指定类型为Student类型 u.setObject(new Student("lisi",20));//设置对象方法 Student stu = u.getObject();//用Student类型引用接收一个设置好的了Student对象 System.out.println(stu.getName()+"......"+stu.getAge());//输出这个对象的名字和年龄 }}
9、泛型方法:
泛型类:将泛型定义在类上 class A<E>
泛型方法:public <T> void show(T t)
(1)当定义一个泛型类时,泛型类中的方法所操作的类型就都是泛型类型了:
例: class Demo<T>
void show(T t){}
void print(T t){}
Demo<String> d = new Demo<String>();
这时d对象在调用show()和print方法时传入的对象只能是String类型的,出现了操作的局限性
##如果想操作其他数据类型,就只能再new一个新的对象
(2)解决这个问题,可以不定义泛型类 而定义泛型方法:
class Demo
public <T> void show(T t){}
public <T> void print(T t){}
Demo d = new Demo();
d.show(String);
d.print(new Integer(3));
## 此时就可以用一个对象操作不用类型的数据了,解决了数据类型操作的局限性
## 切记:泛型中操作的数据类型只能是“引用数据类型”
10、泛型类中一样可以定义泛型方法:
class Demo<T>
{
public void show(T t)
{}
public <Q> void print(Q q)
{}
}
主函数中:
Demo<String> d = new Demo<String>();
d.show(String);//可以通过编译
d.show(4);//编译失败,show()方法是String类型操作方法,
d.print(3.14);编译成功:泛型方法
## 泛型方法的书写格式:
public <Q> void pritn(Q q)
泛型定义在方法上,将泛型置于返回值类型前面
11、静态泛型方法:
(1)class Demo<T>
public static void method(T t)
##此方法在调用时会提示:静态访问非静态内容
因为要调用类中的方法就要建立对象,静态随着类先加载在内存中,对象后加载,而且对象在堆中,是非静态内容,不能将数据传入静态方法中
(2)静态泛型方法:
class Demo<T>
public static <Q> void method(Q q)
##此方法是静态泛型方法,调用时只传入数据,不是类对象的特有数据,所以可以编译通过
##总结:
静态方法不可以访问类上定义的泛型
静态泛型方法可以操作不确定的引用数据类型
12、泛型接口:
## 泛型接口的两种格式:
(1)第一种格式:在子类继承接口时就明确泛型类型:
interface Inter<T>{ public void show(T t);}class SubInter implements Inter<String>//实现接口时就已经明确了泛型类型{ public void show(String s) { System.out.println("show..."+s); }}class GenericInterfaceDemo{ public static void main(String[] args) { SubInter s = new SubInter(); s.show("haha"); }}
(2)第二种格式:在子类实现接口时不明确泛型类型,让用户自己定义数据类型
interface Inter<T>{ public void show(T t);}class SubInter<T> implements Inter<T>//实现接口时不明确泛型类型,由用户自定义数据类型{ public void show(T t) { System.out.println("show..."+t); }}class GenericInterfaceDemo{ public static void main(String[] args) { //不是泛型方法就要实例两个对象操作不同的数据类型 SubInter<String> s = new SubInter<String>(); s.show("hehe"); SubInter<Integer> s1 = new SubInter<Integer>(); s1.show(5); }}
13、集合中的泛型--通配符:
(1)当在类中定义一个方法(普通方法或静态方法),要接收一个集合,但不明确传入集合的类型时,可以用“通配符?”来代替:
public static void show(ArrayList<?> al)//静态函数方便内部调用,ArrayList<?> 传入的集合类型可以是任意类型
{
Iterator<?> it = al.iterator();//传入集合是不明确类型,迭代器也要接收不明确类型
while(it.hasNext())
{
System.out.println(it.next());
}
}
##迭代器的类型随着函数传入的集合类型而变化
(2)第二种方式:静态泛型方法
public static <C> void show(ArrayList<C> al)//静态函数方便内部调用,ArrayList<C> 传入的集合类型可以是任意类型
{
Iterator<C> it = al.iterator();//传入集合是不明确类型,迭代器也要接收不明确类型
while(it.hasNext())
{
System.out.println(it.next());
}
}
14、泛型的高级应用:泛型限定
## GenericLimit 泛型限定 ;
(1)泛型限定:
上限:? extends E ,E这个类型和它的子类型都可以接收
下限:? super E ,E这个类型和它的父类型都可以接收
例:
/*
定义一个泛型上限:
person父类
Student子类
定义一个ArrayList接口,分别添加父类对象,子类对象
调用方法,方法中用迭代器遍历元素,要求可以访问父类和子类对象,获取对象的名字
*/
import java.util.*;class Person{ private String name; Person(String name) { this.name = name; } public String getName() { return name; }}class Student extends Person{ Student(String name) { super(name); }}class GenericLimitDemo { public static void main(String[] args) { ArrayList<Person> al = new ArrayList<Person>();//定义一个接收Person类型的泛型集合 al.add(new Person("java01")); al.add(new Person("java02")); al.add(new Person("java03")); ArrayList<Student> al1 = new ArrayList<Student>();//定义一个接收Student类型的泛型集合 al1.add(new Student("java--01")); al1.add(new Student("java--02")); al1.add(new Student("java--03")); showName(al); showName(al1); } public static void showName(ArrayList<? extends Person> al)//泛型上限:限制了父类是Person,只要是它的子类即可 { Iterator<? extends Person> it = al.iterator(); while(it.hasNext()) { System.out.println(it.next().getName()); } }}
##public static void showName(ArrayList<? super Student> al)//泛型下限:限制了子类Student,只要是它的父类即可
(2)Comparable和Comparator(比较器)的泛型限定:
Comparable(集合<? super E>)泛型下限:
Comparator(集合<? super E>)泛型下限:只要是E的父类对象都可以
##Comparable和Comparator的泛型限定都是下限,只要是E的父类都可以传入:
例:
1.class Student implements Comparable<Student>:此类是Student,它继承了Person,那只要是Student的父类就可以作为泛型
{
public int comparable(Student s){}
}
##传入的是Person也可以:
class Student implements Comparable<Person>
{
public int comparable(Person s){}//如果传入Student Person s = new Student();这是多态
}
2.class MyComp implements Comparator<Student>:比较器的操作泛型是Student,是它的父类就可以作为泛型,因为下限
{
public int compare(Student s1,Student s2){}
}
##传入父类的泛型:
class MyComp implements Comparator<Person>
{
public int compare(Person p1,Person p2){}//传入Student一样是多态
}
(3)Collection中的方法:
containsAll(Collection<?> c) :此集合包含另一个结合的所有元素,返回true
removeAll(Collection<?> c):移除与指定集合的交集元素,移除成功返回true,否则返回false
retainAll(Collection<?> c):保留与指定集合的交集元素
(4)泛型限定提高了扩展性:
##规定类型限定以后,以后的新类只要继承父类就可以传入泛型类中
- 泛型
- 泛型
- 泛型
- 泛型
- 泛型
- 泛型
- 泛型
- 泛型
- 泛型
- 泛型
- 泛型
- 泛型
- 泛型
- 泛型
- 泛型
- 泛型
- 泛型
- 泛型
- JSP request详解
- 自旋锁和互斥锁区别
- 白话经典算法系列之一 冒泡排序的三种实现
- cuda的Pinned Memory(分页锁定内存)
- 网络编程之路---10
- 泛型
- 静态HTML页面的访问量统计实现
- Windows使用msysgit搭建连接CSDN的CODE过程记录
- Excel中PMT计算月供函数的java实现
- 黑马程序员 java动态代理
- 在Windows Server 2003下建立隐藏帐户
- 为什么使用 SLF4J 而不是 Log4J 来做 Java 日志
- 任务和特权级保护
- 探索Win32系统之窗口类(转载)