Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

in kotlin, how to pass back a MutableList where the destination expects a List

having a hashMap with List as value defined:

     private var mMap: HashMap<String, List<DataStatus>>? = null

having a function return a hashMap but with the value of MutableList

     fun getDataStatus(response: JSONObject?): HashMap<String, MutableList<DataStatus>> {

          return HashMap<String, MutableList<AccountStatusAlert>>()
     }

when pass the result to the hashMap expecting List it got error:

     mMap = getDataStatus(resp) //<== got error

got error:

Error:(81, 35) Type mismatch: inferred type is HashMap<String, 
MutableList<DataStatus>> but HashMap<String, List<DataStatus>>? was expected
like image 437
lannyf Avatar asked Oct 09 '17 15:10

lannyf


People also ask

How do you pass a mutable list to function in Kotlin?

To add an element to a Mutable List, call add() function on this mutable list and pass the element. The new element will be added at the end of the list. We can also specify the index, at which the element has to be inserted.

How do I return a mutable list on Kotlin?

Since the type name is MutableList<Int> , you should do: fun get_factors(num: Int) : MutableList<Int> { ... } Or, if the caller doesn't need to modify the list, you can just return List<Int> too: fun get_factors(num: Int) : List<Int> { ... }

How do you push data into a list in Kotlin?

To add a single element to a list or a set, use the add() function. The specified object is appended to the end of the collection. addAll() adds every element of the argument object to a list or a set. The argument can be an Iterable , a Sequence , or an Array .

What is the difference between list and MutableList in Kotlin?

These are some important points you should know before working with Kotlin MutableList: List is read-only (immutable), you cannot add or update items in the original list. MutableList inherites List and supports read/write access, you can add, update or remove items.


2 Answers

You have two solutions depending on your needs.

Cast it

Considering that MutableList is a subclass of List, you can cast it. There's only a problem here: you will lose immutability. If you cast the List back to MutableList, you can modify its content.

mMap = getDataStatus(repo) as HashMap<String, List<String>>

Convert it

In order to maintain immutability on the list, you have to convert each MutableList to an immutable List:

mMap = HashMap<String, List<String>>()
getDataStatus(repo).forEach { (s, list) ->
    mMap?.put(s, list.toList())
}

In this case, if you try to modify the content of a list inside mMap, an exception will be thrown.

like image 51
Giorgio Antonioli Avatar answered Oct 14 '22 09:10

Giorgio Antonioli


If you do not plan to put new items in the map after it was returned to you, just declare your variable having a more permissive type:

// prohibits calling members that take List<DataStatus> as a parameter,
// so you can store a HashMap with values of any List subtype, 
// for example of MutableList
private var mMap: HashMap<String, out List<DataStatus>>? = null

or

// prohibits calling mutating methods
// List<DataStatus> already has 'out' variance
private var mMap: Map<String, List<DataStatus>>? = null

If you for some reason need that variable to have exactly that type, then you need to convert or upcast values in the returned map:

mMap = getDataStatus(resp).mapValuesTo(HashMap()) { (_, v) -> v as List<DataStatus> }
like image 44
Ilya Avatar answered Oct 14 '22 10:10

Ilya