0

converting from java to kotlin

java code

public void logEvent(String eventName, @Nullable Map<String, String> customParams) {
        if (customParams == null) {
            customParams = new HashMap<>();
        }
        customParams.put(OTHER_REQUIRED_KEY, OTHER_REQUIRED_VALUE);
        service.doLogEvent(eventName, customParams);
    }

kotlin code

    fun logEvent(eventName: String, customParams: Map<String, String>?) {
        var customParamsMap = HashMap<String, String>()
        if (customParams != null) {
            customParamsMap.putAll(customParams)
        }
        customParamsMap[OTHER_REQUIRED_KEY] = OTHER_REQUIRED_VALUE
        service.doLogEvent(eventName, customParamsMap)
    }

the kotlin code will create the temp map regardless if the passed in map is null or not.

is there a better way to avoid this map creation?

lannyf
  • 9,865
  • 12
  • 70
  • 152

2 Answers2

3

This is as simple as:

fun logEvent(eventName: String, customParams: MutableMap<String, String>?) {
    val customParamsMap = customParams ?: mutableMapOf()
    ...
}

Or you can specify a default value for customParams:

fun logEvent(eventName: String, customParams: MutableMap<String, String> = mutableMapOf()) {
    ...
}

Note that in both examples I changed the type of customParams to MutableMap. This is a direct equivalent of the Java code. If it requires to be a read-only Map then you actually need to copy elements to a new map:

fun logEvent(eventName: String, customParams: Map<String, String>?) {
    val customParamsMap = customParams?.toMutableMap() ?: mutableMapOf()
    ...
}
broot
  • 21,588
  • 3
  • 30
  • 35
2

The other answer is great for a one-to-one translation of the Java code. But if you are able to change the signature, you can make it more user friendly in Kotlin by making the parameter optional rather than nullable.

fun logEvent(eventName: String, customParams: MutableMap<String, String> = mutableMapOf()) {
    // no need for "customParamsMap`. Use "customParams" directly.
    // ...
}

But either way, in my opinion it is not user friendly to require the passed map to be mutable. And presumably there aren't so many possible parameters that we are worried about the performance of copying them over. I would write the function like this, simple and flexible:

fun logEvent(eventName: String, customParams: Map<String, String> = emptyMap()) {
    service.doLogEvent(eventName, customParams + (OTHER_REQUIRED_KEY to OTHER_REQUIRED_VALUE))
}
Tenfour04
  • 83,111
  • 11
  • 94
  • 154
  • thx. +1, it is very good suggestion. in my simplified sample (definitely misleading) there is only one line to add extra content into final map. In real code it has some logic to build up different extra params based on different case. – lannyf Jul 14 '21 at 15:13