Reputation: 769
I wanted to check if an index
of an array
is empty/null, and if it's, then I wanted to add a new item at that index otherwise replace the old item with the new item (I do not want to keep the old item in the array).
I tried the following code but that didn't work
private var mSelectedImageFileUriList: ArrayList<Uri?>? = null
mSelectedImageFileUriList= ArrayList(5)
if (mSelectedImageFileUriList?.get(1) ===null){
mSelectedImageFileUriList?.add(data.data!!)
}else{
mSelectedImageFileUriList?.set(1,data.data!!)
}
mSelectedImageFileUriList?.add(data.data!!)
is the code I previously used and it worked without errors. Then I try with mSelectedImageFileUriList?.set(0,data.data!!)
, the app crashes. I am checking if the position (index) is null
because there are chances it's already occupied and if it's occupied then I do not want the old data in it, instead, I want to replace it with the new one (new one should be at the same position.
It's basically for creating an array of uri
. When the user wants to change the image, that is when I want to check if, at that index
, the user had already selected an image and if he has, then the old uri
must be removed and the new one should be added in the same position in the array
.
There are 5 images, the size of the array
is limited to 5 (mSelectedImageFileUriList= ArrayList(5)
). When a user adds 'image1' the uri
is stored at 'index0', and when he adds 'image2' the uri
is stored at 'index1'. After adding 'image2' ('index1'), the user wants to edit (change) the image he added for 'image1', if I use mSelectedImageFileUriList?.add(data.data!!)
it doesn't remove the old one and the new uri
is added at the bottom on the array but I want it to be at the same position, in this case, 'index0'. I hope it's clear.
I shall add the complete code if required.
logcat
Process: com.trad, PID: 21555
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=2, result=-1, data=Intent { dat=content://media/external/images/media/76207 flg=0x1 (has extras) }} to activity {com.trad/com.trad.ui.activities.AddProductActivity}: java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
at android.app.ActivityThread.deliverResults(ActivityThread.java:5506)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:5547)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2307)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8512)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
Caused by: java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
at java.util.ArrayList.set(ArrayList.java:453)
at com.trad.ui.activities.AddProductActivity.onActivityResult(AddProductActivity.kt:354)
at android.app.Activity.dispatchActivityResult(Activity.java:8541)
at android.app.ActivityThread.deliverResults(ActivityThread.java:5499)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:5547)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2307)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8512)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
2021-07-11 14:33:46.867 637-1917/? E/BufferQueueProducer: [Application Error: com.trad#0](id:27d00004287,api:0,p:-1,c:637) disconnect: not connected (req=1)
Upvotes: 1
Views: 4208
Reputation: 199
Use either .getOrNull()
:
if (mSelectedImageFileUriList.getOrNull(1) === null){
mSelectedImageFileUriList.add(data.data!!)
} else {
mSelectedImageFileUriList.set(1,data.data!!)
}
Or you could use .elementAtOrNull()
:
if (mSelectedImageFileUriList.elementAtOrNull(1) === null){
mSelectedImageFileUriList.add(data.data!!)
} else {
mSelectedImageFileUriList.set(1,data.data!!)
}
Upvotes: 0
Reputation: 28322
As others already said, you don't have to check whether the value is null or not, because in both cases you can simply do:
list[index] = value
Of in your case:
mSelectedImageFileUriList?.set(1, data.data!!)
This code does exactly what you ask: replaces existing value or "add" (actually, also replaces) if it is null.
But I think your problem is really somewhere else. You created your list with:
mSelectedImageFileUriList= ArrayList(5)
You probably assumed that it creates a list of size 5, but it does not. It creates a list with capacity
of 5, but it is still of 0 size. It does not create a list like this: [null, null, null, null, null]
, but just: []
, so you can't set the value for e.g. index=2.
To create a list of size 5 with nulls inside, use this code:
mSelectedImageFileUriList = MutableList(5) { null }
You will need to change the type of mSelectedImageFileUriList
from ArrayList
to MutableList
. This is actually the reason why it is discouraged to use specific implementation types for variable types.
Upvotes: 1
Reputation: 86
You've declared an ArrayList<Uri?>
which means that in your ArrayList
contains either a Uri
type or a null
type. A null
type still takes up a spot in the list, and isn't considered an "empty" space.
if (mSelectedImageFileUriList?.get(1) ===null){
mSelectedImageFileUriList?.add(data.data!!)
}else{
mSelectedImageFileUriList?.set(1,data.data!!)
}
With this in mind, your code snippet doesn't quite do what you say in the description. Your code here is saying if the element at index 1 is null, append data
to end of the list e.g. if your list was [URI1, null]
, then your list will become [URI1, null, data]
after execution.
It seems that either way (null
or old value) you are looking to replace the value at index 1, so you don't need to check if the value at index 1 is null
and could just have a one line setter:
mSelectedImageFileUriList?.set(1,data.data!!)
Upvotes: 0
Reputation: 23091
You don't need to check for null
. Since you always want to update that index, you can just set it directly.
For example:
fun main() {
val list = mutableListOf("zero","one",null)
println(list)
list[1] = "oneUpdated"
list[2] = "two"
println(list)
}
Output:
[zero, one, null]
[zero, oneUpdated, two]
Upvotes: 1