C# Java Hashmap Equivalent

C# Java HashMap equivalent

Dictionary is probably the closest. System.Collections.Generic.Dictionary implements the System.Collections.Generic.IDictionary interface (which is similar to Java's Map interface).

Some notable differences that you should be aware of:

  • Adding/Getting items

    • Java's HashMap has the put and get methods for setting/getting items

      • myMap.put(key, value)
      • MyObject value = myMap.get(key)
    • C#'s Dictionary uses [] indexing for setting/getting items

      • myDictionary[key] = value
      • MyObject value = myDictionary[key]
  • null keys

    • Java's HashMap allows null keys
    • .NET's Dictionary throws an ArgumentNullException if you try to add a null key
  • Adding a duplicate key

    • Java's HashMap will replace the existing value with the new one.
    • .NET's Dictionary will replace the existing value with the new one if you use [] indexing. If you use the Add method, it will instead throw an ArgumentException.
  • Attempting to get a non-existent key

    • Java's HashMap will return null.
    • .NET's Dictionary will throw a KeyNotFoundException. You can use the TryGetValue method instead of the [] indexing to avoid this:

      MyObject value = null;
      if (!myDictionary.TryGetValue(key, out value)) { /* key doesn't exist */ }

Dictionary's has a ContainsKey method that can help deal with the previous two problems.

How to create a HashMap in C#

Look at Dictionary<key,value> in the System.Collections.Generic. It is the C# "parallel" (albeit having some differences, it is the closest to) of HashMap in Java.

C# Equivalent of Java IdentityHashMap

You can use RuntimeHelpers.GetHashCode(object) which calls object.GetHashCode() non-virtually - this is the equivalent of System.identityHashcode in Java. I think that's what you're after. So your IEqualityComparer would just use that for hashing and object.ReferenceEquals for equality.

Java HashMap to a C# Dictionary

FYI: The accepted answer using new is NOT a port of the provided Java answer. The end result may be the same (and I actually recommend using new instances instead of the methods called player and attribute), but it's not a port of the Java answer. I primarily wanted to clarify that in this answer in case someone else comes across this SO question & answer in the future.

Based on the Java code, it seems your program should contain the methods player(String) and attribute(String, String, String), which return a Player-instance and List<Attribute>-instance respectively. So you should create those same methods in the C# .NET program.

Your current Java snippet doesn't work as is, and actually would result in a similar error! Try it online.

The accepted answer using the new to create new instances of the Player and List<Attribute> directly may work and give the same results in both programs, but it's not a direct port of your current Java implementation! Otherwise your Java code would have looked like this instead:

Map<Player, List<Attribute>> map = new HashMap<>();
map.put(
new Player("Lebron James"),
new ArrayList<Attribute>(){{
add(new Attribute("mid height"));
add(new Attribute("mid weidght"));
add(new Attribute("high vertical"));
}}
);

Try it online.

Assuming your more complete Java code is something like this:

  ...

Map<Player, List<Attribute>> map = new HashMap<>();
map.put(
player("Lebron James"),
attribute("mid height", "mid weidght", "high vertical")
);
}

private Player player(String name){
return new Player(name);
}

private List<Attribute> attribute(String... strAttributes){
List<Attribute> resultList = new ArrayList<>();
for(String strAttr : strAttributes){
resultList.add(new Attribute(strAttr));
}
return resultList;
}

Try it online.

The ported C# .NET code would become this:

  ...

IDictionary<Player, IList<Attribute>> dictionary = new Dictionary<Player, IList<Attribute>>();
dictionary.Add(
player("Lebron James"),
attribute("mid height", "mid weidght", "high vertical")
);
}

private Player player(string name){
return new Player(name);
}

private IList<Attribute> attribute(params string[] strAttributes){
IList<Attribute> resultList = new List<Attribute>();
foreach(string strAttr in strAttributes){
resultList.Add(new Attribute(strAttr));
}
return resultList;
}

Try it online.

Again, I primarily created this answer for other people coming across this question & answer in the future, and to clarify that the accepted answer is not a direct port of the provided Java snippet.

Equivalent Map.Compute in C#

I don't know of an exact equivalent that exists so it may come down to implementing it yourself to some degree. If you're looking for a solution that looks and feels the same, you can add an extension to Dictionary<K,V>.

There's sufficient differences between these languages to require a bit of hand waiving but, to get to the gist of it, this should suffice as a starting point.

Compute doesn't exist on the C# Dictionary so you can add it. Ideally, for an "equivalent", you'd want to ensure it covers all the cases as the original, not just this particular case (IMHO). I don't claim that the following does but you can ensure yours does by investigating the source code for compute in your Java version. (this is what I came up with looking over HashMap; I could be off).

// You can easily add to the Dictionary<K, V> implementation; SWEET!
public static class DictExtensions
{
public static V Compute<K, V>(this Dictionary<K, V> dict, K key, Func<K, V, V> func)
{
// if no func given, throw.
if (func == null) throw new ArgumentNullException(nameof(func));
// if no mapping, return null.
if (!dict.TryGetValue(key, out var value)) return default;
// get the new value from func.
var result = func(key, value);
if (result == null)
{
// if the mapping exists but func => null,
// remove the mapping and return null.
dict.Remove(key);
return default;
}
// mapping exists and func returned a non-null value.
// set and return the new value
dict[key] = result;
return result;
}
}

Then, after adding a correct using statement to the code you'd like to use Compute in, use it like you expect: map.Compute(i, (k, v) => (v == null) ? 1 : v + 1);

Java Map equivalent in C#

You can index Dictionary, you didn't need 'get'.

Dictionary<string,string> example = new Dictionary<string,string>();
...
example.Add("hello","world");
...
Console.Writeline(example["hello"]);

An efficient way to test/get values is TryGetValue (thanx to Earwicker):

if (otherExample.TryGetValue("key", out value))
{
otherExample["key"] = value + 1;
}

With this method you can fast and exception-less get values (if present).

Resources:

Dictionary-Keys

Try Get Value



Related Topics



Leave a reply



Submit