2016-04-28 10 views
0

私はイベントのリストを取り、その日付でソートする再帰関数を持っています。うまくいきましたが、今日はGoogleのデベロッパーコンソールでクラッシュレポートがあります。 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 Date sorting method?]の複製がありますか?(http://stackoverflow.com/questions/2786379/java-date-sorting-method) – jobbert

答えて

3

あなたは右、Java Comparablesを認識していますか?あなたのモデルを変更したくない場合は、次の操作を行うことができ

また
Collections.sort(eventList); 

、::

基本的な使用法:その後、

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

を返すことはありません、あなたの関数を呼び出した後、R入力が設定され、この関数が無限に呼び出され、スタックオーバーフローにつながるだろう。 これらの呼び出しから再呼び出し条件を指定する必要があります。

+0

どういう意味ですか?私はメソッドの最後にreturn文を持っています。すぐに1つのif文がfalseであれば、それは次のイベントを続行し、最後にeventListを返します。 –

+0

最初の繰り返しでは、29行目の日付aとbを入れ替えて、彼らの日々のために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

2つの「イベント」が同じ日付に発生するケースを実際に忘れてしまい、「0」を返します。それを残しておけば、同じ日付の「イベント」が無期限にシフトすることになります。与えられた '.compareTo();'メソッドは、自分で作成するのではなく、あなたのために比較を処理するので、それを使う方が良いでしょう。また、あなたの答えに 'stream'sの使用法はありません。 –

関連する問題