3

Anyone know the best way to iterate a Java HashMap in Xamarin.Android? According to the docs it appears doing a foreach on EntrySet is suppose to return an instance of IMapEntry on each iteration, but I get an invalid cast when doing:

foreach(Java.Util.IMapEntry entry in hashMap.EntrySet())

Or if you'd rather tell me how to convert the HashMap to a .Net dictionary that would be find too as it is my end goal.

Note: this is for Xamarin.Android specifically and it doesn't seem to be as straight forward as the suggested duplicate.

  • Possible duplicate of [Iterate through a HashMap](https://stackoverflow.com/questions/1066589/iterate-through-a-hashmap) – Jon Douglas Aug 13 '17 at 20:55
  • @JonDouglas I definitely looked at that, but was unable to translate it to C#/Xamarin – aweFalafelApps Aug 13 '17 at 21:27
  • 1
    if you can't cast it to IMapEntry, what type does the debugger say that it actually is? – Jason Aug 13 '17 at 22:40
  • @Jason Java.Util.HashMap.HashMapEntry, which I am unable to figure out how to cast to. I have made some progress using JavaCast, but still working through it. I'll of course post an answer if/when I come up with something complete. – aweFalafelApps Aug 14 '17 at 00:05

1 Answers1

4

HashMap.EntrySet() returns an ICollection and items of that collection that can not be cast to an IMapEntry.... issue? probably, but the root issue is trying to use Java generics in C# and thus a non-generic EntrySet() should return a list of HashMap.SimpleEntry (or SimpleImmutableEntry) but is not mapped that way in Xamarin.Android...

I work around this by using the the Xamarin.Android runtime JavaDictionary (Android.Runtime.JavaDictionary) as you can "cast" a Hashmap to its generic version and act upon it as a normal C# generic class.

Assuming you are creating or receiving a simple HashMap key/value (lots of the Google Android APIs use simple HashMaps to convert to Json for their Rest APIs, i.e. the Google Android Drive API makes use of a lot of HashMaps)

Create a Java HashMap (this is from a POCO or POJO):

var map = new HashMap();
map.Put(nameof(uuid), uuid);
map.Put(nameof(name), name);
map.Put(nameof(size), size);

Create a JavaDictionary from the Handle of a Hashmap:

var jdictionaryFromHashMap = new Android.Runtime.JavaDictionary<string, string>(map.Handle, Android.Runtime.JniHandleOwnership.DoNotRegister);

Iterate the JavaDictionary:

foreach (KeyValuePair<string, string> item in jdictionaryFromHashMap)
{
    Log.Debug("SO", $"{item.Key}:{item.Value}");
}

Use Linq to create your C# Dictionary:

var dictionary = jdictionaryFromHashMap.ToDictionary(t => t.Key, t => t.Value);
SushiHangover
  • 68,368
  • 9
  • 89
  • 150