Array Operation in Kotlin - kotlin

The question I want to ask is about programming related question in kotlin.
This question may seem really bad , but I can't think how to handle this situation.
val array = ArrayList<ArrayList<Int>>()
val subAnswer = ArrayList<Int>()
subAnswer.add(1)
subAnswer.add(2)
subAnswer.add(3)
array.add(subAnswer)
subAnswer.clear()
If I printed out the array , it is empty . The behaviour I have expected is subAnswer is cleared but the array will contain [[1,2,3]]
I want to know why.
Isn't it supposed to contained [[1,2,3]] ?
Why clearing subAnswer also cleared the array?
And how can it be solved?
I thought an object was copied and added to the array so the added object to array and subAnswer doesn't share the same memory address. In this case , it seems like the added object is just a reference of the subAnswer so clearing subAnswer can also affect the array.
If I want to get the expected behavior, how can I do it ?
If there's any programming concept related blogs about this problem , please let me know it.
Thank you.

At first you've added a reference of an array contained in subAnswer to variable array and then cleared values in that reference.
Since they were the same reference in the heap, changing it from one variable changes it.
To preserve the list, you can make a duplicate of it,
array.add(ArrayList(subAnswer)) // <- creates a new ArrayList with elements from subAnswer
subAnswer.clear()
PS: Using ArrayList directly is not a recommended style in Kotlin, you should use MutableList instead.
val list = mutableListOf<List<Int>>() // or use MutableList instead if you like too use
val subAnswer = mutableListOf<Int>()
subAnswer.add(1)
subAnswer.add(2)
subAnswer.add(3)
list.add(subAnswer.toList()) // copies and create new list, or use toMutableList to create a mutable list
subAnswer.clear()

Related

How do i declare a 2D Array in Kotlin. Without initialise the array with value's

