Home > Enterprise >  Kotlin - mutableList always returns empty list
Kotlin - mutableList always returns empty list

Time:07-05

I'm using a range with an inline transform so that I can have a list of values and that I want to send it to a method in forEach. But, somehow I see that is not happening. This is the example code I'm using

var valuesList: List<Test> = mutableListOf()
(1..5).map {
    valuesList.plus(Test(<curr value>, Instant.now())
    // Have a condition to check the value and using the value in next statement
    valuesList.plus(Test(<prev value>, Instant.now())
}.forEach { <expecting a list here to send to a method> }

Somehow I always see valuesList as empty list. Can anyone let me know the mistake I'm doing.

Thanks in advance.

CodePudding user response:

You can't add items to List, try to change it to MutableList, also you need to use .add() to add items to the list not .plus(), .plus() is going to return a new list not adding items to the old one.

so your code should look like this :

val valuesList: MutableList<Test> = mutableListOf()
(1..5).map {
    valuesList.add(Test(<curr value>, Instant.now())
    // Have a condition to check the value and using the value in next statement
    valuesList.add(Test(<prev value>, Instant.now())
}.forEach { <expecting a list here to send to a method> }

Also forEach here is not going to receive valuesList so if you wan to iterate valuesList, iterate it separately after the map :

valuesList.forEach { }

CodePudding user response:

I would recommend to construct valuesList in one go. Something along this (not knowing more about the condition):

import java.time.Instant

data class Test(val value: Any, val now: Instant)

val valuesList: List<Test> = (1..5)
  .flatMap { i ->
    val value1 = Test(i, Instant.now())
    val condition = true   // calculate the condition to true or false here
    val value2 = if (condition) Test(i, Instant.now()) else null
    listOfNotNull(value1, value2)
  }

valuesList.forEach(::println)

CodePudding user response:

  1. You've created a mutable list, but assigned it to an immutable list. Change List<Test> to MutableList<Test>

    var valuesList: MutableList<String> = mutableListOf()
    

    You should probably also make it a val, not a var. You want to change the contents of the list, not the variable that points to the list.

    val valuesList: MutableList<String> = mutableListOf()
    
  2. plus() is an operator function that combines two lists, and returns the result. It does NOT change the lists that are being provided.

      .map {
    
        // this `plus` returns a new list
        valuesList.plus(Test(<curr value>, Instant.now())
    
    
        // Have a condition to check the value and using the value in next statement
        valuesList.plus(Test(<prev value>, Instant.now())
      }
    

    plusAssign() is the one you want - it appends the values of the second list onto the first

      valuesList.plusAssign("<current>")
    

    Because plusAssign() is an operator function, it means we can use = to make it clear. Then we can work with lists just like how we would work with integers.

      // the string will be appended to the end of the list
      valuesList  = "<current>"
    

    See more: Kotlin docs on plus and minus operators

  3. It looks unusual that you're 'mapping' 1 to 5, but not using the integer, and additionally looping over the result.

    Without further details I can't say much (please update your question with more code if you want more information). But from what you've shown I think you can use an initializer function to build an immutable list in one go:

    // create a size-5 list, with elements e1, e2, e3, e4, e5
    val valuesList: List<String> = List(5) { i ->
      "e$i"
    }
    

    I can also recommend the collection builder functions.

  • Related