第八章.对象的容纳 -----Thinking in java 更新中……

来源:互联网 发布:mysql教程视频下载 编辑:程序博客网 时间:2024/05/24 04:04

第八章.对象的容纳

更新中……

未完……

待续……

 

目录

ü 数组

ü 集合

ü Vector

ü 枚举器(反复器)--Enumeration 接口

ü Hashtable

 

Ø 数组

注:只是简单的阐述数组与集合的关系中数组的小知识点。重点在集合处,如果想了解Java中数组的定义,初始化等知识请看前几章

l  有两方面的问题将数组与其他集合类型区分开来:效率和类型。

l  数组实际代表一个简单的线性序列,它使得元素的访问速度非常快,但我们却要为这种速度付出代价:创建一个数组对象时,它的大小是固定的,而且不可在那个数组对象的“存在时间”内发生改变。

l  可创建特定大小的一个数组,然后假如用光了存储空间,就再创建一个新数组,将所有句柄从旧数组移到新数组。

 

Java存在边界检查机制

l  C++的矢量类知道自己容纳的是什么类型的对象,但同Java 的数组相比,它却有一个明显的缺点:C++矢量类的operator[]不能进行范围检查,所以很容易超出边界(然而,它可以查询 vector 有多大,而且at()方法确实能进行范围检查)。

在Java 中,无论使用的是数组还是集合,都会进行范围检查——若超过边界,就会获得一个RuntimeException(运行期违例)错误。但是由于对数组和集合都要进行范围检查,所以对性能有一定的影响。

Ø  数组和对象的初始化:

实例:

//:ArraySize.java

//Initialization & re-assignment of arrays

packagec08;

 

classWeeble {} // A small mythical creature

 

publicclass ArraySize

 {

public static void main(String[] args) {

// Arrays of objects:

Weeble[]a; // Null handle

Weeble[]b = new Weeble[5]; // Null handles

Weeble[]c = new Weeble[4];

for(int i= 0; i < c.length; i++)

c[i] =new Weeble();

//数组c显示出我们首先创建一个数组对象,再将Weeble对象赋给那个数组的所有空位

Weeble[]d = {new Weeble(), new Weeble(), new Weeble()};

//数组d揭示出“集合初始化”语法,从而创建数组对象(用 new命令明确进行,类似于数组c),然后用Weeble对象进行初始化,全部工作在一条语句里完成。

 

//Compile error: variable a not initialized:

//!System.out.println("a.length="+ a.length);

 

System.out.println("b.length = " +b.length);

 

// Thehandles inside the array are

//automatically initialized to null:

for(int i = 0; i < b.length; i++)

System.out.println("b[" + i +"]=" + b[i]);

 

System.out.println("c.length = " + c.length);

System.out.println("d.length = " +d.length);

a = d;

System.out.println("a.length = " +a.length);

 

//Java 1.1 initialization syntax:

a = new Weeble[] {new Weeble(), new Weeble()};

System.out.println("a.length = " +a.length);

 

//Arrays of primitives:

int[] e;// Null handle

int[] f =new int[5];

int[] g =new int[4];

for(int i= 0; i < g.length; i++)

g[i] =i*i;

int[] h ={ 11, 47, 93 };

 

//Compile error: variable e not initialized:

//!System.out.println("e.length="+ e.length);

 

System.out.println("f.length = " +f.length);

 

// Theprimitives inside the array are

//automatically initialized to zero:

for(int i = 0; i < f.length; i++)

System.out.println("f[" + i +"]=" + f[i]);

System.out.println("g.length = " +g.length);

System.out.println("h.length = " +h.length);

 

e = h;

System.out.println("e.length = " +e.length);

 

//Java 1.1 initialization syntax:

e = new int[] { 1, 2 };

System.out.println("e.length = " +e.length);

}

}///:~

 

Here’sthe output from the program:

b.length= 5

b[0]=null

b[1]=null

b[2]=null

b[3]=null

b[4]=null

c.length= 4

d.length= 3

a.length= 3

a.length= 2

f.length= 5

f[0]=0

f[1]=0

f[2]=0

f[3]=0

f[4]=0

g.length= 4

h.length= 3

e.length= 3

e.length= 2

 

Ø  数组的返回

