【问题标题】:C# Java HashMap equivalentC# Java HashMap 等价物
【发布时间】:2010-11-19 09:03:37
【问题描述】:

从 Java 世界进入 C# 世界是否存在等效的 HashMap?如果没有,你会推荐什么?

【问题讨论】:

    标签: c# java hashmap


    【解决方案1】:

    Dictionary 可能是最接近的。 System.Collections.Generic.Dictionary 实现了System.Collections.Generic.IDictionary 接口(类似于Java 的Map 接口)。

    您应该注意的一些显着差异:

    • 添加/获取项目
      • Java 的 HashMap 有 putget 设置/获取项目的方法
        • myMap.put(key, value)
        • MyObject value = myMap.get(key)
      • C# 的字典使用[] 索引来设置/获取项目
        • myDictionary[key] = value
        • MyObject value = myDictionary[key]
    • null
      • Java 的 HashMap 允许空键
      • .NET 的 Dictionary 如果您尝试添加空键,则会抛出 ArgumentNullException
    • 添加重复键
      • Java 的HashMap 将用新值替换现有值。
      • .NET 的Dictionary 如果您使用[] 索引,将用新值替换现有值。如果您使用Add 方法,它会改为抛出ArgumentException
    • 尝试获取不存在的密钥
      • Java 的 HashMap 将返回 null。
      • .NET 的 Dictionary 将抛出 KeyNotFoundException。您可以使用TryGetValue 方法而不是[] 索引来避免这种情况:
        MyObject value = null; if (!myDictionary.TryGetValue(key, out value)) { /* key doesn't exist */ }

    Dictionary's 有一个ContainsKey 方法可以帮助处理前面两个问题。

    【讨论】:

    • 没有完全等价的(在 JAVA HashMap 中允许空值和空键)download.oracle.com/javase/1.4.2/docs/api/java/util/…
    • 是的,字典很接近但不准确。
    • 注意,Dictionary 在添加重复键时会抛出异常。
    • 另外,当使用不存在的键请求值时会引发异常。
    • 请注意,如果 TryGetValue 返回 false,它value 的类型设置为 default(通常为 0 或 null,这类似于 @ 987654358@ 返回)。因此,如果您对此感到满意,在某些情况下,您甚至不需要检查 TryGetValue 的布尔结果
    【解决方案2】:

    使用字典 - 它使用哈希表但类型安全。

    另外,你的Java代码

    int a = map.get(key);
    //continue with your logic
    

    最好这样用 C# 编码:

    int a;
    if(dict.TryGetValue(key, out a)){
    //continue with your logic
    }
    

    这样,您可以将变量“a”的需要限定在一个块内,如果您以后需要它,它仍然可以在块外访问。

    【讨论】:

    • dict.TryGetValue(key, out int a) 自 C# 7.0 起。
    【解决方案3】:

    我只想给我两分钱。
    这是根据@Powerlord 的回答。

    "null" 代替 null 字符串。

    private static Dictionary<string, string> map = new Dictionary<string, string>();
    
    public static void put(string key, string value)
    {
        if (value == null) value = "null";
        map[key] = value;
    }
    
    public static string get(string key, string defaultValue)
    {
        try
        {
            return map[key];
        }
        catch (KeyNotFoundException e)
        {
            return defaultValue;
        }
    }
    
    public static string get(string key)
    {
        return get(key, "null");
    }
    

    【讨论】:

      【解决方案4】:

      让我通过一个“codaddict算法”的例子来帮助你理解它

      'Dictionary in C#' 是 'Hashmap in Java' 在平行宇宙中。

      有些实现是不同的。请参阅下面的示例以更好地理解。

      声明 Java HashMap:

      Map<Integer, Integer> pairs = new HashMap<Integer, Integer>();
      

      声明 C# 字典:

      Dictionary<int, int> Pairs = new Dictionary<int, int>();
      

      从某个位置获取值:

      pairs.get(input[i]); // in Java
      Pairs[input[i]];     // in C#
      

      在位置设置值:

      pairs.put(k - input[i], input[i]); // in Java
      Pairs[k - input[i]] = input[i];    // in C#
      

      可以从下面的 Codaddict 算法中观察到一个整体示例。

      codaddict 的 Java 算法:

      import java.util.HashMap;
      
      public class ArrayPairSum {
      
          public static void printSumPairs(int[] input, int k)
          {
              Map<Integer, Integer> pairs = new HashMap<Integer, Integer>();
      
              for (int i = 0; i < input.length; i++)
              {
                  if (pairs.containsKey(input[i]))
                      System.out.println(input[i] + ", " + pairs.get(input[i]));
                  else
                      pairs.put(k - input[i], input[i]);
              }
      
          }
      
          public static void main(String[] args)
          {
              int[] a = { 2, 45, 7, 3, 5, 1, 8, 9 };
              printSumPairs(a, 10);
      
          }
      }
      

      C# 中的 Codaddict 算法

      using System;
      using System.Collections.Generic;
      
      class Program
      {
          static void checkPairs(int[] input, int k)
          {
              Dictionary<int, int> Pairs = new Dictionary<int, int>();
      
              for (int i = 0; i < input.Length; i++)
              {
                  if (Pairs.ContainsKey(input[i]))
                  {
                      Console.WriteLine(input[i] + ", " + Pairs[input[i]]);
                  }
                  else
                  {
                      Pairs[k - input[i]] = input[i];
                  }
              }
          }
          static void Main(string[] args)
          {
              int[] a = { 2, 45, 7, 3, 5, 1, 8, 9 };
              //method : codaddict's algorithm : O(n)
              checkPairs(a, 10);
              Console.Read();
          }
      }
      

      【讨论】:

      • C#9.0 注释:如果您知道变量的类型,则可以使用new(),而不是输入new Dictionary&lt;int, int&gt;()。 :)(这个答案是在 C#9.0 之前发布的,但建议使用此代码的读者编写更具可读性的代码)
      【解决方案5】:

      答案是

      字典

      看看我的函数,它的简单添加使用了字典中最重要的成员函数

      如果列表包含重复项,此函数返回 false

       public static bool HasDuplicates<T>(IList<T> items)
          {
              Dictionary<T, bool> mp = new Dictionary<T, bool>();
              for (int i = 0; i < items.Count; i++)
              {
                  if (mp.ContainsKey(items[i]))
                  {
                      return true; // has duplicates
                  }
                  mp.Add(items[i], true);
              }
              return false; // no duplicates
          }
      

      【讨论】:

        【解决方案6】:

        查看 MSDN 上有关 Hashtable 类的文档。

        表示基于键的哈希码组织的键值对的集合。

        另外,请记住,这不是线程安全的。

        【讨论】:

        • Dictionary&lt;TKey, TValue&gt; 更可取,因为它可以进行编译时类型检查,并且不需要对值类型进行装箱。
        【解决方案7】:

        来自C# equivalent to Java HashMap

        我需要一个接受“null”键的字典,但似乎没有本地字典,所以我自己写了。其实很简单。我从 Dictionary 继承,添加了一个私有字段来保存“null”键的值,然后覆盖索引器。它是这样的:

        public class NullableDictionnary : Dictionary<string, string>
        {
            string null_value;
        
            public StringDictionary this[string key]
            {
                get
                {
                    if (key == null) 
                    {
                        return null_value;
                    }
                    return base[key];
                }
                set
                {
                    if (key == null)
                    {
                        null_value = value;
                    }
                    else 
                    {
                        base[key] = value;
                    }
                }
            }
        }
        

        希望这对将来的人有所帮助。

        ===========

        我修改成这个格式

        public class NullableDictionnary : Dictionary<string, object>
        

        【讨论】:

        • 你不能通过将对象作为类型参数来继续泛型主题吗?
        • 这不起作用。 public StringDictionary this[string key] {... 应该是 public String this[string key] {.我的尝试也无法使用 base[key] 。我建议实现 IDictionary 并只拥有一个全局私有字典对象并为每个方法处理 null 情况。
        • 我想知道你为什么特意拼错字典。
        • @JimBalter 显然他需要一本字典。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-24
        • 1970-01-01
        • 1970-01-01
        • 2013-11-04
        • 1970-01-01
        相关资源
        最近更新 更多