首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

9.5  Hashtable哈希表类和SortedList排序列表类

Hashtable类和SortedList类是两种被称为字典(dictionary)的集合。所谓字典,是指一种具有键值对的集合。

Hashtable类被称为哈希表,很多有关算法和数据结构的书都会讲到这种数据结构。Hashtable类在内部维护着一个内部哈希表,这个内部哈希表为高速检索数据提供了较好的性能。SortedList类是一种可以对“键值对”进行排序的字典集合。

 9.5.1  Hashtable

Hashtable类是一种键值对的集合,在内部,Hashtable维护着一个哈希表。内部哈希表为插入到Hashtable的每个键进行哈希编码,在后续的检索操作中,通过哈希代码,可以遍历所有元素。这种方法为搜寻操作提供了较佳的性能。

在.NET中,键和值可以是任何对象,例如字符串、自定义类等。在后台,当插入键值对到Hashtable中时,Hashtable使用每个键所引用对象的GetHashCode()方法,获取一个哈希编码,存入Hashtable中。

 9.5.2  构造普通哈希表

Hashtable类提供了15个重载的构造函数,本节将列举比较常用的构造函数,并进行举例说明,更多的信息可以查阅MSDN。

4种比较常用的Hashtable构造函数声明如下。

//使用默认的初始容量、加载因子、哈希代码提供程序和比较器来初始化 Hashtable类的实例

public Hashtable();

//使用指定容量、默认加载因子、默认哈希代码提供程序和比较器来初始化Hashtable类的实例

public Hashtable(int capacity);

//使用指定的容量,加载因子来初始化Hashtable类的实例

public Hashtable(int capacity, float loadFactor);

//通过将指定字典中的元素复制到新的 Hashtable 对象中,初始化 Hashtable 类的一个新实例。新 //Hashtable 对象的初始容量等于复制的元素数,并且使用默认的加载因子、哈希代码提供程序和比较器

public Hashtable(IDictionary d);

构造哈希表时,有一些新的概念需要先理解。

—     在哈希表中,键被转换为哈希代码,而值存储在存储桶(bucket)中。

—     初始容量指哈希表中元素的数目。加载因子是哈希表元素与存储桶的最大比率,当初始容量需要自动扩展前,确定值与存储桶之间的最大比率。值越小,出现冲突也越小。.NET默认加载因子为1.0。

下面的例子演示如何使用这4种方法构造哈希表。

        static void Main(string[] args) {

            //使用所有默认值构建哈希表实例

            Hashtable ht = new Hashtable();

            //指定哈希表实例的初始容量为20个元素

            Hashtable ht1 = new Hashtable(20);

            //指定初始容量为20个元素,加载因子为0.8的哈希表实例

            Hashtable ht2 = new Hashtable(20, 0.8f);

            //实例化一个SortedList

            SortedList sl = new SortedList();

            sl.Add("键一", "键值一");

            sl.Add("键二", "键值二");

            sl.Add("键三", "键值三");

            //传入实现了IDictionary接口的参数创建哈希表

            Hashtable ht3 = new Hashtable(sl);

}

创建好哈希表后,可以使用Hashtable提供的方法和属性来操作哈希表对象。下面示例程序演示操作哈希表的基本方法。

class Program

{

    static void Main(string[] args)

    {

        //初始化哈希表

        Hashtable hl = new Hashtable();

        //使用Add方法向哈希表添加元素

        hl.Add("键一", "键值一");

        hl.Add("键二", "键值二");

        hl.Add("键三", "键值三");

        hl.Add("键四", "键值四");

        hl.Add("键五", "键值五");

        hl.Add("键六", "键值六");

        hl.Add("键七", "键值七");

        DisplayResult(hl);

        Console.WriteLine("通过键获取键值:"+ hl["键一"]);

        Console.WriteLine("移除哈希表中的元素");

        hl.Remove("键二");

        Console.WriteLine("哈希表中的元数总数是:" + hl.Count);

        DisplayResult(hl);

        Console.ReadLine();

    }

    static void DisplayResult(Hashtable tl)

    {

        foreach (DictionaryEntry de in tl)

        {

            Console.WriteLine("哈希表中的键:{0},对应的值{1}",de.Key,de.Value);

        }

    }

}

程序代码的输出结果如图9.14所示。

图9.14  哈希表的操作

从输出结果可以发现,哈希表内部的排列是无序的,而且哈希表没有提供类似数组中的Sort方法,如果需要使用排序集合,可以考虑使用SortedList类。

 9.5.3  SortedList

