梦想与现实的落差,就是我们离成功的距离!!

博客园 首页 新随笔 联系 订阅 管理
  34 Posts :: 3 Stories :: 371 Comments :: 18 Trackbacks
不知道把这么一篇不入流的东西放在首页有碍观瞻,但就算是新手也一般是浏览首页,我的目的也是希望给一些碰到类似问题的新手提供点帮助,也希望得到高手的指点。
先看下面的代码

using System;
using System.Collections;

namespace NoSortHashtable
{
    
/// <summary>
    
/// Summary description for Class1.
    
/// </summary>
    class Class1
    {
        
/// <summary>
        
/// The main entry point for the application.
        
/// </summary>
        [STAThread]
        
static void Main(string[] args)
        {
            Hashtable hashTable 
= new Hashtable();

            hashTable.Add(
"hunan","changsha");
            hashTable.Add(
"beijing","beijing");
            hashTable.Add(
"anhui","hefei");
            hashTable.Add(
"sichuan","chengdu");
            
foreach(string str in hashTable.Keys)
            {
                Console.WriteLine(str 
+ " : " + hashTable[str]);
            }

        }
    }
}

打印的结果是:
    anhui : hefei
    hunan : changsha
    sichuan : chengdu
    beijing : beijing

当然,产生这个结果的原因大家都知道,Hashtable内部的排序机制使然,但我现在就是不想排序,我按什么顺序输入的,就想它再怎么给我输出,怎么办?去Google酷了一下,却因为不知道使用什么关键字去酷,结果没有酷出好的相关问题来。
我想到,ArrayList是不排序的啊,那是不是让ArrayList和Hastable配成良缘,那么它们的结晶就是我想要的呢,既有Hashtable的丰富功能,又可以满足我的BT的要求(不排序),动手了。
using System;
using System.Collections;

namespace NoSortHashtable
{
    
/// <summary>
    
/// Summary description for NoSortedHashtable.
    
/// </summary>

    public class NoSortHashtable : Hashtable
    
{
        
private ArrayList keys = new ArrayList();

        
public NoSortHashtable()
        
{
        }

        

        
public override void Add(object key, object value)
        
{
            
base.Add (key, value);
            keys.Add (key);
        }


        
public override ICollection Keys
        
{
            
get
            
{
                
return keys;
            }

        }


        
public override void Clear()
        
{
            
base.Clear ();
            keys.Clear ();
        }


        
public override void Remove(object key)
        
{
            
base.Remove (key);
            keys.Remove    (key);
        }

        
public override IDictionaryEnumerator GetEnumerator()
        
{
            
return base.GetEnumerator ();
        }


    }

}


再试
            hashTable = new NoSortHashtable();

            hashTable.Add(
"hunan","changsha");
            hashTable.Add(
"beijing","beijing");
            hashTable.Add(
"anhui","hefei");
            hashTable.Add(
"sichuan","chengdu");
            
foreach(string str in hashTable.Keys)
            {
                Console.WriteLine(str 
+ " : " + hashTable[str]);
            }

打印结果:
    hunan : changsha
    beijing : beijing
    anhui : hefei
    sichuan : chengdu


问题解决!!
应该很早之前就有人这么解决,只是我不知道而已,高手也应该有更好的办法,只是我想不到而已!
见笑,见谅!
posted on 2006-01-05 11:56 叶漂 阅读(10153) 评论(42)  编辑 收藏 所属分类: 经验小谈

评论

#1楼 2006-01-05 12:26 quitgame      
高手啊

有一点遗憾
就是把 Hashtable 的几个构造函数弄丢了
建议使用装饰器模式解决此问题

  回复  引用  查看    

#2楼 2006-01-05 12:31 linkin      
try NameValueCollection
  回复  引用  查看    

#3楼 2006-01-05 12:55 kiler      
用用sortedlist吧,可以排序
  回复  引用  查看    

