copy one arraylist to another arraylist in kotlin - arraylist

I am trying to copy one ArrayList to another ArrayList in Kotlin
1st ArrayList:
private var leadList1: ArrayList<Lead> = ArrayList()
2nd ArrayList:
val leadList2: ArrayList<Lead?>?
I tried to use addAll(). leadList1.addAll(leadList2)
But its not working.
Error showing:
Required: Collection<Lead>
Found: kotlin.collections.ArrayList<Lead?>?

This isn't safe to do, because your first list can only contain objects of type Lead, while your second one has Lead? as its type parameter, meaning that it might contain null values. You can't add those to the first list.
The solution for this problem will depend on your context, but you can either let the first list contain nullable elements too:
private var leadList1: ArrayList<Lead?> = ArrayList()
Or you can add only the non-null elements of the second list to the first one:
leadList1.addAll(leadList2.filterNotNull())
And in either case, you'll have to perform a null check on leadList2, because the entire list itself is marked as potentially null as well, signified by the last ? of the type ArrayList<Lead?>?.
if (leadList2 != null) {
leadList1.addAll(leadList2.filterNotNull())
}

You can simply pass another List instance into the constructor of your new List
val originalList = arrayListOf(1,2,3,4,5)
val orginalListCopy = ArrayList(originalList)

Do this:
leadList1.addAll(leadList2.orEmpty().filterNotNull())
And to filter by property you can do like this:
leadList1.addAll(leadList2.orEmpty().filter { item -> item?.type == YourTypeString })

Related

Dynamically add list to a list in Kotlin

I have:
var myList: MutableList<MutableList<Int>>
and I want to dynamically create a list (i, j) which are Int and it is to the myList.
I tried
myList.add(mutableListOf(i,j))
But it doesn't work.
Firstly I get error: variable 'myList' must be initialized
And I am not sure that's the right way to make a list on the go and add it to a list of lists
As the error mentions, you have to initialize the list before using it.
var myList: MutableList<MutableList<Int>> with this you just declare its type.
var myList = mutableListOf<MutableList<Int>>() with this you have empty list. After that you can freely add another list inside it as an element.
initialize the list
var myList: MutableList<Int> = ArrayList()

Kotlin: Should mutableList be declared as Val or Var?

