Я сталкиваюсь с ArrayIndexOutOfBoundsException при сортировке. мой код здесь:

Collections.sort(mutualFriends, new Comparator<FriendInfo>() {
   public int compare(FriendInfo s1, FriendInfo s2) {
       return s1.name.compareToIgnoreCase(s2.name);
   }
});

Журналы здесь:

    STACK_TRACE=java.lang.ArrayIndexOutOfBoundsException
    at java.util.Collections.sort(Collections.java:1970)
    at com.platinumapps.fragments.Mutual_Friends_Fragment$1.onComplete(Mutual_Friends_Fragment.java:138) 
    at com.platinumapps.facedroid.AsyncRequestListener.onComplete(AsyncRequestListener.java:59) 
    at com.facebook.android.AsyncFacebookRunner$2.run(AsyncFacebookRunner.java:328)

А мой общий список друзей такой:

private List<FriendInfo> mutualFriends = new ArrayList<FriendInfo>();

Любая идея исправить эту проблему. Заранее спасибо.

-3
Mohammad Imran 16 Янв 2013 в 11:21
1
Список mutualFriends пуст?
 – 
Shashank Kadne
16 Янв 2013 в 11:23
В вашем вопросе недостаточно кода, потому что исключение выбрасывается в другое место.
 – 
Andremoniy
16 Янв 2013 в 11:23
Что происходит в этом Mutual_Friends_Fragment.java:138
 – 
Faizan
16 Янв 2013 в 11:25
3
Моя интуиция подсказывает мне, что в вашем коде присутствует некоторая гонка данных . Изменяет ли какой-то поток mutualFriends одновременно во время сортировки? (Или, другими словами: есть ли у вас какие-либо многопоточные задания в коде, который имеет дело с этим списком)?
 – 
amit
16 Янв 2013 в 11:29
1
Я согласен с @amit, хотя я бы назвал это одновременной модификацией вместо гонки данных . Единственный способ Collections.sort вызвать подобное исключение - это если какой-то другой код вытащит почву из-под него. Если у вас есть несколько потоков, обращающихся к mutualFriends, вам необходимо синхронизировать доступ.
 – 
Ted Hopp
16 Янв 2013 в 11:33

1 ответ

Лучший ответ

Скорее всего, здесь у вас гонка за данными .

Другой поток пытается изменить список во время его сортировки (или доступа) - и вы получаете состояние гонки, которое в вашем случае вызывает IndexOutOfBoundsException.

Трудно понять, в чем именно заключается проблема, но есть несколько общих способов ее решения:

  1. Убедитесь, что ваш код потокобезопасен. Это легко сделать с помощью synchronized ing на ArrayList объект везде, где это есть быть использованным -
  2. Используйте класс, предназначенный для обеспечения безопасности потоков.

Распространенная ошибка, которая может быть проблемой в вашем случае, - это порождение потоков, а не ожидание, пока они закончат свою работу перед сортировкой. Это можно решить, просто вызвав join() во всех потоках, прежде чем предполагать, что они завершены - это гарантирует, что вы не продолжите, пока все потоки не будут завершены.

5
amit 16 Янв 2013 в 11:39
Вы имеете в виду, если я напишу приватную синхронизацию List relativeFriends = new ArrayList (); это решит вопрос ????
 – 
Mohammad Imran
16 Янв 2013 в 12:20
@MohammadImran: Нет, он даже не компилируется. Я подозреваю, что написание synchronized(mutualFriends) перед каждой точкой использования списка решит проблему (хотя и с очень плохой производительностью), но, как я также сказал, без дополнительного кода нельзя быть уверенным.
 – 
amit
16 Янв 2013 в 12:23
В основном после синтаксического анализа JSon я сортирую список, а затем обновляю пользовательский интерфейс. Думаю, это снизит производительность, может возникнуть ANR. было бы лучше использовать asynTask вместо синхронизированного блока ????
 – 
Mohammad Imran
16 Янв 2013 в 13:52