假定我们现在想写一个方法,同时不希望它仅仅返回一样东西,而是想返回一系列东西。此时,象C 和C++这样的语言会使问题复杂化,因为我们不能返回一个数组,只能返回指向数组的一个指针。这样就非常麻烦,因为很难控制数组的“存在时间”,它很容易造成内存“漏洞”的出现。

Java 采用的是类似的方法,但我们能返回一个数组。当然,此时返回的实际仍是指向数组的指针。但在Java里,我们永远不必担心那个数组的是否可用——只要需要,它就会自动存在。而且垃圾收集器会在我们完成后自动将其清除。

实例:

 

public class IceCream {

    static String[]flav =

        {

            "Chocolate", "Strawberry",

            "Vanilla Fudge Swirl","Mint Chip",

            "Mocha Almond Fudge","Rum Raisin",

            "Praline Cream", "Mud Pie"

        };

   

            static String[] flavorSet(intn)

            {

             // Force itto be positive & within bounds:

             n = Math.abs(n) % (flav.length + 1);

             

             String[] results =new String[n];

             int[]picks = newint[n];

             

             for(inti = 0; i < picks.length; i++)

                picks[i] = -1;

             

            for(inti = 0; i < picks.length; i++)

            {

              retry:

             while(true)

             {

                 while(true)

                 {

                     intt =(int)(Math.random() *flav.length);

                     for(intj = 0; j < i; j++)

                     if(picks[j] ==t) continue retry;

                     picks[i] =t;

                     results[i] =flav[t];

                      break;

                }

            }

            returnresults;

            }

            public static void main(String[] args)

            {

             for(inti = 0; i < 20;i++)

             {

               System.out.println("flavorSet(" +i + ") = ");

           

               String[] fl = flavorSet(flav.length);

             

               for(intj = 0; j < fl.length; j++)

               System.out.println("\t" +fl[j]);

            }

            }

}

输出:

flavorSet(0)=

    Mud Pie

    Mint Chip

    Chocolate

    Praline Cream

    Strawberry

    Mocha Almond Fudge

    Rum Raisin

    Vanilla Fudge Swirl

………………………………………………………………

flavorSet(19)=

    Mocha Almond Fudge

    Mud Pie

    Chocolate

    Mint Chip

    Vanilla Fudge Swirl

    Rum Raisin

    Praline Cream

    Strawberry

Ø 集合

Java 提供了四种类型的“集合类”:Vector(矢量)、BitSet(位集)、Stack(堆栈)以及Hashtable(散列表)。

所有Java 集合类都能自动改变自身的大小。所以,我们在编程时可使用数量众多的对象,同时不必担心会将集合弄得有多大。

缺点:类型未知

使用Java 集合的“缺点”是在将对象置入一个集合时丢失了类型信息集合实际容纳的是类型为Object的一些对象的句柄。这种类型当然代表Java 中的所有对象,因为它是所有类的根。当然,也要注意这并不包括基本数据类型,因为它们并不是从“任何东西”继承来的。

值得欣慰的是,Java不允许人们滥用置入集合的对象。假如将一条狗扔进一个猫的集合,那么仍会将集合内的所有东西都看作猫,所以在使用那条狗时会得到一个“违例”错误。在同样的意义上,假若试图将一条狗的句柄“造型”到一只猫,那么运行期间仍会得到一个“违例”错误。

下面是个例子:

//: CatsAndDogs.java

// Simple collection example (Vector)

 

import java.util.*;

class Cat

{

private int catNumber;

Cat(int i)

{

catNumber = i;

}

void print()

 {

System.out.println("Cat #" +catNumber);

}

}

 

class Dog

