Sambhav Khandelwal
Sambhav Khandelwal

Reputation: 3765

Why does a nullable ArrayList give a Type Mismatch error when passing it a non-nullable ArrayList?

I am trying to pass a non-nullable ArrayList to a nullable ArrayList. But, it gives the type mismatch error:

enter image description here

Now, ignoring this, if I try to run my program, I get this issue:

enter image description here

So, how can I make this work? I also tried to make my non-nullable array list nullable, but it does not seem to work.

Upvotes: 0

Views: 373

Answers (2)

Mikhail Belyaev
Mikhail Belyaev

Reputation: 87

Unlike the accepted answer suggests, the problem is not in assigning ArrayList<T> to ArrayList<T?> per se, it lies in that ArrayList is invariant, meaning you cannot basically do anything interchangeable with ArrayList's of different types.

What this means is that while you can do this with List:

val list1: List<String> = listOf("hello")
val list2: List<String?> = list1 // perfectly fine

you cannot do the same with ArrayList

val list1: ArrayList<String> = arrayListOf("hello")
val list2: ArrayList<String?> = list1 // nope

This is intentional in Kotlin compiler because if you could do such things, the following code would be possible:

val list1: ArrayList<String> = arrayListOf("hello")
val list2: ArrayList<String?> = list1

list2.add(null) // 

list1.last() // returns null, but list1 cannot contain nulls!

This is a well known problem called "Heap pollution" that the compiler tries to prevent for you here. In general, any mutable data structure (and ArrayList is mutable) suffers from this problem.

Upvotes: 1

Mohamed Rejeb
Mohamed Rejeb

Reputation: 2629

Both arrayLists are non-nullable, the difference is that the first one accepts a nullable QuestionOptionAdd and the second one accepts a non-nullable QuestionOptionAdd, okay let's explain why you get this error:

Let's say that we have two arrayLists the first one accepts String? and the second one accepts String:

val firstArrayList: ArrayList<String?> = arrayListOf("1", null, "3", "4", null)
val secondArrayList: ArrayList<String> = arrayListOf("1", "2", "3", "4", "5")

Okay now let's try to change the first element of each array, we can change element from firstArrayList to null, but that's not the case for secondArrayList :

firstArrayList[0] = null
secondArrayList[0] = "0"

So when you move the elements of secondArrayList to firstArrayList, it causes that problem because secondArrayList elements can't be nullable and firstArrayList elements must be nullable.

So the solution for this problem is to clear firstArrayList and add to it all the elements of secondArrayList:

firstArrayList.clear()
firstArrayList.addAll(secondArrayList)

Upvotes: 1

Related Questions