2016-11-22 30 views
1

在密鑰複雜的情況下(值的組合) 例如,密鑰可能是一對字符串和整數。字典中複雜鍵的數據結構

你會推薦哪種數據類型用於密鑰?考慮到性能和內存使用情況,如果從字典中讀取大量數據,那麼很難分配的數據類型可能不適合該任務。

我測試了4種不同的策略。

  1. 最幼稚一個,使用一個字符串作爲密鑰和CONCAT的組件:

    int Read(string str, int num) 
    { 
        var key = str + "|" + num; 
        return dict[key]; 
    } 
    
  2. 使用元組代表鍵:

    int Read(string str, int num) 
    { 
        var key = new Tuple<string, int>(str, num); 
        return dict[key]; 
    } 
    
  3. 使用用於KeyValuePair代表關鍵:

    int Read(string str, int num) 
    { 
        var key = new KeyValuePair<string, int>(str, num); 
        return dict[key]; 
    } 
    

我不喜歡第一種方法,用tuple看起來更優雅。 但是,Tuple和字符串沒有太大區別,因爲它們都是類,分配它們可能很昂貴。 KeyValuePair看起來是最可行的數據類型,但在運行一些測試後,我發現它比字符串或元組差得多,因爲KeyValuePair沒有實現GetHashCode(),現在看起來很明顯。 然後我試圖執行重寫Equals和GetHashCode()方法我自己的「KeyValuePair」:

struct KVPair<K, V> 
{ 
    public K Key { get; set; } 

    public V Value { get; set; } 

    public KVPair(K key, V value) 
    { 
     Key = key; 
     Value = value; 
    } 

    public override bool Equals(object obj) 
    { 
     if (!(obj is KVPair<K,V>)) 
     { 
      return false; 
     } 

     KVPair<K, V> other = (KVPair<K, V>)obj; 
     return Key.Equals(other.Key) && 
      Value.Equals(other.Value); 
    } 

    public override int GetHashCode() 
    { 
     int keyHash = Key.GetHashCode(); 
     int valHash = Value.GetHashCode(); 

     return (((keyHash << 5) + keyHash)^valHash); 
    } 
} 

而且使用它作爲我的字典裏的一個關鍵:

int Read(string str, int num) 
    { 
     var key = new KVPair<string, int>(str, num); 
     return dict[key]; 
    } 

它似乎表現得比較好字符串和元組選項,並且比本機KeyValuePair好得多。

我只是想聽聽你會推薦什麼。 由於FCL通常需要處理這些數據,因此我必須謹慎實施自己的數據類型。

回答

1

我更喜歡使用especific類型與關聯屬性名稱:使用

public class RowKey 
{ 
    public string Title { get; set; } 
    public int Id { get; set; } 

    public RowKey() 
    { 
    } 

    public RowKey(string title, int id) 
    { 
     Title = title; 
     Id = id; 
    } 

    public override bool Equals(object obj) 
    { 
     if (!(obj is RowKey)) 
      return false; 

     RowKey other = obj as RowKey; 
     return Title.Equals(other.Title) && Id.Equals(other.Id); 
    } 
    public override int GetHashCode() 
    { 
     int titleHash = Title.GetHashCode(); 
     int idHash = Id.GetHashCode(); 

     return (((titleHash << 5) + titleHash)^idHash); 
    } 
} 

閱讀:

int Read(string str, int num) 
{ 
    var key = new RowKey(str, num); 
    return dict[key]; 
} 
+0

但是是不是一樣用一個元組?這是一個階級,我對它的考慮是分配。 – areller

+0

是的,但是,考慮一下你的代碼結構和組織。元組是通用的,你可能會丟失你的上下文... –

+0

這是在這種情況下反對使用元組的一個好處。但是如何讓你的密鑰成爲一個結構而不是類? – areller