 {

private int dogNumber;

Dog(int i)

{

dogNumber = i;

}

void print()

{

System.out.println("Dog #" +dogNumber);

}

}

 

public class CatsAndDogs

{

public static void main(String[] args)

{

Vectorcats = new Vector();

for(int i = 0; i < 7; i++)

cats.addElement(new Cat(i));

 

// Not a problem to add a dog to cats:

cats.addElement(new Dog(7));

for(int i = 0; i < cats.size(); i++)

((Cat)cats.elementAt(i)).print();

// Dog is detected only at run-time

}

} ///:

可以看出,Vector的使用是非常简单的:先创建一个,再addElement()置入对象,以后用 elementAt()取得那些对象(注意Vector有一个 size()方法,可使我们知道已添加了多少个元素,以便防止误超边界,造成违例错误)。

Cat和 Dog类都非常浅显——除了都是“对象”之外,(为什么可以放)它们并无特别之处(倘若不明确指出从什么类继承,就默认为从 Object继承。所以我们不仅能用 Vector方法将 Cat对象置入这个集合,也能添加 Dog对象,同时不会在编译期和运行期得到任何出错提示。Vector方法elementAt()获取原本认为是Cat的对象时,实际获得的是指向一个Object的句柄,必须将那个对象造型为Cat随后,需要将整个表达式用括号封闭起来,在为Cat调用print()方法之前进行强制造型;否则就会出现一个语法错误。在运行期间,如果试图将Dog对象造型为 Cat,就会得到一个违例。

 

²Vector函数使用详解

参考:http://www.cnblogs.com/zhaoyan001/p/6077492.html

 

向量类提供了三种构造方法:
public vector()
public vector(int initialcapacity,int capacityIncrement)
public vector(int initialcapacity)

使用第一种方法系统会自动对向量进行管理,若使用后两种方法。则系统将根据参数,initialcapacity设定向量对象的容量(即向量对象可存储数据的大小),当真正存放的数据个数超过容量时。系统会扩充向量对象存储容量。

参数capacityincrement给定了每次扩充的扩充值。当capacityincrement为0的时候,则没次扩充一倍,利用这个功能可以优化存储。在Vector类中提供了各种方法方便用户的使用:

插入功能:
(1)public final synchronized void adddElement(Object obj)
obj插入向量的尾部。obj可以是任何类型的对象。对同一个向量对象,亦可以在其中插入不同类的对象。但插入的应是对象而不是数值,所以插入数值时要注意将数组转换成相应的对象。
例如:要插入整数1时,不要直接调用v1.addElement(1),正确的方法为:
Vector v1 = new Vector();
Integer integer1 = new Integer(1);
v1.addElement(integer1);


(2)public final synchronized void setElementAt(Object obj,int index)
index处的对象设置成obj,原来的对象将被覆盖。
(3)public final synchronized void insertElementAt(Object obj,int index)
index指定的位置插入obj,原来对象以及此后的对象依次往后顺延。

 

删除功能
(1)public final synchronized void removeElement(Object obj)
从向量中删除obj,若有多个存在,则从向量头开始试,删除找到的第一个与obj相同的向量成员。
(2)public final synchronized void removeAllElement();
删除向量所有的对象
(3)public fianl synchronized void removeElementAt(int index)
删除index所指的地方的对象

查询搜索功能:
(1)public final int indexOf(Object obj)
从向量头开始搜索obj,返回所遇到的第一个obj对应的下标,若不存在此obj,返回-1.
(2)public final synchronized int indexOf(Object obj,int index)
从index所表示的下标处开始搜索obj.
(3)public final int lastindexOf(Object obj)
从向量尾部开始逆向搜索obj.
(4)public final synchornized int lastIndex(Object obj,int index)
从index所表示的下标处由尾至头逆向搜索obj.
(5)public final synchornized firstElement()
获取向量对象中的首个obj
(6)public final synchornized Object lastElement()
获取向量对象的最后一个obj

获取向量大小
public final int size();
此方法用于获取向量元素的个数。它们返回值是向量中实际存在的元素个数,而非向量容量。可以调用方法capacity()来获取容量值。

方法:
public final synchronized void setsize(int newsize);
此方法用来定义向量的大小,若向量对象现有成员个数已经超过了newsize的值,则超过部分的多余元素会丢失。

 

例子:VectorApp.Java
import java.util.Vector;
import java.lang.*;
import java.util.Enumeration;
public class VectorApp
{
public static void main(String args[])
{
Vector v1 = new Vector();
Integer integer1= new Integer(1);
//加入为字符串对象
v1.addElement("one");
//加入的为integer的对象
v1.addElement(integer1);
v1.addElement(integer1);
v1.addElement("two");
v1.addElement(new Integer(2));
v1.addElement(integer1);
v1.addElement(integer1);
//转为字符串并打印
System.out.println("The Vector v1 is:\n\t"+v1);
//向指定位置插入新对象
v1.insertElementAt("three",2);
v1.insertElementAt(new Float(3.9),3);
System.out.println("The Vector v1(used method
insertElementAt()is:\n\t)"+v1);
//将指定位置的对象设置为新的对象
//指定位置后的对象依次往后顺延
v1.setElementAt("four",2);
System.out.println("The vector v1 cused methodsetElmentAt()is:\n\t"+v1);
v1.removeElement(integer1);
//从向量对象v1中删除对象integer1
//由于存在多个integer1,所以从头开始。
//找删除找到的第一个integer1.
Enumeration enum = v1.elements();
System.out.println("The vector v1 (used method removeElememt()is");
while(enum.hasMoreElements())
System.out.println(enum.nextElement()+"");
System.out.println();
//使用枚举类(Enumeration)的方法取得向量对象的每个元素。
System.out.println("The position ofObject1(top-to-botton):"+v1.indexOf(integer1));
System.out.println("The position ofObject1(tottom-to-top):"+v1.lastIndexOf(integer1));
//按不同的方向查找对象integer1所处的位置
v1.setSize(4);
System.out.println("The new Vector(resized the vector)is:"+v1);
//重新设置v1的大小,多余的元素被抛弃
}
}

运行结果:
E:\java01>java VectorApp
The vector v1 is:[one,1,1,two,2,1,1]
The vector v1(used method insetElementAt()) is:
[one,1,three,3.9,1,two,2,1,1]
The vector v1(used method setElementAt()) is:
[one,1,four,3.9,1,two,2,1,1]
The vector v1(useed method removeElement()) is:
one four 3.9 1 two 2 1 1
The position of object1(top-to-botton):3
The position of object1(botton-to-top):7
The new Vector(resized the vector) is:
[one,four,3.9,1]



 

特列:

第一种情况是相当特殊的:String 类从编译器获得了额外的帮助,使其能够正常工作。只要编译器期待的是一个String对象,但它没有得到一个,就会自动调用在Object里定义、并且能够由任何Java类覆盖的 toString()方法。这个方法能生成满足要求的String对象,然后在我们需要的时候使用。

import java.util.*;

class Mouse

{

private intmouseNumber;

Mouse(int i)

{

mouseNumber = i;

}

 

public StringtoString()

{

return "Thisis Mouse #" + mouseNumber;

}

void print(String msg)

{

if(msg != null)

System.out.println(msg);

System.out.println("Mousenumber " + mouseNumber);

}

回调

}

 

class MouseTrap

 {

static voidcaughtYa(Object m)

Object接受,然后转换

{

Mouse mouse = (Mouse)m; // Cast from Object

mouse.print("Caught one!");

}

}

 

public class WorksAnyway

{

public static voidmain(String[] args)

 {

Vector mice = newVector();

for(int i = 0; i <3; i++)

mice.addElement(newMouse(i));

for(int i = 0; i< mice.size(); i++)

会调用toString方法

{

// No castnecessary, automatic call

// toObject.toString():

System.out.println("Free mouse: " +mice.elementAt(i));

MouseTrap.caughtYa(mice.elementAt(i));

}

}

} ///:~

输出:

Free mouse: This is Mouse #0

Caught one!

Mouse number 0

Free mouse: This is Mouse #1

Caught one!

Mouse number 1

Free mouse: This is Mouse #2

Caught one!

Mouse number 2

注意:

1.可在Mouse 里看到对toString()的重定义代码。在main()的第二个for 循环中,可发现下述语句:

System.out.println("Free mouse: " + mice.elementAt(i));

在“+”后,编译器预期看到的是一个String 对象。elementAt()生成了个 Object,所以为获得希望的String,编译器会默认调用 toString()。但不幸的是,只有针对String才能得到象这样的结果;其他任何型都不会进行这样的转换。

2. 隐藏造型的第二种方法已在Mousetrap里得到了应用。caughtYa()方法接收的不是一个Mouse,而是一个Object。随后再将其造型为一个 Mouse。当然,这样做是非常冒失的,因为通过接收一个 Object,任何东西都可以传递给方法。然而,假若造型不正确——如果我们传递了错误的类型——就会在运行期间得到一个违例错误。这当然没有在编译期进行检查好,但仍然能防止问题的发生

生成能自动判别类型的 Vector

import java.util.*;

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!");

}

}

 