I am reading through the existing codebase for my team, and I notice mutableListOf are always declared as val. In some scenarios, elements are added to the mutableListOf only once. E.g
val jobList = mutableListOf<JobActivity>()
jobList.addAll(job.activities)
In other scenarios, elements are added to mutableListOf in a loop. E.g
val jobList = mutableListOf<JobActivity>()
newJobList.filterScanType(retrieveJobType(JobContext.NEW)).forEach {
jobList.add(it)
}
Since the list is not initialized on creation, why not declare mutableListOf as var? A lot of examples found online also follow the same pattern of declaring mutableListOf as val.
Which is best to use in the 2 scenarios described, val or var?
I think it's declared as val because the list will be the same always, the only thing that changes is it's elements. You'll never do something like:
joblist = anotherList
And as #Taseer said, the properties of the object can be changed even if it's a val. For example:
data class Example(var name: String)
val exampleObject = Example("SomeName")
You'll still be able to do this:
exampleObject.name = "AnotherName"
But you can't do this:
exampleObject = anotherObject
The general rule of thumb while using Kotlin.
Difference in val and var
You may already know the differences but for the sake of an answer, I will repeat it. var lets you modify the reference of an object while val does not permit to change the reference of an object.
An object can be declared safely using either var or val keyword but the reason why you want to use val on an object(in most cases) is that you don't want to refer that class member with a new reference of a new instance of an object. That way, you always keep a reference to the original object and you can modify object properties.
In the case of var, though nothing wrong with it, you can still use it 'without' any problems. You can still access the object properties and modify them and also you will be able to refer that class member to a reference of a new object.
Example:
val myObject = MyObject()
myObject.something = 1 //can still modify object property.
myOjbect = MyObject() //re-referencing the object, NOT POSSIBLE
var myNewObject = MyNewObject()
myNewObject.someThing = "Hello world!" //can still modify object properties
myNewObject = MyNewObject() //can still reference it.
Why to use val over var in case of 'immutable' objects?
It gives you the security of not 'accidentally' placing a new reference.
But is there any performance benefit using val?
Answer: Final keyword benefit
val is more idiomatic for the reasons given in other answers and comments.
You said the val is not instantiated, but in your example code, it is.
val jobList = mutableListOf<JobActivity>()
is a factory that instantiates an empty MutableList<JobActivity>
Using this pattern (val not var, instantiated upon declaration) ensures that your code will never find an uninitialized or null value for jobList; and the compiler can prove it.
In short - there are no rules, its up to you
if you use val you can modify mutableList, but not reassign
if you need reassign another list to same variable, use var. In most cases you dont need it, thats why your team uses it frequently
Whether a variable is var or val distinguishes between a variable of which the value (reference) can be changed (var = mutable) or not (val = immutable).
You should always strive to use val over var to avoid unwanted side-effects (changing it in another thread for example).
In case of the MutableList you should most likely use a val, because you don't want to mutate the reference to the list but rather its contents.
Here an overview of your options:
// Do you want to change its reference (r) / contents (c)?
var a = mutableListOf(1, 2, 3) // r = yes, c = yes
var b = listOf(1, 2, 3) // r = yes, c = no
val c = mutableListOf(1, 2, 3) // r = no, c = yes
val d = listOf(1, 2, 3) // r = no, c = no
You create a variable with var that is mutable (that can change). Mutable means variable can be changed in future.
val is used when variable will not be changed in future that means constant or final.
Here changed means new value or new things will be assigned to the variable but
val list = mutableListOf()
in this list variable you assigned mutable list. You just changed the value of the list. But you didn't assign new instance or new value to the variable you just added and remove value from the list. That's it. So here list is immutable itself.
It will be mutable if you do things like below...
var list = mutableListOf()
list = mutableListOf()
Two initialization on the same variable.

Kotlin multiple class for data storage

I am developing a simple Android app, that will display an icon of a vehicle and the user can click on the icon to display the vehicle information. I want to load the data dynamically when I build the app i.e. the data will come from an external source including the picture for the icon.
I am new to Kotlin and not sure what to search for to understand a suitable solution. What is the correct way to define the data, is it best to create an class as below then create an array of the class (not sure if this is possible)
public class VehicleSpec()
{
var OEM: String? = null
var ModelName: String? = null
var EngineSize: String? = null
}
Or would be better to create a multiple dimension array and then link the data to the cells?
var VehicleSpec = arrayOf(20,20)
VehicleSpec[0][0] = Null //OEM
VehicleSpec[0][1] = Null //ModelName
VehicleSpec[0][2] = Null //EngineSize
What is the best way to set up the data storage, is there any good references to understand how this should be setup?
What is the correct way to define the data, is it best to create an class as below then create an array of the class
Using an array for the properties of an object is not making the full use of the type safety you have in Kotlin (and even Java for that matter).
If what you want to express is multiple properties of an object, then you should use a class to define those properties. This is especially true if the properties have different types.
There is no performance difference between an array and a class, because you'll get a reference to the heap in both cases. You could save on performance only if you convert your multi-dimensional array approach to a single-dimension array with smart indexing. Most of the time, you should not consider this option unless you are handling a lot of data and if you know that performance is an issue at this specific level.
(not sure if this is possible)
Defining lists/arrays of classes is definitely possible.
Usually, for classes that are only used as data containers, you should prefer data classes, because they give you useful methods for free, and these methods totally make sense for simple "data bags" like in your case (equals, hashcode, component access, etc.).
data class Vehicle(
val OEM: String,
val ModelName: String,
val EngineSize: String
)
Also, I suggest using val instead of var as much as possible. Immutability is more idiomatic in Kotlin.
Last but not least, prefer non-null values to null values if you know a value must always be present. If there are valid cases where the value is absent, you should use null instead of a placeholder value like empty string or -1.
First at all, using the "class aprocah" makes it easy for you to understand and give you the full benefits of the language itself... so dont dry to save data in an array .. let the compiler handle those stuff.
Secondly i suggest you have maybe two types (and use data classes ;-) )
data class VehicleListEntry(
val id: Long,
val name: String
)
and
data class VehicleSpec(
val id: Long,
val oem: String = "",
val modelName: String = "",
val engineSize: String = ""
)
from my perspective try to avoid null values whenever possible.
So if you have strings - which you are display only - use empty strings instead of null.
and now have a Model to store your data
class VehicleModel() {
private val specs: MutableMap<Long, VehicleSpec> = mutableMapOf()
private var entries: List<VehicleListEntry> = listOf()
fun getSpec(id: Long) = specs[id]
fun addSpec(spec: VehicleSpec) = specs[spec.id] = spec
fun getEntries(): List<VehicleListEntry> = entries
fun setEntries(data: List<VehicleListEntry>) {
entries = data.toMutableList()
}
}
You could also use a data class for your model which looks like
data class VehicleModel(
val specs: MutableMap<Long, VehicleSpec> = mutableMapOf(),
var entries: List<VehicleListEntry> = listOf()
)
And last but not least a controller for getting stuff together
class VehicleController() {
private val model = VehicleModel()
init{
// TODO get the entries list together
}
fun getEntries() = model.entries
fun getSpec(id: Long) : VehicleSpec? {
// TODO load the data from external source (or check the model first)
// TODO store the data into the model
// TODO return result
}
}

