Odpowiednik C # Java HashMap


325

Przychodząc ze świata Java do C # 1, czy istnieje odpowiednik HashMap? Jeśli nie, co byś polecił?

Odpowiedzi:


481

Dictionaryjest prawdopodobnie najbliższy. System.Collections.Generic.Dictionaryimplementuje System.Collections.Generic.IDictionaryinterfejs (podobny do Mapinterfejsu Java ).

Kilka istotnych różnic, o których powinieneś wiedzieć:

  • Dodawanie / pobieranie przedmiotów
    • Java HashMap ma metody puti getdo ustawiania / pobierania elementów
      • myMap.put(key, value)
      • MyObject value = myMap.get(key)
    • Słownik C # używa []indeksowania do ustawiania / pobierania elementów
      • myDictionary[key] = value
      • MyObject value = myDictionary[key]
  • null Klucze
    • Java HashMappozwala na klucze zerowe
    • .NET Dictionaryrzuca, ArgumentNullExceptionjeśli spróbujesz dodać klucz zerowy
  • Dodanie duplikatu klucza
    • Java HashMapzastąpi istniejącą wartość nową.
    • .NET Dictionaryzastąpi istniejącą wartość nową, jeśli korzystasz z []indeksowania. Jeśli użyjesz tej Addmetody, zamiast niej wyrzuci ArgumentException.
  • Próba uzyskania nieistniejącego klucza
    • Java HashMapzwróci null.
    • .NET Dictionaryrzuca KeyNotFoundException. Możesz użyć TryGetValuemetody zamiast []indeksowania, aby tego uniknąć:
      MyObject value = null; if (!myDictionary.TryGetValue(key, out value)) { /* key doesn't exist */ }

Dictionaryma ContainsKeymetodę, która może pomóc w rozwiązaniu dwóch poprzednich problemów.


9
Nie ma dokładnego odpowiednika (w JAVA HashMap dopuszcza wartości zerowe i klucz zerowy) download.oracle.com/javase/1.4.2/docs/api/java/util/…
Fabio Maulo

3
Tak, słownik jest blisko, ale nie jest dokładny.
Władca Grudnia

14
Uwaga, Dictionaryzgłasza wyjątki podczas dodawania duplikatu klucza.
Rubens Mariuzzo,

4
Zgłaszany jest także wyjątek podczas żądania wartości z nieistniejącym kluczem.
Rubens Mariuzzo,

if (!myDictionary.TryGetValue(key, value))potrzebuje outdrugiego argumentu. Więcif (!myDictionary.TryGetValue(key, out value))
bugybunny

38

Z języka C # odpowiadającego Java HashMap

Potrzebowałem Słownika, który akceptuje klucz „zerowy”, ale wydaje się, że nie ma natywnego, więc napisałem własny. W rzeczywistości jest to bardzo proste. Odziedziczyłem po Dictionary, dodałem prywatne pole do przechowywania wartości klucza „null”, a następnie zastąpiłem indeksator. To wygląda tak:

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

Mam nadzieję, że to pomoże komuś w przyszłości.

==========

Zmodyfikowałem go do tego formatu

public class NullableDictionnary : Dictionary<string, object>

6
Czy nie można kontynuować motywu ogólnego, ustawiając obiekt jako parametr typu?
colithium

To nie działa public StringDictionary this [string string] {... powinien być public String this [string string] {. Również baza [klawisz] nie będzie działać od mojej próby. Sugeruję implementację IDictionary i posiadanie globalnego prywatnego obiektu słownika oraz obsługę wielkości null dla każdej z metod.
A.sharif,

4
Zastanawiam się, dlaczego postarałeś się źle napisać Słownik.
Jim Balter

5
@JimBalter Najwyraźniej potrzebuje słownika.
Phillip Elm

17

Pozwól, że pomogę ci to zrozumieć na przykładzie „algorytmu codaddict”

Dictionary in C #” to „ Hashmap in Java” w równoległym wszechświecie.

Niektóre implementacje są różne. Zobacz poniższy przykład, aby lepiej zrozumieć.

Deklarowanie Java HashMap:

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

Deklarowanie słownika C #:

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

Uzyskiwanie wartości z lokalizacji:

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

Ustawienie wartości w lokalizacji:

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

Ogólny przykład można zaobserwować poniżej algorytmu Codaddict.

algorytm codaddict w Javie:

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

    }
}

Algorytm Codaddict w 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

Sprawdź dokumentację MSDN dla klasy Hashtable .

Reprezentuje kolekcję par klucz-wartość, które są zorganizowane na podstawie kodu skrótu klucza.

Pamiętaj również, że nie jest to bezpieczne dla wątków.


22
Dictionary<TKey, TValue>jest preferowane ze względu na sprawdzanie typu czasu kompilacji i ponieważ nie wymaga boksu typów wartości.
Thorarin

3

Użyj słownika - używa tablicy mieszającej, ale jest bezpieczny dla typów.

Ponadto twój kod Java dla

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

najlepiej będzie kodować w C # w ten sposób:

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

W ten sposób możesz zawęzić zakres potrzeby zmiennej „a” wewnątrz bloku i jest ona nadal dostępna poza blokiem, jeśli będziesz jej potrzebować później.


0

odpowiedź to

Słownik

spójrz na moją funkcję, jej proste dodawanie wykorzystuje najważniejsze funkcje składowe w Słowniku

ta funkcja zwraca false, jeśli lista zawiera elementy Duplikaty

 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

Chciałem tylko dać dwa centy.
Jest to zgodne z odpowiedzią @Powerlord.

Ustawia „null” zamiast łańcuchów o wartości 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");
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.