# Kotlin : String vs StringBuilder

> If get to know something new by reading my articles, don't forget to endorse me on [LinkedIn](https://www.linkedin.com/in/rommansabbir/)

### 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.

```kotlin
    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.

```kotlin
    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`.

```kotlin
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`

```kotlin
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:

```kotlin
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...
