C # Java HashMap equivalente

326

Vindo de um mundo Java para um C #, existe um equivalente HashMap? Se não, o que você recomendaria?

John
fonte

Respostas:

482

Dictionaryé provavelmente o mais próximo. System.Collections.Generic.Dictionaryimplementa a System.Collections.Generic.IDictionaryinterface (que é semelhante à Mapinterface do Java ).

Algumas diferenças notáveis ​​das quais você deve estar ciente:

  • Adicionando / Obtendo itens
    • O HashMap do Java possui os métodos pute getpara configurar / obter itens
      • myMap.put(key, value)
      • MyObject value = myMap.get(key)
    • O dicionário do C # usa []indexação para definir / obter itens
      • myDictionary[key] = value
      • MyObject value = myDictionary[key]
  • null chaves
    • Java's HashMappermite chaves nulas
    • O .NET Dictionarylança um ArgumentNullExceptionse você tentar adicionar uma chave nula
  • Adicionando uma chave duplicada
    • O Java HashMapsubstituirá o valor existente pelo novo.
    • O .NET Dictionarysubstituirá o valor existente pelo novo se você usar a []indexação. Se você usar o Addmétodo, ele lançará um ArgumentException.
  • Tentativa de obter uma chave inexistente
    • O Java HashMapretornará nulo.
    • .NET Dictionarylançará um KeyNotFoundException. Você pode usar o TryGetValuemétodo em vez da []indexação para evitar isso:
      MyObject value = null; if (!myDictionary.TryGetValue(key, out value)) { /* key doesn't exist */ }

Dictionarypossui um ContainsKeymétodo que pode ajudar a lidar com os dois problemas anteriores.

Powerlord
fonte
9
Não há um equivalente exato (no JAVA HashMap permite valores nulos e a chave nula) download.oracle.com/javase/1.4.2/docs/api/java/util/…
Fabio Maulo
3
Sim, o dicionário está próximo, mas não é exato.
Powerlord
14
Observe que Dictionarylança exceções ao adicionar uma chave duplicada.
Rubens Mariuzzo
4
Além disso, uma exceção é lançada ao solicitar um valor com uma chave inexistente.
Rubens Mariuzzo
if (!myDictionary.TryGetValue(key, value))precisa de um outpara o segundo argumento. Entãoif (!myDictionary.TryGetValue(key, out value))
bugybunny
38

De C # equivalente ao Java HashMap

Eu precisava de um dicionário que aceitasse uma chave "nula", mas parece não haver uma nativa, por isso escrevi a minha. É muito simples, na verdade. Eu herdei do Dictionary, adicionei um campo privado para armazenar o valor da chave "null" e depois substituí o indexador. É assim:

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 isso ajude alguém no futuro.

==========

Eu o modifiquei para este formato

public class NullableDictionnary : Dictionary<string, object>
KeithC
fonte
6
Não foi possível continuar o tema dos genéricos transformando o objeto em um parâmetro de tipo?
Colithium
Isso não funciona. public StringDictionary esta [string key] {... deve ser pública String esta [string key] {. Também a base [chave] não funcionará na minha tentativa. Sugiro implementar o IDictionary e ter apenas um objeto de dicionário privado global e manipular o caso nulo para cada um dos métodos.
A.sharif 15/05
4
Eu me pergunto por que você se esforçou para escrever incorretamente o Dicionário.
Jim Balter
5
@ JimBalter Claramente ele precisa de um dicionário.
Phillip Elm
17

Deixe-me ajudá-lo a entender isso com um exemplo do "algoritmo do codaddict"

' Dicionário em C #' é ' Hashmap em Java' no universo paralelo.

Algumas implementações são diferentes. Veja o exemplo abaixo para entender melhor.

Declarando o Java HashMap:

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

Declarando o dicionário C #:

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

Obtendo um valor de um local:

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

Definindo um valor no local:

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

Um exemplo geral pode ser observado abaixo do algoritmo do Codaddict.

algoritmo do codaddict em 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 do codaddict em 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
fonte
5

Confira a documentação no MSDN para a classe Hashtable .

Representa uma coleção de pares de chave e valor organizados com base no código de hash da chave.

Além disso, lembre-se de que isso não é seguro para threads.

Raio
fonte
22
Dictionary<TKey, TValue>é preferível, devido à verificação do tipo de tempo de compilação e porque não requer boxe dos tipos de valor.
Thorarin 13/08/09
3

Use Dictionary - usa hashtable, mas é tipicamente seguro.

Além disso, seu código Java para

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

será melhor codificado em C # desta maneira:

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

Dessa forma, você pode definir a necessidade da variável "a" dentro de um bloco e, ainda assim, ela pode ser acessada fora do bloco, se você precisar dela mais tarde.

Shree Harsha
fonte
0

a resposta é

Dicionário

veja minha função, seu simples add usa as funções membro mais importantes dentro do Dictionary

essa função retornará false se a lista contiver itens 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
fonte
0

Eu só queria dar meus dois centavos.
Isso está de acordo com a resposta do @Powerlord.

Coloca "nulo" em vez de cadeias 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
fonte