C # еквівалент Java HashMap


325

Вихід із світу Java в C # one є еквівалентом HashMap? Якщо ні, що б ви порадили?

Відповіді:


481

Dictionaryмабуть, найближчий. System.Collections.Generic.Dictionaryреалізує System.Collections.Generic.IDictionaryінтерфейс (схожий на Mapінтерфейс Java ).

Деякі помітні відмінності, про які слід пам’ятати:

  • Додавання / отримання елементів
    • HashMap Java має putта getметоди встановлення / отримання елементів
      • myMap.put(key, value)
      • MyObject value = myMap.get(key)
    • Словник C # використовує []індексацію для налаштування / отримання елементів
      • myDictionary[key] = value
      • MyObject value = myDictionary[key]
  • null ключі
    • Java HashMapдозволяє виконувати нульові клавіші
    • .NET Dictionaryкидає, ArgumentNullExceptionякщо ви спробуєте додати нульовий ключ
  • Додавання повторюваного ключа
    • Java HashMapзамінить існуюче значення новим.
    • .NET Dictionaryзамінить існуюче значення новим, якщо ви використовуєте []індексацію. Якщо ви використовуєте Addметод, він замість нього викине ArgumentException.
  • Спроба отримати неіснуючий ключ
    • Java HashMapповерне нульове значення.
    • .NET Dictionaryбуде кидати KeyNotFoundException. Ви можете використовувати TryGetValueметод замість []індексації, щоб уникнути цього:
      MyObject value = null; if (!myDictionary.TryGetValue(key, out value)) { /* key doesn't exist */ }

DictionaryУ Росії є ContainsKeyметод, який може допомогти впоратися з попередніми двома проблемами.


9
Немає точного еквівалента (у JAVA HashMap дозволяється нульові значення та нульовий ключ) download.oracle.com/javase/1.4.2/docs/api/java/util/…
Fabio Maulo

3
Так, словник близький, але не точний.
Powerlord

14
Зауважте, Dictionaryвикидає винятки під час додавання дублюючого ключа.
Рубенс Маріуццо

4
Також виняток видається при запиті значення за допомогою неіснуючого ключа.
Рубенс Маріуццо

if (!myDictionary.TryGetValue(key, value))потребує outдругого аргументу. Отжеif (!myDictionary.TryGetValue(key, out value))
bugybunny

38

З C # еквівалент Java HashMap

Мені потрібен був Словник, який прийняв "нульовий" ключ, але, здається, немає його рідного, тому я написав свій. Насправді це дуже просто. Я успадкував від словника, додав приватне поле для утримання значення ключа "null", а потім перезаписав індексатор. Виходить так:

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

Сподіваюся, це допоможе комусь у майбутньому.

==========

Я змінив його на цей формат

public class NullableDictionnary : Dictionary<string, object>

6
Не могли ви продовжити тему генерики, зробивши об'єкт параметром типу?
колліцій

Це не працює. public StringDictionary this [string key] {... повинен бути відкритим String this [string key] {. Також база [ключ] не спрацює з моєї спроби. Я пропоную реалізувати IDictionary і просто мати глобальний об'єкт приватного словника та обробити нульовий регістр для кожного з методів.
А.шаріф

4
Цікаво, чому ви пішли зі свого шляху до словника неправильних написань.
Джим Балтер

5
@JimBalter Очевидно, що йому потрібен словник.
Філіп Елм

17

Дозвольте мені допомогти вам зрозуміти це на прикладі "алгоритму кодидації"

" Словник у C #" - це " Hashmap на Java" у паралельній всесвіті.

Деякі реалізації відрізняються. Дивіться приклад нижче, щоб краще зрозуміти.

Декларація Java HashMap:

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

Оголошення С # словника:

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

Отримання значення з місця:

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

Встановлення значення місця:

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

Загальний приклад можна побачити нижче алгоритму кодидації.

алгоритм кодидації на 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);

    }
}

Алгоритм кодидації в 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

Ознайомтеся з документацією на MSDN для класу Hashtable .

Представляє сукупність пар ключів і значень, які організовані на основі хеш-коду ключа.

Також пам’ятайте, що це не є безпечним для потоків.


22
Dictionary<TKey, TValue>є кращим, тому що перевірка часу компіляції та тому, що вона не вимагає боксу типів значень.
Торарін

3

Використовуйте словник - він використовує хешбел, але є typesafe.

Також ваш код Java для

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

буде найкраще закодовано в C # таким чином:

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

Таким чином, ви можете обмежити необхідність змінної "a" всередині блоку, і вона все ще доступна поза блоком, якщо вам це потрібно пізніше.


0

відповідь така

Словник

погляньте на мою функцію, її просте додавання використовує найважливіші функції членів всередині словника

ця функція повертає помилкове значення, якщо список містить елементи дублювання

 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

Я просто хотів дати свої два центи.
Це відповідає відповіді @Powerlord.

Ставить "null" замість 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");
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.