SortedList对象是可以排序的字典对象。与哈希表不同的是,SortedList内部管理值和相应键的各一个数组。这些数组有初始容量,并可自动扩容,SortedList根据它们的键保持排序状态,这种特性要求为SortedList中指定的键实现IComparable接口。

为了构建SortedList的一个新实例,可以调用SortedList类的6种构造函数之一。比较常用的构造函数如下代码所示。

//使用默认初始容量,使用由键对象实现的IComparable来实现排序

public SortedList();

//使用指定的IComparer对键排序

public SortedList(IComparer comparer);

//根据IDictionary对象实例初始化SortedList

public SortedList(IDictionary d);

//指定初始容量

public SortedList(int initialCapacity);

下面的代码示例4种构造SortedList方法。

static void Main(string[] args)

{

    //默认值构建

    SortedList sl=new SortedList();

    //指定键的比较器

    SortedList s2=new SortedList(new CaseInsensitiveComparer());

    //指定初始容量

    SortedList temp=new SortedList(2);

    temp.Add("1","1");

    temp.Add("2","2");

    //使用IDictionary来初始化

    SortedList s3=new SortedList(temp);           

}

下面的示例代码将演示如何操作和使用这种类型的数据结构。

static void Main(string[] args)

{

    //默认值构建

    SortedList sl=new SortedList();

    sl.Add("键1", "键值一");

    sl.Add("键2", "键值二");

    sl.Add("键3", "键值三");

    sl.Add("键4", "键值四");

    sl.Add("键5", "键值六");

    sl.Add("键6", "键值七");

    Console.WriteLine("排序字典最初的初始化列表为:");

    DisplayResult(sl);

    sl.Remove("键5");

    Console.WriteLine("键6的键值是:{0}", sl["键6"]);           

    Console.ReadLine();

}

static void DisplayResult(SortedList sl)

{

    foreach (DictionaryEntry de in sl)

    {

        Console.WriteLine("键:{0},键值为:{1}", de.Key, de.Value);

    }

}

示例代码的输出结果如图9.15所示。

图9.15  对SortedList的操作

从图9.15中可以看到,SortedList在增、删时自动对键进行了排序。

 9.5.4  搜索排序哈希表

前面讲过,Hashtable类并没有提供可供排序的方法,但是可以通过它的两个属性Keys和Values,使用一种变通的方法来实现排序。下面的示例演示了通过keys属性排序哈希表的方法。这个方法并没有对哈希表中排列的元素顺序进行排列,这里只是采用了一种变通的方法以实现排序。代码示例如下。

static void Main(string[] args)

{

    Hashtable ht = new Hashtable();

    ht.Add("key1", "this is value1");

    ht.Add("key3", "this is vlaue3");

    ht.Add("key2", "this is value2");

    ht.Add("key4", "this is value4");

    Console.WriteLine("排序前的哈希键值顺序为:");

    foreach (DictionaryEntry de in ht)

    {

        Console.WriteLine("键{0},值{1}", de.Key, de.Value);

    }

    //获取键的集合

    ICollection keys = ht.Keys;

    //将键集合转换为ArrayList类

    ArrayList al = new ArrayList(keys);

    //使用ArrayList进行排序

    al.Sort();

    Console.WriteLine("排序后的哈希键值顺序为:");

    foreach (object key in al)

    {

        Console.WriteLine("键{0},值{1}", key, ht[key]);

    }

    Console.ReadLine();

}

示例代码的运行结果如图9.16所示。上面示例中,使用ArrayList作为Keys属性返回结果的包装,调用ArrayList类实例的Sort方法实现排序。同样的,也可以使用ArrayList类实例的搜索功能进行哈希表搜索。下面的示例代码演示如何搜索哈希表。

Hashtable ht = new Hashtable();

ht.Add("key1", "this is value1");

ht.Add("key3", "this is vlaue3");

ht.Add("key2", "this is value2");

ht.Add("key4", "this is value4");

ICollection keys = ht.Keys;

ArrayList al = new ArrayList(keys);

al.Sort();

//在这里使用ArrayList的BinarySearch搜索指定键值的值

int searchResult = al.BinarySearch("key3");

if (searchResult > 0)

{

    Console.WriteLine("搜索到的结果为:键{0},值{1}",al[searchResult],ht[al [searchResult]]);

}

else

{

    Console.WriteLine("没有搜索到有效的结果值");

}

Console.ReadLine();

程序的结果如图9.17所示。

  

图9.16  哈希表排序结果                            图9.17  哈希表的搜索

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论