Java--集合类之Vector、BitSet、Stack、Hashtable

集合类的优点

任何集合类都可以动态地改变自身的大小。

集合类的缺点

类型未知。将对象置入集合时会丢失对象的类型信息。因为为了成为“常规”工具,对象实际容纳的是“Object"句柄。应该知道”Object"包括所有对象,因为所有类都是从Object类继承而来。但不包括基本数据类型。

由于类型丢失问题,从集合内取得一个对象,在正式使用它之前一定要进行造型(具体说来是下溯造型)。

类型丢失意味着我们可以将任何类型的对象放入一个集合中,但Java为了防止滥用集合中的对象,进行了“违例”控制,例如下述代码:

class Cat{    //猫类
    private int num;
    public cat(int i){ num = i;}
}
class Dog{    //狗类
    private int num;
    public Dog(int i){ num = i;}
}
public class CatAndDog{    //猫狗类
    public static void main(String[] args){
        Vector cats = new Vector();    //创建猫类矢量
        for(int i = 0;i < 5; i++)
            cats.addElement(new Cat(i));
        cats.addElement(new Dog(5));    //狗类也可以存入,不会报错
        for(int j = 0;j < 6; j++)
            (Cat)cats.elementAt(i);    //运行期进行下溯造型时出现违例
    }
}

记住String类例外,因为如果目标类型不是String类型,编译器会自动调用对象的toString()方法。

上面的代码是在运行期检查类型问题,当然,可以实现编译时的类型检测,这需要调整代码结构:

public class CatAndDog{
    Vector v = new Vector(();    //利用组合
    public void addElement(Cat cat){    //使得只能添加Cat类
        v.addElement(cat);
    }
    public Cat elementAt(int index){
        return (Cat)v.elementAt(index);
    }
    //...
}

上述代码利用组合(继承会有点麻烦),将矢量操作放进新类方法中,使用方法参数限制操作类型。这样做显得有点繁琐但可以在编译期发现问题。

枚举器(Enumeration)

枚举器属于反复器(Iterator)的一种简单实现(Java1.2版本实现了反复器)。它可以是一个对象,作用是遍历一系列对象,并选择 那个序列中的每个对象,同时不让客户程序员知道或关注那个序列的基础结构。此外,我们通常认为反复器 是一种“轻量级”对象;也就是说,创建它只需付出极少的代价。

Java 的Enumeration工作原理:

  • 用一个名为 elements()的方法要求集合为我们提供一个 Enumeration。我们首次调用它的 nextElement() 时,这个Enumeration 会返回序列中的第一个元素。
  • 用nextElement()获得下一个对象。
  • 用hasMoreElements()检查序列中是否还有更多的对象。
class PrintData {
    static void print(Enumeration e) {    //接收一个枚举器
        while(e.hasMoreElements())
            System.out.println( e.nextElement().toString());    //打印枚举器的内容
    }
}
class Enumerators2 {
    public static void main(String[] args) {
        Vector v = new Vector();    //创建矢量
        for(int i = 0; i < 5; i++)
            v.addElement(new Mouse(i));
        Hashtable h = new Hashtable();    //创建散列表
        for(int i = 0; i < 5; i++)
            h.put(new Integer(i), new Hamster(i));
        System.out.println("Vector");
        PrintData.print(v.elements());    //打印矢量
        System.out.println("Hashtable");
        PrintData.print(h.elements());    //打印散列表
 }
}

仔细分析上述代码:集合类可以通过elements()方法生成一个枚举对象;枚举器不关心集合的特定类型,它只是使用hasMoreElements()和nextElement()进行访问遍历。

Vector:

Vector的用法很简单,这已在前面的例子中得到了证明。尽管我们大多数时候只需用addElement()插入对 象,用 elementAt()一次提取一个对象,并用elements()获得对序列的一个“枚举”,但它还有一些其他方法很有用处,可以查看相关文档。

BitSet:

BitSet实际是由“二进制位”构成的一个 Vector。如果希望高效率地保存大量“开-关”信息,就应使用 BitSet。它只有从尺寸的角度看才有意义;如果希望的高效率的访问,那么它的速度会比使用一些固有类型 的数组慢一些。 此外,BitSet的最小长度是一个长整数(Long)的长度:64 位。这意味着假如我们准备保存比这更小的数据,如 8 位数据,那么 BitSet就显得浪费了。所以最好创建自己的类,用它容纳自己的标志位。 

Stack:

Stack 有时也可以称为“后入先出”(LIFO)集合。换言之,我们在堆栈里最后“压入”的东西将是以后第 一个“弹出”的。和其他所有 Java 集合一样,我们压入和弹出的都是“对象”,所以必须对自己弹出的东西 进行“造型”。

Stack对象使用push()压栈,使用pop()出栈。要声明的一点是, Vector操作亦可针对 Stack 对象进行。这可能是由继承的特质决定的——Stack“属于”一种 Vector。因此,能对Vector 进行的操作亦可针对Stack 进行,例如 elementAt()方法。

