C # Java HashMap эквивалент


326

Исходя из мира Java в C #, есть ли эквивалент HashMap? Если нет, что бы вы порекомендовали?

Ответы:


482

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/…
Фабио Мауло

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

14
Обратите внимание, Dictionaryвыдает исключения при добавлении дублированного ключа.
Рубенс Мариуццо

4
Кроме того, исключение выдается при запросе значения с несуществующим ключом.
Рубенс Мариуццо

if (!myDictionary.TryGetValue(key, value))нужен outдля второго аргумента. Итакif (!myDictionary.TryGetValue(key, out value))
Bugybunny

38

Из C # эквивалент Java HashMap

Мне нужен был словарь, который принимал «нулевой» ключ, но, похоже, его не было, поэтому я написал свой собственный. Это очень просто, на самом деле. Я унаследовал от словаря, добавил личное поле для хранения значения для «нулевого» ключа, а затем переписать индексатор. Это выглядит так:

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 this [строковый ключ] {. Также база [ключ] не будет работать с моей попытки. Я предлагаю реализовать IDictionary и просто иметь объект глобального частного словаря и обрабатывать нулевой регистр для каждого из методов.
А.Шариф

4
Интересно, почему вы изо всех сил пытались написать словарь орфографических ошибок?
Джим Балтер

5
@JimBalter Очевидно, ему нужен словарь.
Филипп Элм

17

Позвольте мне помочь вам понять это на примере «алгоритма codaddict»

« Словарь в C #» - это « Hashmap в Java» в параллельной вселенной.

Некоторые реализации отличаются. Смотрите пример ниже, чтобы лучше понять.

Объявление Java HashMap:

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

Объявление словаря C #:

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#

Общий пример можно наблюдать из алгоритма Codaddict.

Алгоритм codaddict в 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);

    }
}

Алгоритм Codaddict в 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

Используйте словарь - он использует хеш-таблицу, но безопасен.

Кроме того, ваш код 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

ответ

Словарь

взгляните на мою функцию, ее простое добавление использует наиболее важные функции-члены внутри словаря

эта функция возвращает false, если список содержит элементы Duplicates

 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.

Ставит «ноль» вместо нулевых строк.

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.