2016-04-28 9 views
0

Ich habe eine rekursive Funktion, die eine Liste von Ereignissen nimmt und sie nach ihrem Datum sortiert. Es hat gut funktioniert, aber heute habe ich einen Absturzbericht auf der Google Play Developer Console erhalten. Ein StackOverflowError wird ausgelöst.StackOverflowError beim rekursiven Sortieren von Daten

Also, meine Frage ist, weiß jemand, warum das passiert und was zu tun, um es zu vermeiden?

Meine Sortierfunktion:

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; 
    } 
} 

Stapelüberwachung:

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

Ändern Sie bitte Ihre Unit-Test mehr Veranstaltungen in Eventlist enthalten? – agilob

+0

Ursache ist Ihre Funktion ist nie zurückgekehrt und tiefer und tiefer. Überprüfen Sie die Logik der Methode – Alexander

+0

Mögliche Duplikate von [Java Datum Sortiermethode?] (Http://stackoverflow.com/questions/2786379/java-date-sorting-method) – jobbert

Antwort

3

Sie kennen Java Comparables, nicht wahr?

Grund Nutzung:

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()); 
    } 
} 

Und dann diese Liste zu sortieren, rufen:

Collections.sort(eventList); 

Alternativ, wenn Sie wollen Ihr Modell nicht ändern, können Sie folgendes tun:

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

Sie kommen nie von Ihren reconsiven Anrufen zurück r Eingabe wird beim wiederholten Aufruf der Funktion gesetzt

Diese Funktion wird unendlich aufgerufen und führt zum Stapelüberlauf. Sie müssen eine erneute Bedingung für diese Anrufe angeben.

+0

Was meinst du? Ich habe eine Rückmeldung am Ende der Methode. Sobald eine if-Anweisung falsch ist, wird sie mit dem nächsten Ereignis fortgesetzt und am Ende wird die Ereignisliste zurückgegeben. –

+0

Was ich meine, ist, dass Sie in der ersten Iteration das Datum a und b in Zeile 29 tauschen und gemeinsam die Liste erneut austauschen in Zeile 36 wegen ihrer Tage. Du reinitialisierst "i" auf 0, also geht diese Schleife endlos weiter, indem du a und b vertauschst –

0

Sie können auch Java 8-Streams für die Sortierung wie folgt verwenden:

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

Du hast tatsächlich den Fall vergessen, in dem zwei "Event's am gleichen Datum passieren, die' 0' zurückgeben. Lässt man dies aus, würde dies zu einer unbestimmten Verschiebung von "Ereignissen" mit demselben Datum führen. Es ist besser, die mitgelieferte Methode '.compareTo();' zu verwenden, da sie den Vergleich für Sie übernimmt und nicht Ihren eigenen. Außerdem gibt es keine Verwendung von 'Streams' in Ihrer Antwort. –

Verwandte Themen