您的位置:首页 > 职场人生

黑马程序员_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;

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: