0

I have a list of time slots of an hour each and a list of slot bookings stored in Firestore for the same day. I now need to show availability of free slots to the user. So I am running the below code. It works fine if there is only one slot in a day, and it is booked. But it crashes with an index out of bounds error if there are more slots in a day and one of them is booked. Have spent multiple hours on this tried iterators and dont know why this is happening. Any solutions please?

Please note: i have looked at the below link, didnt work in my case:

Iterating through a Collection, avoiding ConcurrentModificationException when removing objects in a loop

 val existingBookingsList: List<Booking> = it.toObjects(Booking::class.java)

            val newAvailableList: MutableList<String> = listOfAvailableSlots

            for (booking in existingBookingsList) {
                //change availability of the time slots
                val endTimeOfAppointment = createTime(booking.getstartTime()!!)
                //add duration to time stored in Minutes
                servDuration = booking.getduration()!!.toInt()
                if (servDuration == 0) {
                    durhrs = 0
                    durmins = 0
                } else if (servDuration < 60) {
                    durmins = servDuration
                    durhrs = 0
                } else {
                    val hrs: Int = servDuration / 60
                    val mins = servDuration - (hrs * 60)
                    durhrs = hrs
                    durmins = mins
                }
                endTimeOfAppointment.add(Calendar.HOUR_OF_DAY, durhrs)
                endTimeOfAppointment.add(Calendar.MINUTE, durmins)

//Above is getting the endTime for each slot that has been booked for a particular date

//below is looping the end time over the slots that can be booked to identify and remove the overlap

//Error occurs on this line val hour = listOfAvailableSlots[j] - Index out of bounds index 2 and size is 1

                for (j in 0 until listOfAvailableSlots.size) {
                    val hour = listOfAvailableSlots[j]
                    val endTime = createTime(hour)
                    if (endTimeOfAppointment.compareTo(endTime) >= 0) {
                        newAvailableList.removeAt(j)
                    }
                }

            }
madhall
  • 162
  • 1
  • 13

1 Answers1

2

there are several problems in the code.

At the line val newAvailableList: MutableList<String> = listOfAvailableSlots you are not initializing a new list containing the values of listOfAvailableSlots. You are assigning the pointer of listOfAvailableSlots to newAvailableList so every action you perform on newAvailableList is reflected to listOfAvailableSlots. The easiest way to copy a list to another variable is using .toMutableList(). It works even if the source list is already mutable. val newAvailableList: MutableList<String> = listOfAvailableSlots.toMutableList()

The code below can be modified

for (j in 0 until listOfAvailableSlots.size) {
    val hour = listOfAvailableSlots[j]
    val endTime = createTime(hour)
    if (endTimeOfAppointment.compareTo(endTime) >= 0) {
        newAvailableList.removeAt(j)
    }
}

to this

for(availableSlot in listOfAvailableSlot) {
    val endTime = createTime(availableSlot)
    if(endTimeOfAppointment.compareTo(endTime) >= 0) {    //consider to use greaterThan or lessThan
        newAvailableList.remove(availableSlot)
    }
}

which is safer than the previous.

In the same way you can use the filter function:

newAvailableList.filter { endTimeOfAppointment.compareTo(createTime(it) >= 0) }

Try to clean your code and let us know if you solved the problem

Luke
  • 516
  • 2
  • 10
  • 1
    In programming in general, we always need to have into account this sort of stuff regarding memory and pointers. It really helps to understand a little further how memory works. That way you can spot these kind of errors (and some even worse) for yourself and it really pays off. – Nyck Jan 20 '22 at 20:05