1

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"))
  
}
dungarian
  • 203
  • 2
  • 8
  • 3
    array.add statment needs to be inside a function. – Arpit Shukla Jun 04 '22 at 05:24
  • 1
    What you have there is a list, not an array. [`Array`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-array/) and [`List`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/) have specific meanings in Kotlin, so it's best not to confuse them. (Lists are preferred, as they're more flexible and more general; arrays are mainly limited to varargs, low-level implementation, and interoperability.) – gidds Jun 04 '22 at 10:05

3 Answers3

3

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"),
)
broot
  • 21,588
  • 3
  • 30
  • 35
0

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"))
Mino Tiana
  • 33
  • 1
  • 6
  • 2
    Welcome to Stack Overflow! As it stands, this is not sufficient as an answer, since it would not be helpful if the link didn't work. Can you edit the answer to include the main point? – Jeff Bowman Jun 04 '22 at 05:36
  • 2
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jun 04 '22 at 05:48
0

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.

Endzeit
  • 4,810
  • 5
  • 29
  • 52