2011-04-04 53 views
12

我有java代码从文本文件中填充散列表。
HashMap<String, String[]> data = new HashMap<String, String[]>();delphi hashmap?

我用它来制作键值对。这些值是一个字符串数组。我必须遍历键值对的每一个可能的组合(所以也必须遍历String [] - 数组)。这适用于java,但现在我必须将其移植到delphi。有可能这样做吗?如何? 谢谢!

+2

使用Generics.Collections.TDictionary 2011-04-04 08:19:31

回答

16

在Delphi 2009及更高版本中,您可以使用使用Generics.Collections的TDictionary<string, TStringlist>

在较早的版本中,您可以使用TStringlist,其中TStringlist中的每个项目都有一个类型为TStrings的关联对象值。

的Docwiki有一个页面get started with TDictionary

+0

哦,谢谢。这看起来不错。有迭代器吗?在java中,我使用了递归方法,它给了我每个组合的键值对(注意:值是delphi环境下的字符串列表...) – someuser 2011-04-04 08:26:10

+0

您可以用for枚举键值对 – 2011-04-04 08:29:45

+0

我的代码看起来类似像这样(在stackoverflow上找到它):http://stackoverflow.com/questions/5322948/recursive-iterate-hashmap。这是怎么翻译成德尔福的? – someuser 2011-04-04 08:43:01

3

如果你有德尔福(DELPHI 6及以上)的旧版本,你也可以使用记录,那么我们TDynArrayTDynArrayHashed包装一个动态数组的创建一个包含动态数组记录的一个字段的字典。请参阅this unit

TDynArrayHashed包装的开发速度很快。

下面是一些示例代码(从供给单一测试):

var ACities: TDynArrayHashed; 
    Cities: TCityDynArray; 
    CitiesCount: integer; 
    City: TCity; 
    added: boolean; 
    N: string; 
    i,j: integer; 
const CITIES_MAX=200000; 
begin 
    // valide generic-like features 
    // see http://docwiki.embarcadero.com/CodeExamples/en/Generics_Collections_TDictionary_(Delphi) 
    ACities.Init(TypeInfo(TCityDynArray),Cities,nil,nil,nil,@CitiesCount); 
    (...) 
    Check(ACities.FindHashed(City)>=0); 
    for i := 1 to 2000 do begin 
    City.Name := IntToStr(i); 
    City.Latitude := i*3.14; 
    City.Longitude := i*6.13; 
    Check(ACities.FindHashedAndUpdate(City,true)=i+2,'multiple ReHash'); 
    Check(ACities.FindHashed(City)=i+2); 
    end; 
    ACities.Capacity := CITIES_MAX+3; // make it as fast as possible 
    for i := 2001 to CITIES_MAX do begin 
    City.Name := IntToStr(i); 
    City.Latitude := i*3.14; 
    City.Longitude := i*6.13; 
    Check(ACities.FindHashedAndUpdate(City,true)=i+2,'use Capacity: no ReHash'); 
    Check(ACities.FindHashed(City.Name)=i+2); 
    end; 
    for i := 1 to CITIES_MAX do begin 
    N := IntToStr(i); 
    j := ACities.FindHashed(N); 
    Check(j=i+2,'hashing with string not City.Name'); 
    Check(Cities[j].Name=N); 
    CheckSame(Cities[j].Latitude,i*3.14); 
    CheckSame(Cities[j].Longitude,i*6.13); 
    end; 
end; 

所以对于您的问题:

type 
    TMyMap = record 
    Key: string; 
    Value: array of string; 
    end; 
    TMyMapDynArray = array of TMyMap; 

var 
    Map: TMyMap; 
    Maps: TMyMapDynArray; 
    MapW: TDynArrayHashed; 
    key: string; 
    i: integer; 
begin 
    MapW.Init(TypeInfo(TMyMapDynArray),Maps); 
    Map.Key := 'Some key'; 
    SetLength(Map.Value,2); 
    Map.Value[0] := 'One'; 
    Map.Value[1] := 'Two'; 
    MapW.FindHashedAndUpdate(Map,true); // ,true for adding the Map content 
    key := 'Some key'; 
    i := MapW.FindHashed(key); 
    // now i=0 and Maps[i].Key=key 
    for i := 0 to MapW.Count-1 do // or for i := 0 to high(Maps) do 
    with Maps[i] do 
    // now you're enumerating all key/value pairs 
end; 
+0

我刚刚使用这个包装为我的.map文件阅读器,它的作用就像一个魅力。非常快速和容易使用。立即读取.map文件,并使用快速散列将符号名称添加到内部列表中。请参阅[此链接](http://synopse.info/forum/viewtopic.php?pid=1775#p1775) – 2011-04-05 21:16:13

3

自从Delphi 6中,该组预定义的容器类的包括TBucketList和TObjectBucketList。这两个列表是关联的,这意味着他们有一个键和一个实际的条目。密钥用于识别项目并搜索它们。要添加项目,请使用两个参数调用Add方法:密钥和数据。当您使用Find方法时,您传递密钥并检索数据。通过使用Data数组属性,将密钥作为参数传递,可以获得相同的效果。