StackOverflow递归排序日期时出错



我有一个递归函数,它接受事件列表并按日期排序。它运行得很好,但今天我收到了一份关于Google play开发者控制台的崩溃报告。引发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)

您知道Java Compatibles,对吧?

基本用途:

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

你永远不会从递归调用中返回。根据输入集上程序的堆栈跟踪,一旦你递归调用函数,它就永远不会返回

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

此函数将被无限调用,并将导致堆栈溢出。您需要从这些调用中提供一个重新turn条件。

您也可以使用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);

最新更新