黑马程序员_JAVA笔记15——集合框架(泛型)
2013-09-01 16:51
519 查看
------- android培训、java培训、期待与您交流! ----------
1、泛型:JDK1.5后出现的新特性,用于解决安全问题,是一个安全机制。
好处:
将运行时期出现问题ClassCastException异常,转移到编译时期,方便于程序员解决问题,让运行时期问题减少,提高安全。
避免了强制类型转换的麻烦
泛型理解:数组在定义的时候明确了存储类型,因此只能存储该类型的数据,若存其他类型数据,编译时期会出错。集合没有明确存储类型,任何类型都能存,编译不出错,但是在取数据的时候要注意类型的强制转换,但是一般情况下我们向集合中存的是同一种类型的数据,比如存放姓名,但是你向里存年龄,编译不出错,因为集合可以存任何数据类型的元素,但是在运行时就会出问题,当取姓名时,把年龄取出来了,这就是安全问题,我们一般情况下都尽量把问题在编译时期解决(编译时的问题,程序员解决;运行时出的问题,通常是用户遇到的,用户一般不能解决这种问题,需要程序员解决)。泛型,给集合声明了存储数据类型,提高了安全性,把问题在编译时期解决,同时因为声明了数据类型,也避免了在取数据时数据类型的转换。
泛型格式:通过<>来定义要操作的引用数据类型
在使用java提供的对象时,什么时候使用泛型?
通常在集合框架中很常见,只要见到<>就要定义泛型
其实<>就是用来接收类型的。
当使用集合时,将集合中药存储的数据类型作为参数传递到<>中即可。
示例:
class GenericDemo
{
public static void main(String[] args)
{
TreeSet<String> al = new TreeSet<String>(new GenComparator());//泛型,指定集合类数据类型
al.add("fdfd");
al.add("fffff");
al.add(3);//有泛型,编译出错;没有泛型,编译通过
Iterator<String> it = al.iterator();//表明是String类型的Iterator对象
while(it.hasNext())
{
String s = it.next();
//String s = (String)it.next();没有泛型,需类型转换
System.out.println(s.length());
}
}
}
class GenComparator implements Comparator<String>//定义泛型
{
public int compare(String o1,String o2)
{
int num = new Integer(o1.length()).compareTo(new Integer(o2.length()));
//若想倒序,new Integer(o2.length()).compareTo(new Integer(o1.length()));
if(num==0)
return o2.compareTo(o1);
return num;
}
}
2、泛型类,什么时候使用,当类中要操作的引用数据类型不确定的时候。基本数据类型不能使用。
早期定义Object来完成扩展
现在可以定义泛型类
class Worker
{
}
class Student
{
}
//这就是泛型类
class GenicClass<QQ>
{
private QQ q ;
public setGen(QQ q)
{
this.q = q;
}
public getGen()
{
return q;
}
}
//早期用Object
class GenicClass
{
private Object obj ;
public setGen( Object obj )
{
this.obj = obj;
}
public getGen()
{
return obj;
}
}
class GenicDemo
{
public static void main(String[] args)
{
//泛型类时
GenicClass<Student> gc = new GenicClass<Student>();
gc.setGen(new Student());
Student s= gc.getGen();//不需要类型转换
Worker w = gc.getGen();//编译报错,将类型转换问题出现在编译时期
//没泛型,用Object时
GenicClass gc = new GenicClass();
gc.setGen(new Student());
Student s = (Student)gc.getGen();//必须类型转换,否则编译报错
Worker w = (Worker)gc.getGen();//编译不报错,运行报错
}
}
3、泛型方法
泛型类定义的泛型,在整个类中有效,如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有操作的类型就已经固定了。
//泛型类
class Demo<T>
{
public void show(T t)
{
System.out.println(t);
}
public void print(T t)
{
System.out.println(t);
}
}
class GenDemo
{
public static void main(String[] args)
{
Demo<String> d = new Demo<String>();
d.show("new String");
d.print("new String")
}
}
为了让不同方法可以操作不同类型,而且类型还不确定,那么可以将泛型定义在方法上。
//泛型方法,方法上定义的类型只在方法内有效
class Demo
{
public <T> void show(T t)
{
System.out.println(t);
}
public <Q>void print(Q q)
{
System.out.println(t);
}
}
class GenDemo
{
public static void main(String[] args)
{
Demo d = new Demo();
d.show("new String");
d.print(new Integer(4));
}
}
//泛型类中也可以定义泛型方法
class Demo<R>
{
public void Clss(R r)
{
System.out.println(t);
}
public <T> void show(T t)
{
System.out.println(t);
}
public <Q>void print(Q q)
{
System.out.println(t);
}
public static <W> void method(W t)
{
System.out.println("method");
}
}
class GenDemo
{
public static void main(String[] args)
{
Demo<String> d = new Demo<String>();
d.Clss("fdfdf");
d.show("new String");//泛型类对象,在调用泛型类中定义的泛型方法时,使用的不是创建泛型类对象时声明的数据类型,而是使用的泛型方法自身声明的数据类型
d.print(new Integer(4));
Demo.method();//静态方法
}
}
注意:静态方法不可以访问类上定义的泛型,如果静态方法操作的引用数据类型不确定,可以将泛型定义在方法上。
//泛型定义在接口上,
interface Inter<T>
{
void show(T t);
}
class InterImp implements Inter<String>//类实现接口,并指明数据类型
{
public void show(String s)
{
System.out.println(s);
}
}
class InterImppp <T> implements Inter<T>//类实现接口,但不指明数据类型
{
public void show(T t)
{
System.out.println(t);
}
}
class InterDemo
{
public static void main(String[] args)
{
InterImp<String> ii = new InterImp<String>();
ii.show("DFDf");
InterImppp< String > iip = new InterImppp< String >();
iip.show("FdFG");
}
}
4、泛型高级应用
class GenericDemo
{
public static void main(String[] args)
{
ArrayList<String> al = new ArrayList<String>();
al.add("java_1");
al.add("java_2");
al.add("java_3");
al.add("java_4");
ArrayList<Integer> all = new ArrayList<Integer>();
all.add(5);
all.add(6);
all.add(2);
all.add(9");
printCloo(al);
printCloo(all);
}
//没有泛型时,即1.4以前没有泛型时 ,如下写法,虽然可以但不严谨
public static void printCloo(ArrayList al)
{
Iterator it = al.iterator();
while(it.hasNext());
System.out.println(it.next());
}
//有泛型时,可以用<?>代替泛型,表示类型不确定.<?>是占位符
public static void printCloo(ArrayList<?> al)
{
Iterator<?> it = al.iterator();
while(it.hasNext());
{
System.out.println(it.next());
System.out.println(it.next().length());//这里不可以,因为类型不明确,不确定是否有length()方法,泛型不能使用类型的特有方法。但是一些所有共用的方法可以用,例如toString()。
System.out.println(it.next().toString())
}
}
//有泛型时,可以用<T>,但静态时T需定义
public static <T>void printCloo(ArrayList<T> al)
{
Iterator<T> it = al.iterator();
while(it.hasNext());
{
T t = it.next();//这里可以对T进行一些操作,但是<?>不能。
System.out.println(it.next());
}
}
}
//<?>通配符,也可以理解为占位符
泛型的限定
<? extends E>表示既可以是传E 也可以传E的子类。上限。上边限定了
<? super E>表示可以接收E也可以接收E的父类。下限,下边限定了
示例:上限<? extends E>
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 GenericDemo
{
public static void main(String[] args)
{
ArrayList<Person> al = new ArrayList<Person>();
al.add(new Person("java_1"));
al.add(new Person("java_21"));
al.add(new Person("java_31"));
al.add(new Person("java_41"));
ArrayList<Student> all = new ArrayList<Student>();
all.add(new Student("ssss01"));
all.add(new Student("ssss02"));
all.add(new Student("ssss03"));
all.add(new Student("ssss04"));
all.add(new Student("ssss05"));
printCloo(al);
printCloo(all);
}
public static void printCloo(ArrayList<? extends Person> al)
{
Iterator<? extends Person> it = al.iterator();
while(it.hasNext());
{
System.out.println(it.next());
}
}
}
示例:下限<? super E>
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 Worker extends Person
{
Worker(String name)
{
super(name);
}
}
class GenericDemo
{
public static void main(String[] args)
{
TreeSet<Student> al = new TreeSet<Student>(new Comp());
al.add(new Student ("java_1"));
al.add(new Student ("java_21"));
al.add(new Student ("java_31"));
al.add(new Student ("java_41"));
TreeSet <Worker> all = new TreeSet <Worker>(new Comp());
all.add(new Worker ("ssss01"));
all.add(new Worker ("ssss02"));
all.add(new Worker ("ssss03"));
all.add(new Worker ("ssss04"));
all.add(new Worker ("ssss05"));
printCloo(al);
printCloo(all);
}
public static void printCloo(TreeSet<Person> al)//指定父类比较器
{
Iterator<Person> it = al.iterator();
while(it.hasNext());
{
System.out.println(it.next());
}
}
}
class Comp implements Comparator<Person >//指定父类比较器,因此其子类都可以使
//用,但是在该方法中只能使用父类的方
//法,而不能使用子类特有的方法。
{
public int compare(Person p1,Person p2)
{
int num = p1.getName().compareTo(p2.getName());
return num;
}
}
1、泛型:JDK1.5后出现的新特性,用于解决安全问题,是一个安全机制。
好处:
将运行时期出现问题ClassCastException异常,转移到编译时期,方便于程序员解决问题,让运行时期问题减少,提高安全。
避免了强制类型转换的麻烦
泛型理解:数组在定义的时候明确了存储类型,因此只能存储该类型的数据,若存其他类型数据,编译时期会出错。集合没有明确存储类型,任何类型都能存,编译不出错,但是在取数据的时候要注意类型的强制转换,但是一般情况下我们向集合中存的是同一种类型的数据,比如存放姓名,但是你向里存年龄,编译不出错,因为集合可以存任何数据类型的元素,但是在运行时就会出问题,当取姓名时,把年龄取出来了,这就是安全问题,我们一般情况下都尽量把问题在编译时期解决(编译时的问题,程序员解决;运行时出的问题,通常是用户遇到的,用户一般不能解决这种问题,需要程序员解决)。泛型,给集合声明了存储数据类型,提高了安全性,把问题在编译时期解决,同时因为声明了数据类型,也避免了在取数据时数据类型的转换。
泛型格式:通过<>来定义要操作的引用数据类型
在使用java提供的对象时,什么时候使用泛型?
通常在集合框架中很常见,只要见到<>就要定义泛型
其实<>就是用来接收类型的。
当使用集合时,将集合中药存储的数据类型作为参数传递到<>中即可。
示例:
class GenericDemo
{
public static void main(String[] args)
{
TreeSet<String> al = new TreeSet<String>(new GenComparator());//泛型,指定集合类数据类型
al.add("fdfd");
al.add("fffff");
al.add(3);//有泛型,编译出错;没有泛型,编译通过
Iterator<String> it = al.iterator();//表明是String类型的Iterator对象
while(it.hasNext())
{
String s = it.next();
//String s = (String)it.next();没有泛型,需类型转换
System.out.println(s.length());
}
}
}
class GenComparator implements Comparator<String>//定义泛型
{
public int compare(String o1,String o2)
{
int num = new Integer(o1.length()).compareTo(new Integer(o2.length()));
//若想倒序,new Integer(o2.length()).compareTo(new Integer(o1.length()));
if(num==0)
return o2.compareTo(o1);
return num;
}
}
2、泛型类,什么时候使用,当类中要操作的引用数据类型不确定的时候。基本数据类型不能使用。
早期定义Object来完成扩展
现在可以定义泛型类
class Worker
{
}
class Student
{
}
//这就是泛型类
class GenicClass<QQ>
{
private QQ q ;
public setGen(QQ q)
{
this.q = q;
}
public getGen()
{
return q;
}
}
//早期用Object
class GenicClass
{
private Object obj ;
public setGen( Object obj )
{
this.obj = obj;
}
public getGen()
{
return obj;
}
}
class GenicDemo
{
public static void main(String[] args)
{
//泛型类时
GenicClass<Student> gc = new GenicClass<Student>();
gc.setGen(new Student());
Student s= gc.getGen();//不需要类型转换
Worker w = gc.getGen();//编译报错,将类型转换问题出现在编译时期
//没泛型,用Object时
GenicClass gc = new GenicClass();
gc.setGen(new Student());
Student s = (Student)gc.getGen();//必须类型转换,否则编译报错
Worker w = (Worker)gc.getGen();//编译不报错,运行报错
}
}
3、泛型方法
泛型类定义的泛型,在整个类中有效,如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有操作的类型就已经固定了。
//泛型类
class Demo<T>
{
public void show(T t)
{
System.out.println(t);
}
public void print(T t)
{
System.out.println(t);
}
}
class GenDemo
{
public static void main(String[] args)
{
Demo<String> d = new Demo<String>();
d.show("new String");
d.print("new String")
}
}
为了让不同方法可以操作不同类型,而且类型还不确定,那么可以将泛型定义在方法上。
//泛型方法,方法上定义的类型只在方法内有效
class Demo
{
public <T> void show(T t)
{
System.out.println(t);
}
public <Q>void print(Q q)
{
System.out.println(t);
}
}
class GenDemo
{
public static void main(String[] args)
{
Demo d = new Demo();
d.show("new String");
d.print(new Integer(4));
}
}
//泛型类中也可以定义泛型方法
class Demo<R>
{
public void Clss(R r)
{
System.out.println(t);
}
public <T> void show(T t)
{
System.out.println(t);
}
public <Q>void print(Q q)
{
System.out.println(t);
}
public static <W> void method(W t)
{
System.out.println("method");
}
}
class GenDemo
{
public static void main(String[] args)
{
Demo<String> d = new Demo<String>();
d.Clss("fdfdf");
d.show("new String");//泛型类对象,在调用泛型类中定义的泛型方法时,使用的不是创建泛型类对象时声明的数据类型,而是使用的泛型方法自身声明的数据类型
d.print(new Integer(4));
Demo.method();//静态方法
}
}
注意:静态方法不可以访问类上定义的泛型,如果静态方法操作的引用数据类型不确定,可以将泛型定义在方法上。
//泛型定义在接口上,
interface Inter<T>
{
void show(T t);
}
class InterImp implements Inter<String>//类实现接口,并指明数据类型
{
public void show(String s)
{
System.out.println(s);
}
}
class InterImppp <T> implements Inter<T>//类实现接口,但不指明数据类型
{
public void show(T t)
{
System.out.println(t);
}
}
class InterDemo
{
public static void main(String[] args)
{
InterImp<String> ii = new InterImp<String>();
ii.show("DFDf");
InterImppp< String > iip = new InterImppp< String >();
iip.show("FdFG");
}
}
4、泛型高级应用
class GenericDemo
{
public static void main(String[] args)
{
ArrayList<String> al = new ArrayList<String>();
al.add("java_1");
al.add("java_2");
al.add("java_3");
al.add("java_4");
ArrayList<Integer> all = new ArrayList<Integer>();
all.add(5);
all.add(6);
all.add(2);
all.add(9");
printCloo(al);
printCloo(all);
}
//没有泛型时,即1.4以前没有泛型时 ,如下写法,虽然可以但不严谨
public static void printCloo(ArrayList al)
{
Iterator it = al.iterator();
while(it.hasNext());
System.out.println(it.next());
}
//有泛型时,可以用<?>代替泛型,表示类型不确定.<?>是占位符
public static void printCloo(ArrayList<?> al)
{
Iterator<?> it = al.iterator();
while(it.hasNext());
{
System.out.println(it.next());
System.out.println(it.next().length());//这里不可以,因为类型不明确,不确定是否有length()方法,泛型不能使用类型的特有方法。但是一些所有共用的方法可以用,例如toString()。
System.out.println(it.next().toString())
}
}
//有泛型时,可以用<T>,但静态时T需定义
public static <T>void printCloo(ArrayList<T> al)
{
Iterator<T> it = al.iterator();
while(it.hasNext());
{
T t = it.next();//这里可以对T进行一些操作,但是<?>不能。
System.out.println(it.next());
}
}
}
//<?>通配符,也可以理解为占位符
泛型的限定
<? extends E>表示既可以是传E 也可以传E的子类。上限。上边限定了
<? super E>表示可以接收E也可以接收E的父类。下限,下边限定了
示例:上限<? extends E>
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 GenericDemo
{
public static void main(String[] args)
{
ArrayList<Person> al = new ArrayList<Person>();
al.add(new Person("java_1"));
al.add(new Person("java_21"));
al.add(new Person("java_31"));
al.add(new Person("java_41"));
ArrayList<Student> all = new ArrayList<Student>();
all.add(new Student("ssss01"));
all.add(new Student("ssss02"));
all.add(new Student("ssss03"));
all.add(new Student("ssss04"));
all.add(new Student("ssss05"));
printCloo(al);
printCloo(all);
}
public static void printCloo(ArrayList<? extends Person> al)
{
Iterator<? extends Person> it = al.iterator();
while(it.hasNext());
{
System.out.println(it.next());
}
}
}
示例:下限<? super E>
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 Worker extends Person
{
Worker(String name)
{
super(name);
}
}
class GenericDemo
{
public static void main(String[] args)
{
TreeSet<Student> al = new TreeSet<Student>(new Comp());
al.add(new Student ("java_1"));
al.add(new Student ("java_21"));
al.add(new Student ("java_31"));
al.add(new Student ("java_41"));
TreeSet <Worker> all = new TreeSet <Worker>(new Comp());
all.add(new Worker ("ssss01"));
all.add(new Worker ("ssss02"));
all.add(new Worker ("ssss03"));
all.add(new Worker ("ssss04"));
all.add(new Worker ("ssss05"));
printCloo(al);
printCloo(all);
}
public static void printCloo(TreeSet<Person> al)//指定父类比较器
{
Iterator<Person> it = al.iterator();
while(it.hasNext());
{
System.out.println(it.next());
}
}
}
class Comp implements Comparator<Person >//指定父类比较器,因此其子类都可以使
//用,但是在该方法中只能使用父类的方
//法,而不能使用子类特有的方法。
{
public int compare(Person p1,Person p2)
{
int num = p1.getName().compareTo(p2.getName());
return num;
}
}
相关文章推荐
- 黑马程序员----Java集合框架学习笔记2 Map-工具类-泛型
- 黑马程序员——JAVA笔记——集合框架4——泛型
- 黑马程序员_javaAPI集合框架(泛型)
- java笔记-集合框架-泛型、Map集合
- 黑马程序员——Java基础---泛型、集合框架工具类:collections和Arrays
- 黑马程序员——JAVA基础拾遗之泛型和集合框架(二)
- 黑马程序员_JAVA笔记14——集合框架(List、HashSet、TreeSet)
- 黑马程序员----Java集合框架学习笔记1-List 与Set
- 黑马程序员——java学习笔记--集合框架
- 黑马程序员——Java语言基础——06.集合框架(2)泛型和Map集合
- 【Java学习笔记】14.集合框架和泛型
- java 集合框架 泛型--15
- 黑马程序员——java基础-泛型和集合框架工具类
- 黑马程序员——Java基础---泛型、集合框架工具类:collections和Arrays
- 黑马程序员——JAVA笔记——集合框架3——map
- 【黑马程序员】集合框架(上)——Java复习笔记
- 黑马程序员--Java基础学习笔记【集合-List、泛型】
- 黑马程序员—Java学习笔记之集合框架(三)以及1.5新特性
- 黑马程序员 java基础 集合框架之泛型
- 黑马程序员——Java要点笔记——集合框架(Set)