BigMick
BigMick

Reputation: 56

How to fix Fatal Exception: java.lang.IndexOutOfBoundsException Index: 0, Size: 1

Kotlin program snippet:

fun peek() = if (!elements.isEmpty() && elements.size > 0) elements[0] else null

It works great, but sometimes I get a firebase crash report:

Fatal Exception: java.lang.IndexOutOfBoundsException Index: 0, Size: 1 java.util.ArrayList.get (ArrayList.java:437) bigmick.ghu.util.Queue.peek (Queue.kt:17)

For me it sounds crazy: the list's size is 1, also the first (existing) element can be referred by index=0.

As far as I know it should work. But sometimes it does not.

Upvotes: 3

Views: 2099

Answers (1)

Joni
Joni

Reputation: 111229

The ArrayList class is not thread safe. When a thread makes a change at the same time another thread calls your method, unexpected and seemingly impossible things can happen.

A possible fix is to make it impossible for two threads to call methods of the list at the same time ("mutual exclusion"). This is easily achieved with Collections.synchronizedList

elements = Collections.synchronizedList(new ArrayList<>())

If you read elements from the list a lot more than you write, an alternative is to use CopyOnWriteArrayList instead of ArrayList

I see that you're using this code from a class called queue. In that case you may want to use an actual queue data structure instead of a list, and the standard library has many options you can choose from, depending on what behavior you want. See this question for example Choosing the best concurrency list in Java

Upvotes: 4

Related Questions