Class GopherVector

{

privateVector v = new Vector();

publicvoid addElement(Gopher m)

{

v.addElement(m);

}

publicGopher elementAt(int index)

{

return(Gopher)v.elementAt(index);

}

publicint size()

{ returnv.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));

}

} ///:~

 

 

 

 

 

 

 

Ø 枚举器(反复器)

--- Enumeration 接口

 

Java 的Enumeration(枚举,注释②)便是具有这些限制的一个反复器的例子。除下面这些外,不可再用它做其他任何事情:

(1)   public Enumeration elements(); 

从索引 0 开始列举向量中所有元素。该方法返回一个列举(Enumeration )对象

(2)   public Object nextElement(); 

如果 Enumeration 枚举对象还含有元素,该方法返回对象中的下一个元素。如果没有,则抛出 NoSuchElementException 异常。

(3)   booleanhasMoreElements();  

是否还有元素,如果返回 true ,则表示至少含有一个元素

 

使用Enumeration,我们不必关心集合中的元素数量。所有工作均由 hasMoreElements()和nextElement()自动照管了。

java.util.Enumeration 接口中,但只提供了遍历 Vector  Hashtable (及子类Perperties )类型集合元素的功能,不支持元素的移除操作。此外, Iterator 接口添加了一个可选的移除操作,并使用较短的方法名。

