分类: Java
2009-11-27 16:01:44
本来jdk5之前有java.util.List这个Interface
是这么用的:
List myIntList = new LinkedList(); // LinkedList是实现了List Interface的类
myIntList.add(new Integer(0));
Integer x = (Integer)myIntList.iterator().next();
这里myIntList其实可以myIntList.add(new Object());因为声明语句就没有写出该List到底支持什么。
所以myIntList.iterator().next()返回的只能是Object,它并不知道这里面装的到底是什么具体的类。
因为这个List里既可能有Integer对象,也可能有Double对象~
为了不要(Integer)这个强制转换,我们有了这个:
List
这个时候,Integer x = (Integer)myIntList.iterator().next();就可以去掉强制转换写成
Integer x = myIntList.iterator.next();
因为编译器确实知道了myIntList里放的就是Integer,不会是其他。
这个地方要注意
List
这句话的真正含义
右边是创建一个LinkedList
理解下面两个例子就知道了:
List myIntList = new LinkedList
List
List
事情到这里,看似所有问题都解决了,但是不尽然。慢慢道来:
class Shape {
public void say();
};
class Circle extends {
public void say() {
System.out.println("i am a circle");
}
};
通过上面,我们可以
Shape shape = new Circle();
shape.say(); // i am a circle.
这里表明,父类可以代表子类。
但是
List
如果有个函数:
public void sayAll(List
for(Shape s : list) {
s.say();
}
}
那么这个函数不能被这样调用:
List
sayAll(circleList);
只能被这样调用:
List
sayAll(shapeList);
##这里详细解释为什么List
看下面代码就知道:
List
List
shapeList.add(new Shape());
circleList.iterator().next(); //出错。
那么怎么解决这个问题?可以这样解决:
public void sayAll(List> list) {
for(Object s : list) {
}
}
具体我们刚才讨论的Shape和Circle的问题可以这样写:
public void sayAll(List extends Shape> list) {
for(Shape s : list) {
s.say();
}
}
其中public void sayAll(List> list) 就是public void sayAll(List extends Object> list) 的意思
这个例子说明,List>才是List
也说明List extends Shape>是List
我们再来看一个例子来加深印象,结束这个话题。然后讨论新话题。
class Person {}
class Student extends Person{}
public class Census {
public static void addRegistry(Map
};
Map
Census.add(allDrivers);
我们下一个话题,先由这个引起:
我们说过,如果
List
那么会出现一个矛盾:
List
List
shapeList.add(new Shape());
circleList.iterator().next(); //出错。
那么List>确实是List
List
List> list= circleList; //正确
list.add(new Shape()); //错误
为什么list不能加新元素?
因为list里的元素类型已经定义好了,是?,不是任何类型,所以不能加入任何类型的元素。
所以如下方法是不能使用的:
static void fromArrayToCollection(Object[] a, Collection> c) {
for (Object o : a) {
c.add(o); // compile time error 因为c不能加入元素
}
}
但是我们想要在List>里加入元素如何弄呢?一个例子概括如下:
static
for (T o : a) {
c.add(o); // correct
}
}
那么这样,c这个Collection
Object[] oa = new Object[100];
Collection
fromArrayToCollection(oa, co);// T inferred to be Object
String[] sa = new String[100];
Collection
fromArrayToCollection(sa, cs);// T inferred to be String
fromArrayToCollection(sa, co);// T inferred to be Object
Integer[] ia = new Integer[100];
Float[] fa = new Float[100];
Number[] na = new Number[100];
Collection
fromArrayToCollection(ia, cn);// T inferred to be Number
fromArrayToCollection(fa, cn);// T inferred to be Number
fromArrayToCollection(na, cn);// T inferred to be Number
fromArrayToCollection(na, co);// T inferred to be Object
fromArrayToCollection(na, cs);// compile-time error
到现在为止,上面一共讲了两个jdk1.5中新的事物
List extends Parent> list = new LinkedList
static
那么看下面两个例子,他们做的事情都是一样的,但是分别用了这两个方法:
interface Collection
public boolean containsAll(Collection> c);
public boolean addAll(Collection extends E) c);
}
interface Collection
public
public
}
他们都做两件事:判断任意类的容器是不是在本身这容器里。加入E子类的容器到本身的容器里。
也可以同时都用上两个新东西:
class Collection {
public static
}
或者写成
class Collection {
public static src){}
}
作为总结这两个新的java特性,举出一个复杂例子:
static List> history = new ArrayList
>();
public void drawAll(List extends Shape> shapes) {
history.addLast(shapes);
for(Shape s : shape) {
s.draw(this);
}
}