#4楼 2006-01-05 13:08 leafyoung      
System.Collections.Specialized.ListDictionary 这个应该可以满足要求,只要数据量不太大
  回复  引用    

#5楼[楼主] 2006-01-05 13:13 叶漂      
to kiler
sortedlist 是不行的,我就是不要排序,它也是自动排序的

  回复  引用  查看    

#6楼[楼主] 2006-01-05 13:13 叶漂      
多谢大家的指点
  回复  引用  查看    

good
  回复  引用  查看    


  

#9楼 2006-01-05 18:28 FantasySoft      
Hashtable中元素的序列应该是随机的哦~~~
  回复  引用  查看    

#10楼[楼主] 2006-01-05 19:10 叶漂      
不是随机排序的,是在内部通过某种机制对Key进行排序,在外面是干涉不到的,所以我们不能直接对Hashtable排序的,当然通过某些变通的方法也可以让它按字母顺序排序
  回复  引用  查看    

#11楼 2006-01-06 08:30 quitgame      
@FantasySoft
Hashtable 内的元素 基本是按 哈希值 排序的,但如果遇到碰撞,会执行相应的散列
^^

  回复  引用  查看    

#12楼 2006-01-06 08:47 DrkBreeze's Bolg      
用Queue 行不行啊, 这个好像是一个先进先出的队列
  回复  引用  查看    

#13楼 2006-01-06 08:57 Pharaoh      
很久以前写的一个不排序和可以重复Key的SortedList,可以参考一下。http://pharaoh.cnblogs.com/archive/2005/05/16/156202.html">http://pharaoh.cnblogs.com/archive/2005/05/16/156202.html
  回复  引用  查看    

#14楼 2006-01-06 09:19 FantasySoft      
虽然没有玩过C#中的Hashtable,但是我相信Hashtable的实现应该都是类似的。如果Hashtable以一个固定的规则排序,那么也就是说增加key/value pair的顺序不会影响最终的输出结果。但是事实上并非如此,改变了以下四句话的顺序,会影响最终的输出结果的:
hashTable.Add("hunan","changsha");
hashTable.Add("beijing","beijing");
hashTable.Add("anhui","hefei");
hashTable.Add("sichuan","chengdu");

也许我妄言是随机排序有点武断了,但既然是排序,就应该与增加key/value pair的次序是无关的,否则又怎能算排序呢?

我的基础知识比较薄弱,如果说错了,请各位多多批评。

  回复  引用  查看    

#15楼 2006-01-06 09:56 quitgame      
@FantasySoft
我查了一下MSDN 又试了一下
1 我前面所述的 "基本是按 哈希值 排序的" 是不正确的,只能说跟Hash值有关
2 并没有发现 因为插入的顺序不同而导致输出的顺序不同
3 输出的顺序会因为 存储桶的大小而改变
比如说 ht = new Hashtable(10) ; 和 ht = new Hashtable(100) ; 的时候会出两种不同的输出结果
考虑到简单的Hash算法 一般是这样的 存储位置 = x.GetHashCode() % 桶大小 , 假设Hashtable 的输出枚举是按照存储位置进行的,则输出结果会随初始桶的大小而改变是正确的

请多多指教 :)

  回复  引用  查看    

#16楼 2006-01-06 10:19 FantasySoft      
To quitgame: 所谓输出的变化,是值key的顺序发生了变化。诚然,由key得出的hashcode由始至终都是一样的,但问题是通过Hashtable.Keys返回的key序列却会根据插入的顺序而发生变化。见以下测试结果:
1. 与原文一样的插入顺序:
hashTable.Add("hunan","changsha");
hashTable.Add("beijing","beijing");
hashTable.Add("anhui","hefei");
hashTable.Add("sichuan","chengdu");

结果是:anhui : hefei
hunan : changsha
sichuan : chengdu
beijing : beijing