注:此接口的功能与Iterator接口的功能是重复的。优先使用Iterator接口

实例:

importjava.util.*;

classHamster

 {

private int hamsterNumber;

Hamster(int i)

 {

hamsterNumber = i;

}

public String toString()

{

return "This is Hamster #" +hamsterNumber;

}

}

 

classPrinter

{

static voidprintAll(Enumeration e)

{

1

while(e.hasMoreElements())

System.out.println(e.nextElement().toString());

}

}

 

publicclass HamsterMaze

{

public static void main(String[] args)

{

Vector v = new Vector();

for(int i = 0; i < 3; i++)

v.addElement(new Hamster(i));

Printer.printAll(v.elements());

}

}///:~

注意其中没有与序列类型有关的信息。我们拥有的全部东西便Enumeration。为了解有关序列的情况,一个Enumeration 便足够了:可取得下一个对象,亦可知道是否已抵达了末尾。取得一系列对象,然后在其中遍历,从而执行一个特定的操作——这是一个颇有价值的编程概念,本书许多地方都会沿用这一思路。这个看似特殊的例子甚至可以更为通用,因为它使用了常规的toString()方法(之所以称为常规,是由于它属于Object类的一部分)。

2

下面是调用打印的另一个方法(尽管在效率上可能会差一些):

System.out.println(""+ e.nextElement());

3

它采用了封装到Java 内部的“自动转换成字串”技术。一旦编译器碰到一个字串,后面跟随一个“+”,就会希望后面又跟随一个字串,并自动调用toString()。在Java 1.1中,第一个字串是不必要的;所有对象都会转换成字串。亦可对此执行一次造型,获得与调用toString()同样的效果:

System.out.println((String)e.nextElement())

 

 

 

ØHashtable

²Dictionary

字典是代表一个键/值存储库。

给定一个键和值,可以在一个Dictionary对象存储的值。一旦该值被存储,可以使用它的键检索。因此,像一个映射,词典可以被认为是作为键/值对的列表。

 

通过字典中定义的抽象方法如下:

1

Enumeration elements( )
返回包含在字典中的值的枚举。

2

Object get(Object key)
返回包含key关联的值的对象。如果关键不在字典中,则返回一个空对象。

3

boolean isEmpty( )
如果字典是空返回true,如果它至少包含一个键返回false。

4

Enumeration keys( )
返回包含在字典中的键的枚举。

5

Object put(Object key, Object value)
插入一个键,并将其值到字典中。返回null,如果按键是不是已经在字典中,返回key相关联的先前值,如果键已经在字典。

6

Object remove(Object key)
删除键,并将其值。返回与key相关联的值。如果关键不在字典中,则返回空。

7

int size( )
返回字典中的条目数。

Dictionary类是过时的,应该用Map接口获得键/值存储功能

 

实例:

importjava.util.*;

//继承后重写了所有的其中的方法。

/这意味着AssocArray 属于Dictionary的一种类型,所以可对其发出与 Dictionary一样的请求。如果想生成自己的 Dictionary,而且就在这里进行,那么要做的全部事情只是填充位于Dictionary内的所有方法(而且必须覆盖所有方法,因为它们——除构建器外——都是抽象的)。

public class AssocArray extends Dictionary

{

private Vectorkeys = new Vector();

private Vectorvalues = new Vector();

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

public boolean isEmpty()

 {

return keys.isEmpty();

}

public Object put(Object key, Object value)

 {

keys.addElement(key);

values.addElement(value);

return key;

}

public Object get(Object key)

{

int index = keys.indexOf(key);

// indexOf() Returns -1 if key not found:

if(index == -1) return null;

return values.elementAt(index);

}

public Object remove(Object key)

{

int index = keys.indexOf(key);

if(index == -1) return null;

keys.removeElementAt(index);

Object returnval = values.elementAt(index);

values.removeElementAt(index);

return returnval;

}

public Enumeration keys()

{

return keys.elements();

}

public Enumeration elements()

{

return values.elements();

}

//Test it:

publicstatic void main(String[] args)

 {

AssocArray aa = newAssocArray();

//把大小写相互关联

for(char c = 'a'; c <= 'z'; c++)

aa.put(String.valueOf(c),String.valueOf(c).toUpperCase());

 

char[] ca = { 'a', 'e', 'i', 'o', 'u' };

for(int i = 0; i < ca.length; i++)

System.out.println("Uppercase: " +

aa.get(String.valueOf(ca[i])));//用小写输出大写

}

}///:~

输出:

Uppercase:A

Uppercase:E

Uppercase:I

Uppercase:O

Uppercase:U

 

²扩展:

Ø  String.valueOf()方法的使用

参考:http://blog.csdn.net/evilcry2012/article/details/71429898?locationNum=13&fps=1

1. 由基本数据型态转换成 String 
String 类别中已经提供了将基本数据型态转换成String 的 static 方法 
也就是 String.valueOf() 这个参数多载的方法 ,有下列几种 
String.valueOf(boolean b) : 将 boolean 变量 b 转换成字符串 
String.valueOf(char c) : 将 char 变量 c 转换成字符串 
String.valueOf(char[] data) : 将 char 数组 data 转换成字符串 
String.valueOf(char[] data, int offset, int count) : 
将 char 数组 data 中 由 data[offset] 开始取 count 个元素 转换成字符串 
String.valueOf(double d) : 将 double 变量 d 转换成字符串 
String.valueOf(float f) : 将 float 变量 f 转换成字符串 
String.valueOf(int i) : 将 int 变量 i 转换成字符串 
String.valueOf(long l) : 将 long 变量 l 转换成字符串 
String.valueOf(Object obj): obj对象转换成字符串,等于 obj.toString() 


用法如: 
int i = 10; 
String str = String.valueOf(i); 
这时候 str 就会是 "10" 


2. String转换成数字的基本数据型态 
比如说 String 转换成 byte 
可以使用 Byte.parseByte(String s) 
这一类的方法如果无法将 s 分析 则会丢出NumberFormatException byte : 
Byte.parseByte(String s) : 将 s 转换成 byte 
Byte.parseByte(String s, int radix) : 以 radix 为基底 将 s 转换为 byte 
比如说Byte.parseByte("11", 16) 会得到 17 
double : 
Double.parseDouble(String s) : 将 s 转换成 double 
float : 
Double.parseFloat(String s) : 将 s 转换成 float 
int : 
Integer.parseInt(String s) : 将 s 转换成 int 

 

 

²  Hashtable

Hashtable是Dictionary(字典)类的子类。在字典类中就把关键字对应到数据值。字典类是一个抽象类。在java.util中还有一个类Properties,它是Hashtable的子类。

Hashtable的函数

java.util.Hashtable提供了种方法让用户使用哈希表,而不需要考虑其哈希表真正如何工作。
  哈希表类中提供了三种构造方法,分别是:
  public Hashtable()
  public Hashtable(intinitialcapacity)
  public Hashtable(intinitialCapacity,float loadFactor)
  参数initialCapacityHashtable的初始容量,它的值应大于0loadFactor又称装载因子,是一个0.00.1之间的float型的浮点数。它是一个百分比,表明了哈希表何时需要扩充,例如,有一哈希表,容量为100,而装载因子为0.9,那么当哈希表90%的容量已被使用时,此哈希表会自动扩充成一个更大的哈希表。如果用户不赋这些参数,系统会自动进行处理,而不需要用户操心。
  Hashtable提供了基本的插入、检索等方法。
  ■插入
  public synchronized voidput(Object key,Object value)
给对象value设定一关键字key,并将其加到Hashtable中。若此关键字已经存在,则将此关键字对应的旧对象更新为新的对象Value。这表明在哈希表中相同的关键字不可能对应不同的对象(从哈希表的基本思想来看,这也是显而易见的)。
  ■检索
  public synchronized Objectget(Object key)
  根据给定关键字key获取相对应的对象。
  public synchronized booleancontainsKey(Object key)
  判断哈希表中是否包含关键字key。
  public synchronized booleancontains(Object value)
  判断value是否是哈希表中的一个元素。
  ■删除
  public synchronized objectremove(object key)
  从哈希表中删除关键字key所对应的对象。
  public synchronized voidclear()
  清除哈希表
  另外,Hashtalbe还提供方法获取相对应的枚举集合:
  public synchronizedEnumeration keys()
  返回关键字对应的枚举对象。
  public synchronizedEnumeration elements()
  返回元素对应的枚举对象。

Hashtable的例子。
  import java.util.Hashtable;
  importjava.util.Enumeration;
  public class HashApp{
   public static voidmain(String args[]){
    Hashtable hash=new Hashtable(2,(float)0.8);
    //创建了一个哈希表的对象hash,初始容量为2,装载因子为0.8

    hash.put("Jiangsu","Nanjing");
    //将字符串对象“Jiangsu”给定一关键字“Nanjing”,并将它加入hash
    hash.put("Beijing","Beijing");
    hash.put("Zhejiang","Hangzhou");

    System.out.println("Thehashtable hash1 is: "+hash);
    System.out.println("Thesize of this hash table is "+hash.size());
    //打印hash的内容和大小

    Enumeration enum1=hash.elements();
System.out.print("Theelement of hash is: ");
while(enum1.hasMoreElements())
System.out.print(enum1.nextElement()+"");
System.out.println();

//注意输出结果
    //依次打印hash中的内容
    if(hash.containsKey("Jiangsu"))
     System.out.println("Thecapatial of Jiangsu is "+hash.get("Jiangsu"));
    hash.remove("Beijing");
    //删除关键字Beijing对应对象
    System.out.println("Thehashtable hash2 is: "+hash);
    System.out.println("Thesize of this hash table is "+hash.size());
   }
  }

  运行结果:
  The hashtable hash1 is:{Beijing=Beijing, Zhejiang=Hangzhou, Jiangsu=Nanjing}
  The size of this hash tableis 3
  The element of hash is: Beijing Hangzhou Nanjing
  The capatial of Jiangsu isNanjing
  The hashtable hash2 is:{Zhejiang=Hangzhou, Jiangsu=Nanjing}
  The size of this hash tableis 2

² VectorHashtable对比

实例:

importjava.util.*;

 

class PrintData

{

    static void print(Enumeration e)

    {

        while(e.hasMoreElements())

            System.out.println(e.nextElement().toString());

    }

}

 

class Hamster

{

    private int hamsterNumber;

    Hamster(inti)

 {

        hamsterNumber = i;

}

publicString toString()

{

return "This is Hamster #" + hamsterNumber;

}

}

 

class Mouse

{

    private int mouseNumber;

    Mouse(inti)

    {

        mouseNumber = i;

    }

//Magic method:

publicString toString()

{

    return "This isMouse #" + mouseNumber;

}

 

}

 

public class Enumerators2

{

    public static void main(String[] args)

    {

        Vector v = new Vector();

        for(inti = 0; i < 5;i++)

        v.addElement(new Mouse(i));

       

        Hashtable h = new Hashtable();

        for(inti = 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());

        }

}

输出:

Vector

Thisis Mouse #0

Thisis Mouse #1

Thisis Mouse #2

Thisis Mouse #3

Thisis Mouse #4

Hashtable

Thisis Hamster #4

Thisis Hamster #3

Thisis Hamster #2

Thisis Hamster #1

Thisis Hamster #0

 

原创粉丝点击