Android:How to convert the ExitGames::Common::Hashtable to java HashMap

Options
Vasilis
Vasilis
edited October 2019 in Native
Hello,

I am trying to get the properties of a user (or a room), and I need to create a HashMap from the HashTable object. Could someone please assist me on this task?

This is what I have so far:
jclass clazz = mEnv->FindClass("java/util/HashMap");
	if(clazz != NULL)
	{
        jmethodID init = mEnv->GetMethodID(clazz, "<init>", "()V");
        jobject hashMap = mEnv->NewObject(clazz, init);

		jmethodID put = mEnv->GetMethodID(clazz, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");

        char *str = "p";
        jstring jstrBuf = mEnv->NewStringUTF(str);

        jclass cls = mEnv->FindClass("java/lang/Integer");
        jmethodID midInit = mEnv->GetMethodID( cls, "<init>", "(I)V");
        jobject newObj = mEnv->NewObject(cls, midInit, player.getNumber());

		mEnv->CallObjectMethod(hashMap, put, jstrBuf, newObj);

        jclass stringClazz = mEnv->FindClass("java/lang/String");
        jmethodID id = mEnv->GetMethodID(stringClazz, "<init>", "([BLjava/lang/String;)V");

        const ExitGames::Common::Hashtable& properties = player.getCustomProperties();
        const ExitGames::Common::JVector<ExitGames::Common::Object>& keys = properties.getKeys();
        int i;
int r = keys.getSize();
        for(i) // normal forloop, simplified because the editor modifies it
        {

            ExitGames::Common::Object key = keys[i];

            jstring keyBuf = mEnv->NewStringUTF(key.toString().UTF8Representation().cstr());

            const ExitGames::Common::Object *value = properties.getValue(key);

            
                jstring valueBuf = mEnv->NewStringUTF(value->toString().UTF8Representation());
                mEnv->CallObjectMethod(hashMap, put, keyBuf, valueBuf);
            
        }
	}
This does populate the HashMap, but all keys are doubled quoted, e.g. ""Demo"". Why do I have this ?

Thank you

Comments

  • Vasilis
    Options
    The good thing is that the function toString() returns a representation of the HashTable which is almost a json object. With only one substitution, I can parse it as a JSONObject.

    Still, I would like to know what is the error in my code.
    Thank you
  • Kaiserludi
    Kaiserludi admin
    edited November 2019
    Options
    Hi @Vasilis.

    I don't know what the Java Hashmap class does internally, but it looks like one pair of quotes must come from there.
    The other pair of quoted is added by the toString() calls.
    Photons toString() API returns a string representation of the object on which it is called. If that object itself is an instance of a string class, then the toString() call adds quotes around the returned string representation of it. If you call toString() on a container class like a Dictionary, Hashtable or JVector, then the toString() implementation of that container class will iterate over all its elements and call toString() on them. Calling toString() on an instance of class Object or of a subclass of it will result in a call of toString() on its payload.

    When toString() is called on a JString instance (which will happen if you call it on an Object instance that holds a JString), then it will return the payload of that strring wrapped into quotation marks.
    This is the case because it makes it easier to spot strings in the string representations of complex containers structures (which are in turn the structures for which toString() is the most useful).

    The primary intended usage scenarios for toString() are logging and debugging: If the payload of a complex container does not seem to look like you expected, then it often helps to print a string representation of the containers inner structure in a human-readable representation.

    When you want to retrieve the payload of an Object instance, then the proper way to do it is operate through the matching KeyObject or ValueObject template for the payload type. So in the case of a key object that holds a string you would access the payload of that object through KeyObject< JString>::getDataCopy(). That way you get the original payload string and not a string representation of the Object like with a toString() call
    Hence KeyObject< JString>::getDataCopy() returns the string without additional quotes while Object::toString() returns it with extra quotes.
  • Vasilis
    Vasilis
    edited November 2019
    Options
    Hi @Kaiserludi,

    Thank you for this explanation
  • davidbillg
    Options

    It's worth noting that the order of the elements in the HashMap may not be the same as the order of elements in the original Hashtable, as the order is not guaranteed in either data structure. Additionally, if there are any null keys or values in the Hashtable, they will throw a NullPointerException in the HashMap, as HashMap does not allow null keys or values.