Anybody know a short and easy way ?
I found a function that work's good but still got value's.
var tilemap = Array<IntArray>(sizeX,{IntArray(sizeY,{-1})})
If you don't want to initialise there, you have three options:
Using lazy [docs]
Using lateinit [docs], but that means, you will just place initialisation somewhere else
Using ArrayList (it contains pointers to it's elements, maybe it will be enough of not initialisation)

Kotlin - java.util.ConcurrentModificationException: null

Guys how can I fix the error java.util.ConcurrentModificationException: null
experiments.forEach {
if(NAME_VARIANT == it.variantName) {
for (i in (0..Math.min(result.size - 1, Constants.MAX_METHODS_APPLIED))) {
if (response.paymentMethods[i].scoring.rules!!.none { it.ruleName == NAME_RULE}) {
response.appliedExperiments.clear()
}
}
}
}
This exception ConcurrentModificationException is thrown when you're trying to modify a collection at the same time as iterating over it.
In the piece of code you provided, you're iterating over experiments, and you're modifying response.appliedExperiments (by calling clear() on it). If those 2 variables actually point to the same collection, calling clear() is expected to throw.
In order to do what you want, you probably want those lists to start off as copies of each other, but still be different. When you create response.appliedExperiments, make sure it's a new list and not the same list.
EDIT: in the code you provided, you are passing experiments directly to the constructor of SortingServiceResponse, and I'm guessing this constructor uses the list as-is as the appliedExperiments property of reponse. Instead, you should pass a copy of the list, for instance using toMutableList():
val response = SortingServiceResponse(experiments.toMutableList(), result)
An even better approach would be to use read-only List instead of MutableList for experiments to avoid making this kind of mistakes in the first place. Only use mutable collections when you really need to. Most of the time, you can use operators (like filter or map) that create new read-only lists instead of working with mutable lists directly.

Kotlin: val mutableList vs var immutableList. When to use which?

We are encouraged to have immutable variables as much as we can.
But sometimes when I have to modify a list I start to wonder which approach would be better for current situation...
val mutableList = mutableListOf()
// where I can just .add() / .remove() accordingly
or
var immutableList = listOf()
// where I can create a new list (using filter or `+`) each time a change is made
I guess there are different scenarios one is preferred over the other.
Hence I would like to know when one should be used over the other
val -> You could think that you can't reassign for the variable.
//that is ok
var a:Int = 1
a=2
//Even you can reassign but you can't change its type
a= "string" //that's wrong
//that is wrong
val b:Int = 1
b = 2
ListOf -> You could think that you can't insert/delete/alter any element in the list
(can't do anything to the content of the list)
var list:List<Int> = listOf(1,2,3,4) //[1,2,3,4]
//you can read list
list.get(0)
list[0]
//but you can't change(/write) the content of the list (insert/delete/alter)
list.set(0, 100)
list.add(5)
list.removeAt(0)
var mutableList:MutableList<Int> = mutableListOf(1,2,3,4) //[1,2,3,4]
//you can read and write
mutableList.get(0)
mutableList.set(0, 100) //[100,2,3,4]
mutableList.add(5) //[100,2,3,4,5]
mutableList.removeAt(0) //[2,3,4,5]
SO
combine both of them, you will get four cases
Case 1: var mutableList:MutableList = mutableListOf(1,2,3,4)
//you can reassign
mutableList = mutableListOf(4,5,6,7) //[4,5,6,7]
//you can alter the content
mutableList.set(0, 100) //[100,5,6,7]
mutableList.add(8) //[100,5,6,7,8]
mutableList.removeAt(0) //[5,6,7,8]
Case 2: val mutableList:MutableList = mutableListOf(1,2,3,4)
//you can't reassign
mutableList = mutableListOf(4,5,6,7) //that's wrong
//you can alter the content
mutableList.set(0, 100) //[100,2,3,4]
mutableList.add(8) //[100,2,3,4,8]
mutableList.removeAt(0) //[2,3,4,8]
Case 3: var list:List = ListOf(1,2,3,4)
//you can reassign
list= ListOf(4,5,6,7) //[4,5,6,7]
//you can't alter the content
list.set(0, 100) //that's wrong
list.add(8) //that's wrong
list.removeAt(0) //that's wrong
Case 4: val list:List = ListOf(1,2,3,4)
//you can't reassign
list= ListOf(4,5,6,7) //that's wrong
//you can't alter the content
list.set(0, 100) //that's wrong
list.add(8) //that's wrong
list.removeAt(0) //that's wrong
//the only thing you can do is Read
list.get(0) //return 1
list[0] //return 1
Mutable and immutable list increase the design clarity of the model.
This is to force developer to think and clarify the purpose of collection.
If the collection will change as part of design, use mutable collection
If model is meant only for viewing, use immutable list
Purpose of val and var is different from immutable and mutable list.
val and var keyword talk about the how a value/reference of a variable should be treated.
var - value/reference assigned to a variable can be changed at any point of time.
val - value/reference can be assigned only once to a variable and can't be changed later point in the execution.
It is completely valid in Kotlin to assign mutable list to a val and add element to it.
val a = mutableListOf(1,2,3,4)
a.add(5)
println(a)
will output
[1, 2, 3, 4, 5]
I guess there are different scenarios one is preferred over the other. Hence would like to get to know when one should be used over the other etc.
There are several reasons why immutable objects are often preferable:
They encourage functional programming, where state is not mutated, but passed on to the next function which creates a new state based on it. This is very well visible in the Kotlin collection methods such as map, filter, reduce, etc.
A program without side effects is often easier to understand and debug (you can be sure that the value of an object will always be the one at its definition).
In multithreaded programs, immutable resources cannot cause race conditions, as no write access is involved.
You have also some disadvantages:
Copying entire collections just to add/remove a single element is computationally expensive.
In some cases, immutability can make the code more complex, when you tediously need to change single fields. In Kotlin, data classes come with a built-in copy() method where you can copy an instance, while providing new values for only some of the fields.
Which one you end up using depends on the use case at hand. For data classes (bundling a few attributes together), it's often a good idea to stick to immutability. For collections, if you use immutable ones just to modify their copies and re-assign the reference pointing to them all the time, you can as well use mutable ones. If you share a collection to many parts of your application that depend on the state remaining constant, use immutable.
Keep in mind that Kotlin collections have different concepts:
Mutable collections: MutableList<T>, MutableSet<T>, MutableMap<T>
These can be modified at any time.
Read-only collections: List<T>, Set<T>, Map<T>
These provide a read-only view on the collection, i.e. the collection cannot be modified through that reference. It gives no guarantee about immutability though (another mutable reference to it can still exist and used for modification).
(Proposed, not yet part of Kotlin)
Immutable collections: ImmutableList<T>, ImmutableSet<T>, ImmutableMap<T>
These would guarantee true immutability, and provide patterns to build new modified collections based on them. See the Proposal for details.

What is the use of emptyArray() in Kotlin

I was learning emptyArray() in Kotlin, but I can't assign values in it (which is for obvious) and neither I can set it's size. What is the use of emptyArray in Kotlin?
There are cases where you want to fallback to an empty array or empty list. For example:
return someInputArray?.filterNotNull() ?: emptyArray()
In this case if I have a valid input array, I filter out null values, otherwise if the source array was null I return an empty array. Therefore an array is always returned instead of a null. Empty lists and arrays are probably more common than passing around nullable lists or arrays in Kotlin.
So yes, it is empty and you cannot add to it, just as no JVM array is expandable once allocated.
Similar to the java.util.Collections.emptyList() methods and its counterparts for Maps, etc., these methods are handy when you are calling a method which takes an array/collection as argument, but you don't want/need to provide any elements in that collection. You can either instantiate a new empty array/collection or use one of the helper methods.
If the above use case is very common in your scenario, you are safing memory by using the helpers as always the same instance is reused instead of creating new instances again and again. Otherwise it's mainly "syntax candy" making your code more readable and easier to understand.
emptyArray() function returns an empty array of size 0. it doesn't take any paramters (Nor size, neither elements). you can use it as rvalue in assignment operations. You can use empty array to dump all the values in a pre-existing arrays and set it's size to 0.
Note: it is better to return an empty than returning an array of nulls, as it'll not create any null point exceptions in further operations.
var array=arrayOf(1,2,3,4,5);
array = emptyArray() //The array datais dumped and size is set to 0;
array = arrayOf(0,1,2)
Arrays are fixed size containers. The emptyArray() function creates an array of 0 length, and you really can't do much with this. You can't store anything in it, and you can't resize it.
A common use case where you need an empty array would be as a default value for a property that will be set to a different array at a later point. This can be better than storing null in that property by default, because you don't have to deal with handling the possible null value when your code uses the array. For example, you can safely iterate over an empty array.
For a simple example:
class NumberHolder {
var numbers: Array<Int> = emptyArray()
fun printNumbers() {
numbers.forEach { println(it) }
}
}
The usage of this class would look something like this:
val nh = NumberHolder()
nh.printNumbers() // prints nothing
nh.numbers = arrayOf(1, 2, 3)
nh.printNumbers() // prints 1, 2, and 3 on separate lines

Is declaring a variable with an empty map, and then assigning a different object to it an efficient pattern?

We are developing a Grails project and I am am a Grails/Groovy novice and I am seeing a pattern where we define a variable as an empty map in the controller, and then in a service method also defining another empty map, and populating it with key/value pairs from the DB.
My contention is that this pattern is wasteful. We are assigning an empty map to the controller variable, only to create another map in the service and then assigning the service map to the controller variable, thereby orphaning the empty map created in the controller, and releasing it for garbage collection.
A coworker contends that the data from the service map is ending up in the controller map, such that the original map created in the controller is being used and is therefore declaring it is not wasteful.
What is really happening? Is that first controller map being created only to be garbage collected, or is it somehow being filled with the data in the service map?
Controller method:
getMap() {
....
def output = [:]
output = someService.getHashMap()
...
}
Service method:
getHashMap() {
...
def output = [:]
output = [key0: 'value0', key1: 'value1', key2: 'value2']
}
There is no good reason to do something like this...
def output = [:]
output = [key0: 'value0', key1: 'value1', key2: 'value2']
Maybe this will help clarify what is going on. The following is equivalent to the code above...
def output = new LinkedHashMap()
output = new LinkedHashMap()
output.put 'key0', 'value0'
output.put 'key1', 'value1'
output.put 'key2', 'value2'
It is setting an object reference that is never used to a variable and then setting another reference of a different map instance (created inside the service probably). The garbage collector is going to remove the first empty map, it is not a big performance issue but is easily avoidable.
To add the contents of the map, you would need to use putAll or the left shift operator <<.
I'd personally resent (I know; it's a strong word) re-assigning values to a variable. The following (ugly) pattern is one of the main roots of evil in your code:
def x = foo()
// do something with 'x'
...
x = bar()
// do something else with 'x'
This can easily make understanding the code very difficult and introduce bugs. You have to constantly keep an eye on x to make sure it contains the value it is supposed to! Really!
Just create another variable to hold the second value; there's absolutely nothing wrong with it --the days of 64KB of memory are long gone now.
def fooX = foo()
// do something with 'fooX'
...
def barX = bar()
// do something with 'barX'
This makes reading the code and understanding its behaviour, much easier.
Personally, when I write code that needs to re-assign to a variable, I quickly realise that there's something wrong with the way I'm organising my code. I do it ONLY on extremely rare occasions.