 Hashtable:

Vector允许我们用一个数字从一系列对象中作出选择,所以它实际是将数字同对象关联起来了。但假如我们 想根据其他标准选择一系列对象呢? 这种“从一系列对象中选择”的概念亦可叫作一个“映射”、“字典”或者“关联数组”。从概念上讲,它 看起来象一个Vector,但却不是通过数字来查找对象,而是用另一个对象来查找它们! 在Java 中,这个概念具体反映到抽象类 Dictionary身上。该类的接口是非常直观的。

  • size()告诉我们其中包含了多少元素;
  • isEmpty()判断是否包含了元素(是则为 true);
  • put(Object key, Object value)添加一个值,并将其同一个键关联起来(想用于搜索它的东西);
  • get(Object key)获得与某个键对应的值;
  • 而remove(Object Key)用于从列表中删除“键-值”对;
  • 还可以使用枚举技术:keys()产生对键的一个枚举(Enumeration);而 elements()产生对所有值的一个枚举。
public class SpringDetector2 {
    public static void main(String[] args) {
        Hashtable ht = new Hashtable();
        for(int i = 0; i < 10; i++)
            ht.put(new Groundhog2(i),new Prediction());
        Groundhog2 gh = new Groundhog2(3);
        if(ht.containsKey(gh))
            System.out.println((Prediction)ht.get(gh));
    }
} 

下一篇:Java--集合类之Collection与Map

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏工科狗和生物喵

【计算机本科补全计划】《C++ Primer》:数组全解!!

正文之前 其实我的《C++ Primer》 已经看到第五章了,但是因为码字比较费时间,所以暂时没有迅速更新实在是对不住,但是没办法, 总不能一天拿出五六个小时来...

35510
来自专栏码云1024

JAVA 第二天 基本数据类型

2699
来自专栏MyBlog

Effective.Java 读书笔记(11)关于clone方法

说到clone方法,我们来提一提Cloneable这个接口,这个接口是用来作为一种标记某对象允许被clone的一种混合接口,可是不幸运的是,这个接口并没能起到该...

992
来自专栏python读书笔记

python 数据分析基础 day9-datetime类型常用对象以及函数日期类型的运算

今天是读《python数据分析基础》的第9天,今天将通过python的date模块来总结日期类型。 常用对象以及函数 对象 可通过date模块创建创建以下对象:...

3016
来自专栏智能算法

Python学习(七)---- 面向对象学习(类)

原文地址: https://blog.csdn.net/fgf00/article/details/52449707 编辑:智能算法,欢迎关注!

1062
来自专栏Java帮帮-微信公众号-技术文章全总结

第五天 方法【悟空教程】

2007
来自专栏苦逼的码农

Unicode与UTF-8的区别

要弄清Unicode与UTF-8的关系,我们还得从他们的来源说起,下来我们从刚开始的编码说起,直到Unicode的出现,我们就会感觉到他们之间的关系

7352
来自专栏CodingBlock

Java数据结构和算法总结-字符串相关高频面试题算法

前言:周末闲来无事,在七月在线上看了看字符串相关算法的讲解视频,收货颇丰,跟着视频讲解简单做了一下笔记,方便以后翻阅复习同时也很乐意分享给大家。什么字符串在算...

3490
来自专栏有趣的django

8.python面向对象编程

基本概念 Class 类 一个类即是对一类拥有相同属性的对象的抽象、蓝图、原型。在类中定义了这些对象的都具备的属性(variables(data))、共同的方法...

3237
来自专栏程序员叨叨叨

8.1 函数第 8 章 函数与程序设计

通过第 5 章到第 7 章的阅读,我们已经知道了怎么声明变量(第 5 章),怎么写表达式和语句(第 6 章),怎么将输入 \ 输出参数绑定到语义词(第 7 章)...

932

扫码关注云+社区