Equivalente HashMap Java C #


326

Venendo da un mondo Java in uno C # esiste un equivalente di HashMap? In caso contrario, cosa consiglieresti?

Risposte:


482

Dictionaryè probabilmente il più vicino. System.Collections.Generic.Dictionaryimplementa l' System.Collections.Generic.IDictionaryinterfaccia (che è simile all'interfaccia di Java Map).

Alcune notevoli differenze di cui dovresti essere a conoscenza:

  • Aggiungere / ottenere elementi
    • HashMap di Java ha i metodi pute getper impostare / ottenere elementi
      • myMap.put(key, value)
      • MyObject value = myMap.get(key)
    • Il dizionario di C # usa l' []indicizzazione per impostare / ottenere elementi
      • myDictionary[key] = value
      • MyObject value = myDictionary[key]
  • null chiavi
    • Java HashMapconsente chiavi null
    • .NET Dictionarygenera un ArgumentNullExceptionse si tenta di aggiungere una chiave null
  • Aggiunta di una chiave duplicata
    • Java HashMapsostituirà il valore esistente con quello nuovo.
    • .NET Dictionarysostituirà il valore esistente con quello nuovo se si utilizza l' []indicizzazione. Se usi il Addmetodo, lancerà invece un ArgumentException.
  • Tentativo di ottenere una chiave inesistente
    • Java HashMaprestituirà null.
    • .NET Dictionarylancerà a KeyNotFoundException. È possibile utilizzare il TryGetValuemetodo anziché l' []indicizzazione per evitare ciò:
      MyObject value = null; if (!myDictionary.TryGetValue(key, out value)) { /* key doesn't exist */ }

Dictionaryha un ContainsKeymetodo che può aiutare ad affrontare i due problemi precedenti.


9
Non esiste un equivalente esatto (in JAVA HashMap consente valori null e la chiave null) download.oracle.com/javase/1.4.2/docs/api/java/util/…
Fabio Maulo,

3
Sì, il dizionario è vicino ma non esatto.
Powerlord il

14
Nota, Dictionarygenera eccezioni quando si aggiunge una chiave duplicata.
Rubens Mariuzzo,

4
Inoltre, viene generata un'eccezione quando si richiede un valore con una chiave inesistente.
Rubens Mariuzzo,

if (!myDictionary.TryGetValue(key, value))serve un outsecondo argomento. Quindiif (!myDictionary.TryGetValue(key, out value))
bugybunny,

38

Da C # equivalente a Java HashMap

Avevo bisogno di un dizionario che accettasse una chiave "null", ma sembra che non ce ne sia uno nativo, quindi ne ho scritto uno mio. È molto semplice, in realtà. Ho ereditato dal dizionario, aggiunto un campo privato per contenere il valore per la chiave "null", quindi sovrascritto l'indicizzatore. Va così:

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

Spero che questo aiuti qualcuno in futuro.

==========

L'ho modificato in questo formato

public class NullableDictionnary : Dictionary<string, object>

6
Non potresti continuare il tema dei generici rendendo l'oggetto un parametro di tipo?
colithium,

Questo non funziona public StringDictionary this [string key] {... dovrebbe essere public String this [string key] {. Anche base [chiave] non funzionerà dal mio tentativo. Suggerisco di implementare IDictionary e semplicemente avere un oggetto dizionario privato globale e gestire il caso null per ciascuno dei metodi.
A.sharif,

4
Mi chiedo perché hai fatto di tutto per sbagliare dizionario.
Jim Balter,

5
@JimBalter Chiaramente ha bisogno di un dizionario.
Phillip Elm,

17

Lascia che ti aiuti a capirlo con un esempio di "algoritmo di codaddict"

' Dizionario in C #' è ' Hashmap in Java' nell'universo parallelo.

Alcune implementazioni sono diverse. Vedi l'esempio di seguito per capire meglio.

Dichiarazione di Java HashMap:

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

Dichiarazione del dizionario C #:

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

Ottenere un valore da una posizione:

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

Impostazione di un valore nella posizione:

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

Un esempio generale può essere osservato dal basso algoritmo di Codaddict.

algoritmo di codaddict 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);

    }
}

Algoritmo di Codaddict 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();
    }
}

5

Consulta la documentazione su MSDN per la classe Hashtable .

Rappresenta una raccolta di coppie chiave-valore organizzate in base al codice hash della chiave.

Inoltre, tieni presente che questo non è thread-safe.


22
Dictionary<TKey, TValue>è preferibile, a causa della verifica del tipo di tempo di compilazione e perché non richiede l'inscatolamento dei tipi di valore.
Thorarin,

3

Usa dizionario: utilizza hashtable ma è typesafe.

Inoltre, il tuo codice Java per

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

sarà meglio codificato in C # in questo modo:

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

In questo modo, puoi valutare la necessità della variabile "a" all'interno di un blocco ed è ancora accessibile all'esterno del blocco se ne hai bisogno in seguito.


0

la risposta è

Dizionario

guarda la mia funzione, la sua semplice aggiunta utilizza le funzioni membro più importanti all'interno del Dizionario

questa funzione restituisce false se l'elenco contiene elementi duplicati

 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
    }

0

Volevo solo dare i miei due centesimi.
Questo è secondo la risposta di @Powerlord.

Mette "null" invece di stringhe 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");
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.