Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to convert a Java Map to a Dictionary in C#

I need to write a function in C# that takes in a java.util.Map and converts it to a C# Dictionary. (The project I'm working on uses IKVM to use some Java classes in C#.)

I've tried using a foreach loop (e.g. foreach (java.util.Map.Entry in map) or foreach (string key in map.keySet()) to add to the Dictionary element-by-element, but it seems that Java Maps and Sets are not enumerable.

What's my best approach here? Should I use a java.util.Iterator? (I'm not opposed to using a Java Iterator on principle, but it feels like there should be a cleaner, more "c-sharp-y" way.) I guess I could get the keySet, use the Set method toArray(), and iterate through that, but again, it doesn't feel "c-sharp-y". Should I just get over myself and do one of those things, or is there a better way? (Or, of those two options, which is more efficient in terms of time/space taken?)

For reference, here's a sketch of what I'm trying to do:

public Dictionary<string, object> convertMap(java.util.Map map)
{
    Dictionary<string, object> dict = new Dictionary<string, object>();
    foreach (String key in map.keySet()) // doesn't work; map is not enumerable
        dict.Add(key, map.get(key));
    return dict;
}
like image 725
firechant Avatar asked Jul 29 '13 22:07

firechant


2 Answers

You can create an extension method for map to Dictionary

java.util.Map map = new java.util.HashMap();
map.put("a", 1);
map.put("b", 2);

var dict = map.ToDictionary<string, int>();

public static class JavaUtils
{
    public static Dictionary<K, V> ToDictionary<K, V>(this java.util.Map map)
    {
        var dict = new Dictionary<K, V>();
        var iterator = map.keySet().iterator();
        while (iterator.hasNext())
        {
            var key = (K)iterator.next();
            dict.Add(key, (V)map.get(key));
        }
        return dict;
    }
}
like image 158
I4V Avatar answered Sep 26 '22 00:09

I4V


I've got one horrible suggestion which might work. Introduce an extension method on Iterable (or Iterable<E> if you can, but I'm assuming generics don't really work...)

public static class JavaExtensions
{
    public static IEnumerable ToEnumerable(Iterable iterable)
    {
        var iterator = iterable.iterator();
        while (iterator.hasNext())
        {
            yield return iterator.next();
        }
    }
}

Then you can use LINQ:

public Dictionary<string, object> convertMap(java.util.Map map)
{
    return map.keySet()
              .ToEnumerable()
              .Cast<string>()
              .ToDictionary(key => key, key => map.get(key));
}

I'm not sure whether that's nice or utterly foul... but obviously the ToEnumerable method is very reusable.

like image 21
Jon Skeet Avatar answered Sep 23 '22 00:09

Jon Skeet