How to make static array in Kotlin?

761 views Asked by At

I am trying to make a static array in Kotlin. For doing this, I created an Object class, and inside that declared a mutableListOf<PersonModel>().

When I try to add new Object PersonModel to array, I get red underline suggesting error in last line, which says Expecting member declaration.

Code

object Data {
    
    val array = mutableListOf<PersonModel> (PersonModel("roshan",65,50,"White",21,"male"))
    
    array.add(PersonModel("roshan",65,50,"White",21,"male"))
  
}
3

There are 3 answers

0
broot On BEST ANSWER

You can't use arbitrary executable code inside object/class declaration. This code block is only for defining of class members. If you want to execute some code when the class is instantiated, you can use initialization block:

object Data {
    
    val array = mutableListOf<PersonModel> (PersonModel("roshan",65,50,"White",21,"male"))
    
    init {
        array.add(PersonModel("roshan",65,50,"White",21,"male"))
    }
}

If you prefer to keep initialization code for a member in a single place, a common pattern is to use scope function, for example run() or apply():

val array = mutableListOf<PersonModel>().apply {
    add(PersonModel("roshan",65,50,"White",21,"male"))
    add(PersonModel("roshan",65,50,"White",21,"male"))
}

In your specific case, you don't have to do this, because you can create a list with both items directly:

val array = mutableListOf<PersonModel> (
    PersonModel("roshan",65,50,"White",21,"male"),
    PersonModel("roshan",65,50,"White",21,"male"),
)
0
Endzeit On

As written by @Arpit Shukl in the comments, one cannot add arbitrary statements such as array.add(...) to the body of an object (or class) declaration.

To achieve a statically initialized, globally available variable (or value) in Kotlin, you have multiple options.

Top-level declaration

In Kotlin you can declare variables / values and functions on the top-level without the need for a wrapping object (or class).

package com.example.models

val availablePersonModels = listOf(
    PersonModel("roshan", 65, 50, "White", 21, "male")
)
import com.example.models.availablePersonModels

fun foo() {
    for (availablePersonModel in availablePersonModels) {
        println(availablePersonModel)
    }
}

If you want to be able to add / remove items from the list after initialization, simply exchange listOf with mutableListOf.

Object declaration

If you want to group several declarations together or make the declaration context more explicit, you may wrap the declaration in an object.

object ModelProvider {
    val availablePersonModels = listOf(
        PersonModel("roshan", 65, 50, "White", 21, "male")
    )
}
import com.example.models.ModelProvider

fun foo() {
    for (availablePersonModel in ModelProvider.availablePersonModels) {
        println(availablePersonModel)
    }
}

Initializing static values using statements

The listOf and mutableListOf function calls support being passed values to add to the created List, thus you do NOT need to call add(...) as part of the initialization. However, that must not be the case always. E.g. there might be classes that need to be instantiated with an empty constructor and filled with values by calling setters afterdwards.

class ExampleClass {
    var x: Int? = null
    var y: Int? = null
}

Using the object declaration above, you might want to add such calls into the constructor of the object, e.g.:

object ModelProvider {
    val exampleValue = ExampleClass()

    init {
        exampleValue.x = 1
        exampleValue.y = 1
    }
}

Instead of splitting the initialization and population like above, you might also use a single expression for both, e.g. using one of the scope functions such as apply, e.g.:

val exampleValue = ExampleClass().apply {
    x = 1
    y = 1
}

Of course this can be used inside an object as well, removing the need for the init block.

2
Mino Tiana On

Here's my suggestion code:

// place the object class constructor //

class PersonModel (var name: String, var a: Int, var b: Int, var color: String, var c: Int, var sex: String)

// create your first object //

val array = mutableListOf<PersonModel>(PersonModel("roshan",65,50,"White",21,"male"))

// add the second object //

array.add(PersonModel("minotiana",30,10,"White",21,"Male"))