2. 改变了插入顺序:
hashTable.Add("anhui","hefei");
hashTable.Add("beijing","beijing");
hashTable.Add("hunan","changsha");
hashTable.Add("sichuan","chengdu");

结果是:hunan : changsha
anhui : hefei
beijing : beijing
sichuan : chengdu

  回复  引用  查看    

#17楼 2006-01-06 10:27 quitgame      
@http://perhaps.cnblogs.com/" target="_blank">FantasySoft
不知你的全部代码?我的是
Hashtable hashTable =new Hashtable();

hashTable.Add(
"anhui","hefei");
hashTable.Add(
"beijing","beijing");
hashTable.Add(
"hunan","changsha");
hashTable.Add(
"sichuan","chengdu");

foreach(string s in hashTable.Keys)
{
Console.WriteLine(hashTable[s]) ;
}

得出的结果始终是 hefei changsha chengdu beijing
我的是 fw1.1 的结果 :)


  回复  引用  查看    

#18楼 2006-01-06 10:30 FantasySoft      
To quitgame: 对于你说的第三点,hashtable的初始长度会用于计算某一个key/value的index,因此改变了初始长度,index也就发生了变化,那么key的序列发生变化也在情理之中。
  回复  引用  查看    

#19楼 2006-01-06 10:33 FantasySoft      
To quitgame:就是把楼主的代码拿来修改啊,改变代码中的Add方法的顺序就会得到不同的输出结果。难道我们的结果不一样? FT~~~

BTW:我用的.NET 2.0,而且我也在Java上测试过了,相同的结果。

  回复  引用  查看    

#20楼 2006-01-06 14:25 FantasySoft      

To quitgame: 我写一篇Post——http://perhaps.cnblogs.com/archive/2006/01/06/312335.html" target="_blank">解读Hashtable来说明这个问题的。

谢谢你,还有叶漂兄,给了我思考与反思的机会。


  回复  引用  查看    

#21楼 2006-01-06 15:23 活靶子.Net      
SortList可以用阿
  回复  引用  查看    

#22楼[楼主] 2006-01-06 15:33 叶漂      
没想到我的一篇小文引发了我们对hashtable的深入讨论,让我明白了一句话,“鼓不敲不响,话不讲不明”,也怪不得那么多爱开研讨会了。
另外郑重申明,本人是GG,不是MM,这么MM是我GF而已

  回复  引用  查看    

#23楼 2006-01-06 17:58 FantasySoft      
叶漂兄,不好意思,不好意思~~ 我已经改过来了。
  回复  引用  查看    


  

#25楼[楼主] 2006-01-14 17:56 叶漂      
xiaoma
的确,hashtable的确是检索速度很快,直接实现IDictionary接口,应该是可以的,但本人现在项目很紧,也没时间去验证了。等有时间,我也得好好去研究一下!

  回复  引用  查看    

#26楼 2006-01-25 08:04 狂人      
IList接口是有序的,也就是说,是按照添加入的顺序保存的

现在在一般情况下,我都是用List<T,T>泛型来做这样的事情

  回复  引用  查看    

#27楼 2006-06-28 00:11 Eunge      
建议看看数据结构中的“哈希”以及了解一下什么是“哈希冲突”,哈希就是哈希,和列表和本质区别。
  回复  引用  查看    


  

#29楼[楼主] 2006-07-25 11:26 叶漂      
@QQ254875073
c#

  回复  引用  查看    


  


  


  


  


  


  

#36楼 2007-06-15 14:01 Robot·H      
ArrayList akeys=new ArrayList(ht.Keys); System.Collections
akeys.Sort(); //按字母顺序进行排序
foreach(string skey in akeys)
{
Console.Write(skey + ":");
Console.WriteLine(ht[skey]);//排序后输出
}

  回复  引用  查看    


  


  

#39楼 2008-05-04 21:47 liubo      
姐姐好。
  回复  引用  查看    


  




发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 311418


相关文章:

相关链接: