8.2旧集合类Vector

8.2集合
写程序时,并不知道固定使用多少个对象,用更复杂的方式来保存对象,java提供了四种类型的“集合类”vector、bitset、statck以及hashtable。
stack(先入先出),hashtable是关联数组,运行将任何对象关联起来,除此之外,集合类还能自动改变自身大小。

8.2.1缺点:类型未知
因为程序员不知道用户会把什么类型放置集合里,所以丢失了类型信息,但若指定了类型信息,又会妨碍它“常规用途”的特性。集合实际容纳的是类型为Object对象的一些对象的句柄,这种类型能表示java中的所有对象,因为它是所有类的根。当然不包括基本类型,因为他们不是从“任何东西”继承来的。
缺点:将一根对象句柄放入集合时,类型信息会被抛弃,所以任何类型的对象都可以放入集合,即便特别指定它只能容纳特定类型的对象。
由于类型信息不复存在,集合能肯定的唯一事情就是自己容纳的是一个对象的句柄,正式使用它之前,必须对他进行造型,使其具有正确的类型。

package cn.wangs.c08.$8_2_1;

//:WorksAnyway.java

// In special cases, things just seem
// to work correctly.
import java.util.*;

class Mouse {
private int mouseNumber;

Mouse(int i) {
    mouseNumber = i;
}

// Magic method:
public String toString() {
    return "This is Mouse #" + mouseNumber;
}

void print(String msg) {
    if (msg != null)
        System.out.println(msg);
    System.out.println("Mouse number " + mouseNumber);
}

}

class MouseTrap {
static void caughtYa(Object m) {
Mouse mouse = (Mouse) m; // Cast from Object
mouse.print(“Caught one!”);
}
}

public class WorksAnyway {
public static void main(String[] args) {
Vector mice = new Vector();
for (int i = 0; i < 3; i++)
mice.addElement(new Mouse(i));
for (int i = 0; i < mice.size(); i++) {
// No cast necessary, automatic call
// to Object.toString():
System.out.println(“Free mouse: ” + mice.elementAt(i));
MouseTrap.caughtYa(mice.elementAt(i));
}
}
}
Vector的使用简单,创建一个,再addElement()置入对象,以后用elementAt()取对象,Vector有一个size(),可知添加了多少个元素。
试图将Dog对象造型为Cat,就会出现异常。Exception in thread “main” java.lang.ClassCastException: cn.wangs.c08.8_2_1.Dog cannot be cast to cn.wangs.c08.8_2_1.Cat
at cn.wangs.c08.$8_2_1.CatAndDog.main(CatAndDog.java:12)
Cat和Dog对象倘若不指明从什么类继承,默认从Object类继承,所以使用addElement()添加元素的时候,既可以是Dog也可以是Cat。elementAt()在获取对象的时候,实际上获取的是指向Object对象的句柄,必须将对象造型为Cat,接着要将整个表达式封闭起来,在调用Cat对象的print()的时候,要将Object对象进行强制造型,否则会有编译(语法)错误。在运行期间,如果试图将Dog对象造型为Cat对象就会发生异常。
1.隐藏的错误有时会显示不出
为了让自己类的对象能显示隐藏的错误,要做的全部事情就是覆盖toString():
可在 Mouse 里看到对 toString()的重定义代码。在 main()的第二个 for 循环中,可发现下述语句:
System.out.println(“Free mouse: ” +
mice.elementAt(i));
在“ +”后,编译器预期看到的是一个 String 对象。 elementAt()生成了一个 Object,所以为获得希望的
String,编译器会默认调用 toString()。但不幸的是,只有针对 String 才能得到象这样的结果;其他任何
类型都不会进行这样的转换。
隐藏造型的第二种方法已在 Mousetrap 里得到了应用。 caughtYa()方法接收的不是一个 Mouse,而是一个
Object。随后再将其造型为一个 Mouse。当然,这样做是非常冒失的,因为通过接收一个 Object,任何东西
都可以传递给方法。然而,假若造型不正确—— 如果我们传递了错误的类型—— 就会在运行期间得到一个违
例错误。这当然没有在编译期进行检查好,但仍然能防止问题的发生。注意在使用这个方法时毋需进行造
型:
MouseTrap.caughtYa(mice.elementAt(i));

2.生成能自动识别类型的Vector
一个更“健壮”的方案是用Vector创建一个新类,使其只接受我们指定的类型,也只生成我们希望的类型。
package cn.wangs.c08.$8_2_1;

import java.util.Vector;

public class GopherVector {

private Vector v = new Vector();

public void addElement(Gopher m) {
    v.addElement(m);
}

public Gopher elementAt(int index) {
    return (Gopher) v.elementAt(index);
}

public int size() {
    return v.size();
}

public static void main(String[] args) {
    GopherVector gophers = new GopherVector();
    for (int i = 0; i < 3; i++)
        gophers.addElement(new Gopher(i));
    for (int i = 0; i < gophers.size(); i++)
        GopherTrap.caughtYa(gophers.elementAt(i));
}

}

class Gopher {
private int gopherNumber;

Gopher(int i) {
    gopherNumber = i;
}

void print(String msg) {
    if (msg != null)
        System.out.println(msg);
    System.out.println("Gopher number " + gopherNumber);
}

}

class GopherTrap {
static void caughtYa(Gopher g) {
g.print(“Caught one!”);
}
}


public void addElement(Gopher m) {
v.addElement(m);
}

public Gopher elementAt(int index) {
    return (Gopher) v.elementAt(index);
}

GopherVector gophers = new GopherVector();
    for (int i = 0; i < 3; i++)
        gophers.addElement(new Gopher(i));
    for (int i = 0; i < gophers.size(); i++)
        GopherTrap.caughtYa(gophers.elementAt(i));
addElement(Gopher)指定只能是Gopher类型的对象,在置入元素的时候就控制住了,所以不用担心类型转换异常的出现了

3.参数化类型
我们许多时候要在其他类型的基础上创建新的类型,此时,在编译期间拥有特定的类型是很有帮助的,这就是“参数化类型”的概念。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值