Check type of ArrayList in Kotlin

Kotlin provides Array.isArrayOf() for checking if an array is of a certain type.
It's used like this
if(object.isArrayOf<String>())
And defined like this
/**
* Checks if array can contain element of type [T].
*/
#Suppress("REIFIED_TYPE_PARAMETER_NO_INLINE")
public fun <reified T : Any> Array<*>.isArrayOf(): Boolean =
T::class.java.isAssignableFrom(this::class.java.componentType)
But it's only for Array. I need to check ArrayList.
I thought to change the signature like so.
#Suppress("REIFIED_TYPE_PARAMETER_NO_INLINE")
public fun <reified T : Any> ArrayList<*>.isArrayListOf(): Boolean =
T::class.java.isAssignableFrom(this::class.java.componentType)
but class.java.componentType is specific to Array
How can I check what type of ArrayList I have?
I should clarify, I only care if its one of 3 types, so I don't need a completely open-ended way of checking.
If you want to check the type of a list you can do:
when (list.firstOrNull()) {
is String -> { /*do something*/ }
is Int -> { /*do another thing*/ }
else -> { /*do something else*/ }
}
And if you need to use the list of a certain type you can use:
list.filterInstance</*the type you need*/>()
Hope this works for you.
You can't. Arrays are the only generic type for which this is possible (because they aren't really generic in the same sense, Kotlin just hides it).
The only thing you can do is look at its contents, but of course
that won't work for empty lists;
if a list contains e.g. a String, it could be ArrayList<String>, ArrayList<CharSequence>, ArrayList<Any>, etc.
For this purpose:
I need to direct it into the appropriate Bundle method. bundle.putStringArrayList(), bundle.putIntegerArrayList(), ect
neither should be a problem, I believe.
If the list is of one type then you can convert the list to array using: toTypedArray() and after you can then check the type using: isArrayOf
But this would be inefficient since you are converting the list to array, better if you can just directly guess or retrieved the first item of the list.

How to create an Immutable List that needs to loop through a field of another list

I want to create a List of item from the field within another List of items.
private var destinies: MutableList<String> = ArrayList()
fun createDestinies(sources: List<Source>) {
for (source in sources) {
destinies.add(source.endpoint)
}
}
In order to do that, I need to define my destinies as MutableList, so that I could "add" to it. But I just need the "add" loop once.
Is there a way for me to do that, without need to have a MutableList? (i.e. I prefer an immutable List, since it doesn't need to change after that)
Apparently quite simple as below
private var destinies: List<String> = ArrayList()
fun createDestinies(sources: List<Source>) {
destinies = sources.map { it.endpoint }
}