集合框架(泛型概述)
2014-02-26 23:12
148 查看
泛型:jdk1.5版本以后出现的一个安全机制。表现格式:< >
好处:
1:将运行时期的问题ClassCastException问题转换成了编译失败,体现在编译时期,程序员就可以解决问题。
2:避免了强制转换的麻烦。
只要带有<>的类或者接口,都属于带有类型参数的类或者接口,在使用这些类或者接口时,必须给<>中传递一个具体的引用数据类型。
泛型技术:其实应用在编译时期,是给编译器使用的技术,到了运行时期,泛型就不存在了。
为什么? 因为泛型的擦除:也就是说,编辑器检查了泛型的类型正确后,在生成的类文件中是没有泛型的。
在运行时,如何知道获取的元素类型而不用强转呢?
泛型的补偿:因为存储的时候,类型已经确定了是同一个类型的元素,所以在运行时,只要获取到该元素的类型,在内部进行一次转换即可,所以使用者不用再做转换动作了。
练习:使用泛型按照字符串长度排序字符串,长度相同比较字符串。
[java] view
plaincopy
import java.util.*;
public class TreeSetTest {
public static void main(String[] args) {
TreeSet<String> s1 = new TreeSet<String>(new StrLenComparator());
s1.add("aaa");
s1.add("asfasf");
s1.add("sdds");
s1.add("cc");
s1.add("tttt");
Iterator<String> it = s1.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
}
}
class StrLenComparator 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;
}
}
什么时候用泛型类呢?
当类中的操作的引用数据类型不确定的时候,以前用的Object来进行扩展的,现在可以用泛型来表示。这样可以避免强转的麻烦,而且将运行问题转移到的编译时期。
[java] view
plaincopy
class Worker
{
}
class Students
{
}
//泛型类
class Utils<QQ>
{
private QQ q;
public void setObject(QQ q)
{
this.q = q;
}
public QQ getObject()
{
return q;
}
}
public class GenericDemo {
public static void main(String[] args) {
Utils<Students> u = new Utils<Students>();
u.setObject(new Students());
Students w = u.getObject();
}
}
集合框架---泛型方法:
泛型类定义的泛型,在整个类中有效,如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有方法要操作的类型就已经固定了。
为了让不同方法可以操作不同类型,而且类型还不确定,可以将泛型定义在方法上。
特殊之处:
静态方法不可以访问类上定义的泛型。
如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上。
[java] view
plaincopy
class Demo
{
//泛型方法
public <T> void show(T t)
{
System.out.println("show:"+t);
}
//泛型方法
public <Q> void print(Q q)
{
System.out.println("print:"+q);
}
}
public class GenericDemo2 {
public static void main(String[] args) {
Demo d = new Demo();
d.show("haha");
d.print("papa");
}
}
集合框架---泛型接口:
[java] view
plaincopy
//泛型定义在接口上
interface Inter<T>
{
void show(T t);
}
class InterImpl <T> implements Inter<T>
{
public void show(T t)
{
System.out.println("show:"+t);
}
}
public class GenericDemo3 {
public static void main(String[] args) {
InterImpl<Integer> i = new InterImpl<Integer>();
i.show(3);
}
}
泛型中的通配符:可以解决当具体类型不确定的时候,这个通配符就是 ? ;当操作类型时,不需要使用类型的具体功能时,只使用Object类中的功能。那么可以用 ? 通配符来表未知类型。
泛型限定:
上限:?extends E:可以接收E类型或者E的子类型对象。
[java] view
plaincopy
import java.util.*;
public class GenericDemo4 {
public static void main(String[] args) {
// ArrayList<Person> al = new ArrayList<Person>();
// al.add(new Person("aaa"));
// al.add(new Person("bbb"));
// al.add(new Person("ccc"));
ArrayList<Student2> al1 = new ArrayList<Student2>();
al1.add(new Student2("aaa"));
al1.add(new Student2("bbb"));
al1.add(new Student2("ccc"));
printColl(al1);
}
public static void printColl(ArrayList<? extends Person2> al)
{
Iterator<? extends Person2> it = al.iterator();
while(it.hasNext())
{
System.out.println(it.next().getName());
}
}
}
class Person2
{
private String name;
Person2(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
}
class Student2 extends Person2
{
Student2(String name)
{
super(name);
}
}
下限:?super E:可以接收E类型或者E的父类型对象。
上限什么时候用:往集合中添加元素时,既可以添加E类型对象,又可以添加E的子类型对象。为什么?因为取的时候,E类型既可以接收E类对象,又可以接收E的子类型对象。
下限什么时候用:当从集合中获取元素进行操作的时候,可以用当前元素的类型接收,也可以用当前元素的父类型接收。
泛型的细节:
1)、泛型到底代表什么类型取决于调用者传入的类型,如果没传,默认是Object类型;
2)、使用带泛型的类创建对象时,等式两边指定的泛型必须一致;
原因:编译器检查对象调用方法时只看变量,然而程序运行期间调用方法时就要考虑对象具体类型了;
3)、等式两边可以在任意一边使用泛型,在另一边不使用(考虑向后兼容);
好处:
1:将运行时期的问题ClassCastException问题转换成了编译失败,体现在编译时期,程序员就可以解决问题。
2:避免了强制转换的麻烦。
只要带有<>的类或者接口,都属于带有类型参数的类或者接口,在使用这些类或者接口时,必须给<>中传递一个具体的引用数据类型。
泛型技术:其实应用在编译时期,是给编译器使用的技术,到了运行时期,泛型就不存在了。
为什么? 因为泛型的擦除:也就是说,编辑器检查了泛型的类型正确后,在生成的类文件中是没有泛型的。
在运行时,如何知道获取的元素类型而不用强转呢?
泛型的补偿:因为存储的时候,类型已经确定了是同一个类型的元素,所以在运行时,只要获取到该元素的类型,在内部进行一次转换即可,所以使用者不用再做转换动作了。
练习:使用泛型按照字符串长度排序字符串,长度相同比较字符串。
[java] view
plaincopy
import java.util.*;
public class TreeSetTest {
public static void main(String[] args) {
TreeSet<String> s1 = new TreeSet<String>(new StrLenComparator());
s1.add("aaa");
s1.add("asfasf");
s1.add("sdds");
s1.add("cc");
s1.add("tttt");
Iterator<String> it = s1.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
}
}
class StrLenComparator 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;
}
}
什么时候用泛型类呢?
当类中的操作的引用数据类型不确定的时候,以前用的Object来进行扩展的,现在可以用泛型来表示。这样可以避免强转的麻烦,而且将运行问题转移到的编译时期。
[java] view
plaincopy
class Worker
{
}
class Students
{
}
//泛型类
class Utils<QQ>
{
private QQ q;
public void setObject(QQ q)
{
this.q = q;
}
public QQ getObject()
{
return q;
}
}
public class GenericDemo {
public static void main(String[] args) {
Utils<Students> u = new Utils<Students>();
u.setObject(new Students());
Students w = u.getObject();
}
}
集合框架---泛型方法:
泛型类定义的泛型,在整个类中有效,如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有方法要操作的类型就已经固定了。
为了让不同方法可以操作不同类型,而且类型还不确定,可以将泛型定义在方法上。
特殊之处:
静态方法不可以访问类上定义的泛型。
如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上。
[java] view
plaincopy
class Demo
{
//泛型方法
public <T> void show(T t)
{
System.out.println("show:"+t);
}
//泛型方法
public <Q> void print(Q q)
{
System.out.println("print:"+q);
}
}
public class GenericDemo2 {
public static void main(String[] args) {
Demo d = new Demo();
d.show("haha");
d.print("papa");
}
}
集合框架---泛型接口:
[java] view
plaincopy
//泛型定义在接口上
interface Inter<T>
{
void show(T t);
}
class InterImpl <T> implements Inter<T>
{
public void show(T t)
{
System.out.println("show:"+t);
}
}
public class GenericDemo3 {
public static void main(String[] args) {
InterImpl<Integer> i = new InterImpl<Integer>();
i.show(3);
}
}
泛型中的通配符:可以解决当具体类型不确定的时候,这个通配符就是 ? ;当操作类型时,不需要使用类型的具体功能时,只使用Object类中的功能。那么可以用 ? 通配符来表未知类型。
泛型限定:
上限:?extends E:可以接收E类型或者E的子类型对象。
[java] view
plaincopy
import java.util.*;
public class GenericDemo4 {
public static void main(String[] args) {
// ArrayList<Person> al = new ArrayList<Person>();
// al.add(new Person("aaa"));
// al.add(new Person("bbb"));
// al.add(new Person("ccc"));
ArrayList<Student2> al1 = new ArrayList<Student2>();
al1.add(new Student2("aaa"));
al1.add(new Student2("bbb"));
al1.add(new Student2("ccc"));
printColl(al1);
}
public static void printColl(ArrayList<? extends Person2> al)
{
Iterator<? extends Person2> it = al.iterator();
while(it.hasNext())
{
System.out.println(it.next().getName());
}
}
}
class Person2
{
private String name;
Person2(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
}
class Student2 extends Person2
{
Student2(String name)
{
super(name);
}
}
下限:?super E:可以接收E类型或者E的父类型对象。
上限什么时候用:往集合中添加元素时,既可以添加E类型对象,又可以添加E的子类型对象。为什么?因为取的时候,E类型既可以接收E类对象,又可以接收E的子类型对象。
下限什么时候用:当从集合中获取元素进行操作的时候,可以用当前元素的类型接收,也可以用当前元素的父类型接收。
泛型的细节:
1)、泛型到底代表什么类型取决于调用者传入的类型,如果没传,默认是Object类型;
2)、使用带泛型的类创建对象时,等式两边指定的泛型必须一致;
原因:编译器检查对象调用方法时只看变量,然而程序运行期间调用方法时就要考虑对象具体类型了;
3)、等式两边可以在任意一边使用泛型,在另一边不使用(考虑向后兼容);
相关文章推荐
- Spring MVC和Struts2的比较
- HTML5 Video
- 【iOS-Cocos2d游戏开发之十八】解决滚屏背景/拼接地图有黑边(缝隙)/动画播放出现毛边以及禁止游戏中自动锁屏问题!
- 神经网络
- MySQL中Procedure事务编写基础笔记
- java学习脚印:反射与动态代理
- cocos2d-x 3.0 游戏我来啦 - 可视化创建工程
- iOS中协议的使用
- 【BFS】-PDSU-1112-最少操作数
- ubuntu使用xftp
- 认识Tempdb----概览和用法
- 是男人就下100层【第一层】——高仿微信界面(2)
- js get提交中文乱码解决方案
- 是男人就下100层【第一层】——高仿微信界面(2)
- 检测MSWORD.OLB是否注册及注册的代码
- C51指针
- C语言学习——顺序表
- maven仓库快速镜像
- [连载]C#程序设计(02)--- 构建C#应用程序
- 不同阶段学习C++推荐用书(也可以作为对这类图书内容的层次的评价)