C # Java HashMap เทียบเท่า


325

การมาจากโลกของ Java สู่ C # หนึ่งจะเทียบเท่า 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's HashMapจะแทนที่ค่าที่มีอยู่ด้วยค่าใหม่
    • .NET's Dictionaryจะแทนที่ค่าที่มีอยู่ด้วยค่าใหม่หากคุณใช้การ[]จัดทำดัชนี ถ้าคุณใช้วิธีการมันแทนจะโยนAddArgumentException
  • กำลังพยายามรับคีย์ที่ไม่มีอยู่
    • Java HashMapจะคืนค่าว่าง
    • .NET ของจะโยนDictionary KeyNotFoundExceptionคุณสามารถใช้TryGetValueวิธีการแทนการ[]ทำดัชนีเพื่อหลีกเลี่ยงปัญหานี้:
      MyObject value = null; if (!myDictionary.TryGetValue(key, out value)) { /* key doesn't exist */ }

DictionaryมีContainsKeyวิธีการที่สามารถช่วยจัดการกับปัญหาสองข้อก่อนหน้านี้


9
ที่มีอยู่ไม่เทียบเท่าที่แน่นอน (ใน JAVA HashMap อนุญาตให้ค่า null และที่สำคัญเป็นโมฆะ) download.oracle.com/javase/1.4.2/docs/api/java/util/...
ฟาบิโอ Maulo

3
ใช่พจนานุกรมใกล้ แต่ไม่แน่นอน
Powerlord

14
หมายเหตุจะDictionaryโยนข้อยกเว้นเมื่อเพิ่มคีย์ซ้ำ
รูเบนส์ Mariuzzo

4
นอกจากนี้ข้อยกเว้นจะถูกโยนทิ้งเมื่อร้องขอค่าด้วยคีย์ที่ไม่มีอยู่
รูเบนส์ Mariuzzo

if (!myDictionary.TryGetValue(key, value))ต้องการoutข้อโต้แย้งที่สอง ดังนั้นif (!myDictionary.TryGetValue(key, out value))
bugybunny

38

จากC # เทียบเท่ากับ Java HashMap

ฉันต้องการพจนานุกรมที่ยอมรับคีย์ "null" แต่ดูเหมือนว่าไม่มีเจ้าของภาษาอยู่แล้วดังนั้นฉันจึงเขียนของฉันเอง มันง่ายมากจริง ๆ แล้ว ฉันรับมาจากพจนานุกรมเพิ่มเขตข้อมูลส่วนตัวเพื่อเก็บค่าคีย์ "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
คุณไม่สามารถดำเนินการต่อชุดรูปแบบทั่วไปโดยการทำให้วัตถุเป็นพารามิเตอร์ชนิดได้หรือไม่
colithium

มันใช้งานไม่ได้ สาธารณะ StringDictionary นี้ [คีย์สตริง] {... ควรเป็นสาธารณะ String นี้ [คีย์สตริง] { นอกจากนี้เบส [คีย์] จะไม่ทำงานจากการลองของฉัน ฉันขอแนะนำให้ติดตั้ง IDictionary และเพียงแค่มีวัตถุพจนานุกรมส่วนตัวทั่วโลกและจัดการกรณีที่ว่างสำหรับแต่ละวิธี
A.sharif

4
ฉันสงสัยว่าทำไมคุณจึงออกไปสะกดคำผิด
Jim Balter

5
@JimBalter เห็นได้ชัดว่าเขาต้องการพจนานุกรม
Phillip Elm

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>เป็นที่นิยมมากกว่าเนื่องจากการตรวจสอบประเภทเวลารวบรวมและเพราะไม่ต้องการการชกมวยประเภทค่า
Thorarin

3

ใช้พจนานุกรม - มันใช้ hashtable แต่เป็นประเภทที่ปลอดภัย

นอกจากนี้รหัส 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 ถ้ารายการมีรายการซ้ำ

 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");
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.