ChatGPT解决这个技术问题 Extra ChatGPT

C# Java HashMap equivalent

Coming from a Java world into a C# one is there a HashMap equivalent? If not what would you recommend?


P
Powerlord

Dictionary is probably the closest. System.Collections.Generic.Dictionary implements the System.Collections.Generic.IDictionary interface (which is similar to Java's Map interface).

Some notable differences that you should be aware of:

Adding/Getting items Java's HashMap has the put and get methods for setting/getting items myMap.put(key, value) MyObject value = myMap.get(key) C#'s Dictionary uses [] indexing for setting/getting items myDictionary[key] = value MyObject value = myDictionary[key]

Java's HashMap has the put and get methods for setting/getting items myMap.put(key, value) MyObject value = myMap.get(key)

myMap.put(key, value)

MyObject value = myMap.get(key)

C#'s Dictionary uses [] indexing for setting/getting items myDictionary[key] = value MyObject value = myDictionary[key]

myDictionary[key] = value

MyObject value = myDictionary[key]

null keys Java's HashMap allows null keys .NET's Dictionary throws an ArgumentNullException if you try to add a null key

Java's HashMap allows null keys

.NET's Dictionary throws an ArgumentNullException if you try to add a null key

Adding a duplicate key Java's HashMap will replace the existing value with the new one. .NET's Dictionary will replace the existing value with the new one if you use [] indexing. If you use the Add method, it will instead throw an ArgumentException.

Java's HashMap will replace the existing value with the new one.

.NET's Dictionary will replace the existing value with the new one if you use [] indexing. If you use the Add method, it will instead throw an ArgumentException.

Attempting to get a non-existent key Java's HashMap will return null. .NET's Dictionary will throw a KeyNotFoundException. You can use the TryGetValue method instead of the [] indexing to avoid this: MyObject value = null; if (!myDictionary.TryGetValue(key, out value)) { /* key doesn't exist */ }

Java's HashMap will return null.

.NET's Dictionary will throw a KeyNotFoundException. You can use the TryGetValue method instead of the [] indexing to avoid this: MyObject value = null; if (!myDictionary.TryGetValue(key, out value)) { /* key doesn't exist */ }

Dictionary's has a ContainsKey method that can help deal with the previous two problems.


There isn't an exact equivalent (in JAVA HashMap permits null values and the null key) download.oracle.com/javase/1.4.2/docs/api/java/util/…
Yes, Dictionary is close but not exact.
Note, Dictionary throws Exceptions when adding a duplicated key.
Also, an Exception is thrown when requesting a value with a non existing key.
Note that if TryGetValue returns false, it also sets value to default for its type (typically 0 or null, which would be similar to what HashMap returns). So if you're happy with that, in some case you don't even need to check the boolean result of TryGetValue
K
Kurru

From C# equivalent to Java HashMap

I needed a Dictionary which accepted a "null" key, but there seems to be no native one, so I have written my own. It's very simple, actually. I inherited from Dictionary, added a private field to hold the value for the "null" key, then overwritten the indexer. It goes like this :

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;
            }
        }
    }
}

Hope this helps someone in the future.

==========

I modified it to this format

public class NullableDictionnary : Dictionary<string, object>

Couldn't you continue the generics theme by making object a type parameter?
This doesn't work. public StringDictionary this[string key] {... should be public String this[string key] {. Also base[key] won't work from my try. I suggest implementing IDictionary and just having a global private dictionary object and handling the null case for each of the methods.
I wonder why you went out of your way to misspell Dictionary.
@JimBalter Clearly he needs a dictionary.
A
Ajay Yadiki

Let me help you understand it with an example of "codaddict's algorithm"

'Dictionary in C#' is 'Hashmap in Java' in parallel universe.

Some implementations are different. See the example below to understand better.

Declaring Java HashMap:

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

Declaring C# Dictionary:

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

Getting a value from a location:

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

Setting a value at location:

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

An Overall Example can be observed from below Codaddict's algorithm.

codaddict's algorithm in 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);

    }
}

Codaddict's algorithm in C#

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 comment: you can use new() if you know the type of a variable, instead of typing out new Dictionary<int, int>() for example. :) (this answer was posted way before C#9.0 but readers using this code are advised to write more readable code)
S
Shree Harsha

Use Dictionary - it uses hashtable but is typesafe.

Also, your Java code for

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

will be best coded in C# this way:

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

This way, you can scope the need of variable "a" inside a block and it is still accessible outside the block if you need it later.


dict.TryGetValue(key, out int a) since C# 7.0.
j
jmort253

Check out the documentation on MSDN for the Hashtable class.

Represents a collection of key-and-value pairs that are organized based on the hash code of the key.

Also, keep in mind that this is not thread-safe.


Dictionary<TKey, TValue> is preferable, because of compile time type checking and because it doesn't require boxing of value types.
B
Basheer AL-MOMANI

the answer is

Dictionary

take look at my function, its simple add uses most important member functions inside Dictionary

this function return false if the list contain Duplicates items

 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
    }

o
ossobuko

I just wanted to give my two cents. This is according to @Powerlord 's answer.

Puts "null" instead of null strings.

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");
}