Kotlin - Map integers to lists of lists - android

I am trying to find the proper syntax to initialize "Map<,<List<List>>>" in kotlin. I am a bit new to kotlin. I have variables initialized in my class as this:
var jitterMs: Double = 0.0
The way I am trying to initialize is this:
val bandMap: Map<Int,<List<List<String>>>> = emptyMap()
It gives me an error that a proper getter or setter is expected, and I think that's because it just doesn't understand what I am trying to do. What is wrong with this syntax?
Thanks,
Edit: As Tenfour pointed out, I actually want a mutable map. This is what I have now as an error saying there is a type error:
val bandMap: MutableMap<Int,List<List<String>>> = emptyMap()

This is how you would do it:
val bandMap: Map<Int, List<List<String>>> = emptyMap()
For a MutableMap write the following:
val bandMap: MutableMap<Int, List<List<String>>> = mutableMapOf()
Or, for the most idiomatic way to make a mutableMap would be:
val bandMap = mutableMapOf<Int, List<List<String>>>()

val bandMap: Map<Int,List<List<String>>> = emptyMap()
This will work. You added extra < >

Related

Android cast MutableLiveData<MutableSet>> to LiveData<Set>>

I'm using variable shadowing and I have a something like
val selectedEntryIds: LiveData<Set<Long>>
get() = _selectedProductIds
private val _selectedProductIds = MutableLiveData<MutableSet<Long>>(mutableSetOf())
However I get an error saying type mismatch.
Use the variance annotation out like this:
val selectedEntryIds: LiveData<out Set<Long>>
get() = _selectedProductIds
To tell the compiler that the LiveData will only produce such a set. Check:
https://kotlinlang.org/docs/generics.html#declaration-site-variance
You may be able to do the following
val selectedEntryIds: LiveData<Set<Long>>
get() = _selectedProductIds as LiveData<Set<Long>>
private val _selectedProductIds = MutableLiveData<MutableSet<Long>>(mutableSetOf())
as to cast the MutableLiveData<..> into a regular LiveData<..> object.

Why do i get "useless cast" when casting MutableLiveData to LiveData?

I have an array of feedback channels because (outside of question scope) in my ViewModel.
Now, I don't want to expose my MutableLiveData to outside my Viewmodel.
So, i make a private list of LiveData objects, but compiler complains of "Useless Cast"
private val _feedbackChannels = Array(10) { MutableLiveData<FeedbackEvent>() }
val feedbackChannels
get() = _feedbackChannels.map{
#Suppress("USELESS_CAST") // it is not useless as it no longer exposes the mutableLiveData
it as LiveData<*>
}
Why do I get USELESS_CAST warning?
Compiler doesn't realize you're doing it only to force implication of property type.
Just specify type explicitly and you'll be able to drop the cast entirely. You won't even have to use map, a simple toList() will do:
private val _feedbackChannels = Array(10) { MutableLiveData<FeedbackEvent>() }
val feedbackChannels : List<LiveData<FeedbackEvent>>
get() = _feedbackChannels.toList()
Clearly the compiler doesn't understand the point of the cast. In order to do this in a more explicit way and remove the costly map function, you can just upcast it like this:
private val _feedbackChannels = Array(10) { MutableLiveData<FeedbackEvent>() }
val feedbackChannels: Array<out LiveData<FeedbackEvent>>
get() = _feedbackChannels
Edit
If you wanted to expose a List specifically (avoid exposing a mutable array) then you should probably just create one in the first place:
private val _feedbackChannels = List(10) { MutableLiveData<FeedbackEvent>() }
val feedbackChannels: List<out LiveData<FeedbackEvent>>
get() = _feedbackChannels

Haw to use variable instead of real property name to describe property in Kotlin

There are a lot of similar questions, but I still can't find out right answer.
In Jawa square brackets works i think, but in Kotlin?
data class source (
val npk : Int = 0,
val name : String = "",
val coa : String = ""
)
fun main() {
var sourceList : MutableList<source> = mutableListOf(source(1, "Uno", "one"),
source(2, "Dues", "two"),
source(3, "Tres", "three"))
sourceList.forEach { source -> println(source.name)} // haw to use variable instead "name"?
val variable = "name"
// sourceList.forEach { source -> println(source.$variable)} Is there construction like this possible in KOTLIN?
Without code changes on your class it's only possible via reflection API. Not usually recommended as it can be slower, and is more error prone.
See this answer for an example on how reflection can be used to achieve that : https://stackoverflow.com/a/35539628/3801327
I'd recommend you to go with the solution that CommonsWare suggested in the comment ( adding get operator ) instead

How to construct MutableList based List in Kotlin?

I hope to construct MutableList a based List b, how can I do in Kotlin?
BTW, Code A is wrong
var a:MutableList<MSetting>
var b:List<MSetting>
Code A
var a=mutableListOf(b)
Kotlin has a few versions of the toMutableList() extension function that should cover you. Check out the documentation here.
Basically, on any Collection, Interable, typed Array or generic Array, you can call .toMutableList() and it will creat a new MutableList (backed by ArrayList).
So in your code, you can do this (I'm showing types, you can leave them off):
var b: List<MSetting> = listOf(...)
var a: MutableList<MSetting> = b.toMutableList()
It is a generic and needs type information e.g.
var a = mutableListOf<Int>()
I tested at https://try.kotlinlang.org/#/
EDIT: I didn't read closely enough, what you want should be a toMutableList method.
var b = listOf(2, 3);
var a = b.toMutableList()
it's very easy:
val listB = listA?.toMutableList() ?: mutableListOf() // list B = A if (A != null), other wise, B = new empty list

Create ArrayList<String> from resource string-array

I have declared ArrayList like,
var otherSeriesList = ArrayList<String>()
And trying to get data from resource by following,
otherSeriesList = ArrayList<String>(Arrays.asList(resources.getStringArray(R.array.get_other_series)))
But I am getting error. Please see the image-
How should I create ArrayList from resource string-array?
Simple do like this-
otherSeriesList = ArrayList<String>(Arrays.asList(*resources.getStringArray(R.array.get_other_series)))
* will pass the Array as vararg
Just use ArrayList(resources.getStringArray( ... ).toMutableList()) instead.
If you don't need to use ArrayList exactly in your code, then you can change type of property to MutableList<String> and call resources.getStringArray( ... ).toMutableList()
Or you can use spread operator on your array and create ArrayList via call arrayListOf(*context.resources.getStringArray())
You can to declare it as MutableList(). Also cast that StringArray to String before that.
var otherSeriesList: MutableList<String> = Arrays.asList(resources.getStringArray(R.array.get_other_series).toString())
Or you can do it like,
var otherSeriesList: MutableList<String> = resources.getStringArray(R.array.get_other_series).toMutableList()
you can create an extension function
private fun Array<String>.getAsArrayList(): ArrayList<String> {
val list = ArrayList<String>()
this.forEach { it->list.add(it) }
return list
}
and call it like this
val list = resources.getStringArray(R.array.array).getAsArrayList()
If you have an array, simply call toList() on it.
val arr = arrayOf(1, 2)
val list = arr.toList()
Alternatively, there’s also a toMutableList() extension available.
Note that you can declare lists in Kotlin like this:
val list = listOf<String>(1, 2)
To be sure to get an ArrayList, use arrayListOf().

Categories

Resources