Kotlin : String vs StringBuilder

Kotlin : String vs StringBuilder

Java/Kotlin : String vs StringBuilder performance comparison

ยท

3 min read

If get to know something new by reading my articles, don't forget to endorse me on LinkedIn

String

As we know, Strings in Java/Kotlin are immutable. Modifying the String creates a new String object in the heap memory with the latest content and the original String is never changed.

    var tmpString = "Hello"
    tmpString += "World!"
    println("String: $tmpString")

When we append the value "World!" to the tmp variable, a new String object gets created with the new value "Hello World!" and gets assigned to tmp. The original string "Hello" does not change.

When we frequently modify strings such as using the + operator has significant performance issues, every time the + append is used, a new String object gets created and reassigned.

To modify the strings efficiently, we should consider the StringBuilder, which changes the string and does not create any extra object in the heap memory.

StringBuilder

Alternatively, we can use the StringBuilder class to modify the string. This does not create a new String object but changes the existing one.

    val tmp = StringBuilder("Hello")
    tmp.append("World!")
    println("StringBuilder: $tmp")

Learning

  • StringBuilder executes significantly faster than the String class when performing the concatenation or modification operations.

  • Modifying a String creates a new String in the heap memory. To change the content of the String, we should consider the StringBuilder class.

  • Any attempt to modify the String class creates a new object in the heap memory, which has significant performance drawbacks.

  • StringBuilder is ideal for modifying string content. It does so without creating any extra objects in the memory.

Kotlin Extension Function

Let's create a new Extension Function called writeString() which takes a Lambda Function or Higher Order Function (HOF) as a parameter and returns the result as String.

private val stringBuilderLazyInstance by lazy { StringBuilder() }

fun Any.writeString(body: (builder: StringBuilder) -> Unit): String {
    return stringBuilderLazyInstance.apply {
        clear()
        body.invoke(this)
    }.toString()
}

Here in the body: (builder: StringBuilder) -> Unit of HOF, we are receiving an instance of StringBuilder to append whatever we want to append.

Note: stringBuilderLazyInstance provides a Lazy instance of StringBuilder.

Test case for Extension Function

Let's create a new test for our Extension Function called StringBuilderExtensionTest

class StringBuilderExtensionTest {

    @Test
    fun writeAString() {
        val expected = "Hello World!"
        val result = writeString { builder ->
            builder.append("Hello ")
            builder.append("World!")
        }
        assert(expected == result)
    }
}

โœ… Tests passed: 1 of 1 test - 16ms

UseCase in Android (Example)

We can use this writeString function in our POJO class when we parse a JSON object to POJO class by using Gson. Ex:

class Data : SomethingBaseObject() {
            @SerializedName("name")
            @Expose
            var name: String? = null
                set(value) {
                    writeString { builder -> builder.append(value) }
                }

            @SerializedName("fathers_name")
            @Expose
            var fathersName: String? = null
                set(value) {
                    writeString { builder -> builder.append(value) }
                }

            @SerializedName("mothers_name")
            @Expose
            var mothersName: String? = null
                set(value) {
                    writeString { builder -> builder.append(value) }
                }

            @SerializedName("company")
            @Expose
            var company: String? = null
                set(value) {
                    writeString { builder -> builder.append(value) }
                }
        }

That's it for today. Happy Coding...

ย