C # Java HashMap equivalente

326

Viniendo de un mundo Java a C # uno, ¿hay un equivalente de HashMap? Si no, ¿qué recomendarías?

Juan
fuente

Respuestas:

482

DictionaryEs probablemente el más cercano. System.Collections.Generic.Dictionaryimplementa la System.Collections.Generic.IDictionaryinterfaz (que es similar a la Mapinterfaz de Java ).

Algunas diferencias notables que debe tener en cuenta:

  • Agregar / Obtener elementos
    • HashMap de Java tiene los métodos puty getpara configurar / obtener elementos
      • myMap.put(key, value)
      • MyObject value = myMap.get(key)
    • El Diccionario de C # utiliza la []indexación para configurar / obtener elementos
      • myDictionary[key] = value
      • MyObject value = myDictionary[key]
  • null llaves
    • Java HashMappermite claves nulas
    • .NET's Dictionaryarroja un ArgumentNullExceptionsi intentas agregar una clave nula
  • Agregar una clave duplicada
    • Java HashMapreemplazará el valor existente con el nuevo.
    • .NET's Dictionaryreemplazará el valor existente con el nuevo si usa []indexación. Si usa el Addmétodo, en su lugar arrojará un ArgumentException.
  • Intentando obtener una clave inexistente
    • Java HashMapdevolverá nulo.
    • .NET Dictionarylanzará un KeyNotFoundException. Puede usar el TryGetValuemétodo en lugar de la []indexación para evitar esto:
      MyObject value = null; if (!myDictionary.TryGetValue(key, out value)) { /* key doesn't exist */ }

Dictionary's tiene un ContainsKeymétodo que puede ayudar a lidiar con los dos problemas anteriores.

Powerlord
fuente
99
No hay un equivalente exacto (en JAVA HashMap permite valores nulos y la clave nula) download.oracle.com/javase/1.4.2/docs/api/java/util/…
Fabio Maulo
3
Sí, el diccionario está cerca pero no es exacto.
Powerlord
14
Tenga en cuenta que Dictionaryarroja excepciones al agregar una clave duplicada.
Rubens Mariuzzo
44
Además, se genera una excepción al solicitar un valor con una clave no existente.
Rubens Mariuzzo
if (!myDictionary.TryGetValue(key, value))necesita un outpara el segundo argumento. Entoncesif (!myDictionary.TryGetValue(key, out value))
bugybunny el
38

Desde C # equivalente a Java HashMap

Necesitaba un diccionario que aceptara una clave "nula", pero parece que no hay una nativa, así que he escrito la mía. Es muy simple, en realidad. Heredé de Dictionary, agregué un campo privado para contener el valor de la clave "nula" y luego sobrescribí el indexador. Dice así :

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

Espero que esto ayude a alguien en el futuro.

==========

Lo modifiqué a este formato

public class NullableDictionnary : Dictionary<string, object>
KeithC
fuente
66
¿No podría continuar con el tema de genéricos haciendo que el objeto sea un parámetro de tipo?
colithium
Esto no funciona public StringDictionary this [string key] {... debe ser public String this [string key] {. También base [clave] no funcionará desde mi intento. Sugiero implementar IDictionary y solo tener un objeto de diccionario privado global y manejar el caso nulo para cada uno de los métodos.
A.sharif
44
Me pregunto por qué te esforzaste por escribir mal el Diccionario.
Jim Balter
55
@JimBalter Claramente necesita un diccionario.
Phillip Elm
17

Déjame ayudarte a entenderlo con un ejemplo del "algoritmo de codaddict"

' Diccionario en C #' es ' Hashmap en Java' en universo paralelo.

Algunas implementaciones son diferentes. Vea el siguiente ejemplo para comprender mejor.

Declarando Java HashMap:

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

Declarando Diccionario C #:

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

Obtener un valor de una ubicación:

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

Establecer un valor en la ubicación:

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

Se puede observar un ejemplo general desde abajo del algoritmo de Codaddict.

Algoritmo de codaddict en 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);

    }
}

Algoritmo de Codaddict en 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();
    }
}
Ajay Yadiki
fuente
5

Consulte la documentación en MSDN para la clase Hashtable .

Representa una colección de pares de clave y valor que se organizan en función del código hash de la clave.

Además, tenga en cuenta que esto no es seguro para subprocesos.

Rayo
fuente
22
Dictionary<TKey, TValue>es preferible, debido a la verificación del tipo de tiempo de compilación y porque no requiere el encajonamiento de los tipos de valor.
Thorarin
3

Use Dictionary: usa hashtable pero es seguro para escribir.

Además, su código Java para

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

se codificará mejor en C # de esta manera:

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

De esta manera, puede determinar la necesidad de la variable "a" dentro de un bloque y aún se puede acceder fuera del bloque si la necesita más adelante.

Shree Harsha
fuente
0

la respuesta es

Diccionario

eche un vistazo a mi función, su simple complemento utiliza las funciones miembro más importantes dentro del Diccionario

esta función devuelve falso si la lista contiene elementos duplicados

 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
    }
Basheer AL-MOMANI
fuente
0

Solo quería dar mis dos centavos.
Esto está de acuerdo con la respuesta de @Powerlord.

Pone "nulo" en lugar de cadenas nulas .

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