2016-04-28 3 views
0

У меня есть рекурсивная функция, которая принимает список событий и сортирует их по дате. Он отлично справился, но сегодня я получил сообщение о сбоях в консоли разработчика Google Play. Выбрасывается StackOverflowError.StackOverflowError при сортировке дат рекурсивно

Итак, мой вопрос: кто-то знает, почему это происходит и что делать, чтобы избежать этого?

Моя функция сортировки:

public class SortEventDates { 

    public List<Event> sortDates(List<Event> eventList) { 
     int a, b, c, d, e, f, g, h, ix, j; 

     // Sorting 
     for (int i = 0; i < eventList.size() - 1; i++) { 
      a = Integer.valueOf(eventList.get(i).getDate().split("/")[2]); // <--Row 18 
      b = Integer.valueOf(eventList.get(i+1).getDate().split("/")[2]); 
      // Sorting years 
      if (a > b) { 
       Collections.swap(eventList, i, i+1); 
       sortDates(eventList); 
      } else if (a == b) { 
       c = Integer.valueOf(eventList.get(i).getDate().split("/")[0]); 
       d = Integer.valueOf(eventList.get(i+1).getDate().split("/")[0]); 
       // Sorting months 
       if (c > d) { 
        Collections.swap(eventList, i, i+1); 
        sortDates(eventList); // <-- Row 30 
       } else if (c == d) { 
        e = Integer.valueOf(eventList.get(i).getDate().split("/")[1]); 
        f = Integer.valueOf(eventList.get(i+1).getDate().split("/")[1]); 
        // Sorting days 
        if (e > f) { 
         Collections.swap(eventList, i, i+1); 
         sortDates(eventList); // <-- Row 37 
        } else if (e == f) { 
         g = Integer.valueOf(eventList.get(i).getTime().split(":")[0]); 
         h = Integer.valueOf(eventList.get(i+1).getTime().split(":")[0]); 
         // Sorting hours 
         if (g > h) { 
          Collections.swap(eventList, i, i+1); 
          sortDates(eventList); 
         } else if (g == h) { 
          ix = Integer.valueOf(eventList.get(i).getTime().split(":")[1]); 
          j = Integer.valueOf(eventList.get(i+1).getTime().split(":")[1]); 
          // Sorting minutes 
          if (ix > j) { 
           Collections.swap(eventList, i, i+1); 
           sortDates(eventList); 
          } 
         } 
        } 
       } 
      } 
     } 
     return eventList; 
    } 
} 

Стек след:

java.lang.RuntimeException: An error occured while executing doInBackground() 
    at android.os.AsyncTask$3.done(AsyncTask.java:300) 
    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355) 
    at java.util.concurrent.FutureTask.setException(FutureTask.java:222) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:242) 
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
    at java.lang.Thread.run(Thread.java:841) 
Caused by: java.lang.StackOverflowError 
    at java.util.regex.Splitter.fastSplit(Splitter.java:46) 
    at java.lang.String.split(String.java:1842) 
    at java.lang.String.split(String.java:1824) 
    at app.android.arret.java.services.SortEventDates.sortDates(SortEventDates.java:18) 
    at app.android.arret.java.services.SortEventDates.sortDates(SortEventDates.java:37) 
    at app.android.arret.java.services.SortEventDates.sortDates(SortEventDates.java:37) 
    at app.android.arret.java.services.SortEventDates.sortDates(SortEventDates.java:37) 
    at app.android.arret.java.services.SortEventDates.sortDates(SortEventDates.java:30) 
    at app.android.arret.java.services.SortEventDates.sortDates(SortEventDates.java:37) 
    ... 
    ... 
    at app.android.arret.java.services.SortEventDates.sortDates(SortEventDates.java:30) 
    at app.android.arret.java.activity.DownloadJSON.doInBackground(DownloadJSON.java:119) 
    at app.android.arret.java.activity.DownloadJSON.doInBackground(DownloadJSON.java:24) 
    at android.os.AsyncTask$2.call(AsyncTask.java:288) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
+0

Измените модульное тестирование, чтобы содержать больше событий в EventList? – agilob

+0

Причина - ваша функция никогда не возвращалась и не становилась все глубже и глубже. Проверьте логику метода – Alexander

+0

Возможный дубликат [Метод сортировки по дате Java?] (Http://stackoverflow.com/questions/2786379/java-date-sorting-method) – jobbert

ответ

3

Вы знаете Java Comparables, верно?

Базовое использование:

public class Event implements Comparable<Event> { 

    private Date date; 

    public Event(Date date) { 
     this.date = date; 
     // Constructor 
    } 

    public Date getDate() { 
     return date; 
    } 

    @Override 
    public int compareTo(Event e) { 
     if (getDate() == null || e.getDate() == null) { 
      return 0; 
     } 
     return getDate().compareTo(e.getDate()); 
    } 
} 

И затем вызвать эту функцию, чтобы отсортировать список:

Collections.sort(eventList); 

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

Collections.sort(eventList, new Comparator<Event>() { 
    public int compare(Event e1, Event e2) { 
     if (e1.getDate() == null || e2.getDate() == null) { 
      return 0; 
     } 

     return e1.getDate().compareTo(e2.getDate()); 
    } 
}); 
1

Вы никогда не возвращаетесь к своим рекрутерным вызовам. В соответствии с трассировкой стека программы на вас вход т установить, как только вы рекурсивный вызов вашей функции он никогда не возвращает

if (c > d) { 
        Collections.swap(eventList, i, i+1); 
        sortDates(eventList); // <-- Row 30 
       } 

Эта функция будет вызываться бесконечно, и приведет к переполнению стека. Вам необходимо предоставить условие перезапуска из этих вызовов.

+0

Что вы имеете в виду? У меня есть оператор возврата в нижней части метода. Как только один if-statement будет ложным, он продолжит следующее событие, и в конце он вернет eventList. –

+0

. Я имею в виду, что на первой итерации вы меняете дату a и b в строке 29 и сопутствуете замене списка снова по строке 36 из-за их дней. Вы переинициализировали «i» на 0, таким образом, этот цикл продолжается бесконечно при замене a и b –

0

Вы также можете использовать Java 8 потоков для сортировки, как это:

Comparator<Event> sortByDate = new Comparator<Event>() { 
    public int compare(Event left, Event right) { 
     if (left.getDate().isBefore(right.getDate())) { 
      return -1; 
     } else { 
      return 1; 
     } 
    } 
}; 

Collections.sort(events, sortByDate); 
+0

. Вы фактически забыли случай, когда два 'события происходят в ту же дату, что возвращает' 0'. Если оставить это, это приведет к неопределенному перераспределению «Событий» с той же датой. Лучше использовать предоставленный метод '.compareTo();', поскольку он обрабатывает сравнение для вас, а не записывает ваши собственные. Кроме того, в вашем ответе нет использования 'stream'. –

Смежные вопросы