【问题标题】:Merge sort java.lang.StackOverflowError合并排序 java.lang.StackOverflowError
【发布时间】:2016-02-12 04:41:37
【问题描述】:

我正在为学校做一个项目,事情进展顺利,直到我尝试对我的 ArrayList 执行合并排序。
它会运行,但随后会出错。许多人的第一个错误是Exception in thread "main" java.lang.StackOverflowError。 我查看了代码,无法找出错误发生的原因。 它确实给了我一个位置(line 74:first_half = mergeSort(first_half);),但我没有看到问题。

public static void main(String[] args) throws IOException {

    // URL url = new
    // URL("https://www.cs.uoregon.edu/Classes/15F/cis212/assignments/phonebook.txt");
    FileReader fileReader = new FileReader("TestSort.txt");
    BufferedReader bufferReader = new BufferedReader(fileReader);
    String entry = bufferReader.readLine();

    // Scanner s = new Scanner(url.openStream());

//      int count = 0;

    while (entry != null) {

        // String person = s.nextLine();
        String phoneNum = entry.substring(0, 7);
        String name = entry.substring(9);
        PhonebookEntry newentry = new PhonebookEntry(name, phoneNum);
        phoneBook.add(newentry);
        entry = bufferReader.readLine();
    }
    // ********************Selection
    // Sort*************************************
    ArrayList<PhonebookEntry> sortList = new ArrayList<PhonebookEntry>(phoneBook);

    for (int min = 0; min < sortList.size(); min++) {

        for (int i = min; i < sortList.size(); i++) {
            int res = sortList.get(min).getName().compareTo(sortList.get(i).getName());

            if (res > 0) {
                PhonebookEntry temp = sortList.get(i);
                sortList.set(i, sortList.get(min));
                sortList.set(min, temp);

            }

        }

    }
    for (PhonebookEntry sortentry : sortList) {
        System.out.println(sortentry);
    }


    System.out.println(mergeSort(mergeSortList));

}


// *****************************merge sort******************************************
static int mergecounter = 0;
static ArrayList<PhonebookEntry> mergeSortList = new ArrayList<PhonebookEntry>(appMain.phoneBook);

public static ArrayList<PhonebookEntry> mergeSort(ArrayList<PhonebookEntry> mergeSortLists) {
    if (mergeSortLists.size() == 1) {
        return mergeSortLists;
    }
    int firstHalf = mergeSortLists.size() % 2 == 0 ? mergeSortLists.size() / 2 : mergeSortLists.size() / 2 + 1;

    ArrayList<PhonebookEntry> first_half = new ArrayList<PhonebookEntry>(mergeSortLists.subList(0, firstHalf));
    ArrayList<PhonebookEntry> mergeSortHalf2 = new ArrayList<PhonebookEntry>(
    mergeSortLists.subList(first_half.size(), mergeSortLists.size()));

    System.out.println(++mergecounter);

    first_half = mergeSort(first_half);
    mergeSortHalf2 = mergeSort(mergeSortHalf2);
    return merge(first_half, mergeSortHalf2);
}

public static ArrayList<PhonebookEntry> merge(ArrayList<PhonebookEntry> first_half,
        ArrayList<PhonebookEntry> mergeSortHalf2) {
    ArrayList<PhonebookEntry> returnMerge = new ArrayList<PhonebookEntry>();

    while (first_half.size() > 0 && mergeSortHalf2.size() > 0) {
        if (first_half.get(0).getName().compareTo(mergeSortHalf2.get(0).getName()) > 0) {
            returnMerge.add(mergeSortHalf2.get(0));
            mergeSortHalf2.remove(0);
        }

        else {
            returnMerge.add(first_half.get(0));
            first_half.remove(first_half.get(0));
        }
    }

    while (first_half.size() > 0) {
        returnMerge.add(first_half.get(0));
        first_half.remove(first_half.get(0));

    }
    while (mergeSortHalf2.size() > 0) {
        returnMerge.add(mergeSortHalf2.get(0));
        mergeSortHalf2.remove(mergeSortHalf2.get(0));
    }
    return returnMerge;
}

}

【问题讨论】:

    标签: java sorting arraylist merge stack-overflow


    【解决方案1】:

    我认为代码没有错误。
    怎么确定?

    我在我的环境中运行了你的代码,它的执行没有任何错误。

    使用我在https://www.cs.uoregon.edu/Classes/15F/cis212/assignments/phonebook.txt 找到的文本文件作为输入 并为PhonebookEntry做了一个简单的实现

    那为什么会出现这个错误?

    首先尝试理解错误,我的意思是为什么会出现StackOverflowError。因为有很多我不打算解释这个 但是请阅读这两个线程的最佳答案,我相信您会知道为什么会发生这种情况。

    Thread 1: What is a StackOverflowError?
    Thread 2: What actually causes a Stack Overflow error?

    如果您阅读了这些内容,希望您能理解摘要是You Ran Out Of Memory

    那为什么我没有收到那个错误:可能的原因是

    在我的环境中,我将 jvm 配置为以 1024m 到 1556m 的更高内存运行(作为 eclipse 参数)

    现在让我们用解决方案分析您的案例:

    1. 输入:你有很大的输入(50,000)

      要检查您的代码,请尝试缩短输入并进行测试。

    2. 您已经在这个大输入上以单一方法执行了两个算法: 当一个方法执行时,它的所有变量都留在内存中,直到它完成执行。 因此,当您调用合并排序时,所有以前的用户变量和其他变量都会留在内存中,这可能会导致这种情况

      现在如果你使用分离的方法并从主方法中调用它们,比如编写一个选择排序的方法,它所有使用的变量都将超出范围 并且在选择排序结束后可能是免费的(如果 GC 收集它们)。

      所以写了两个分离的方法来读取输入文件和选择排序。 close()FileReaderBufferedReader

    3. 摆脱那些静态方法。使它们成为类的非静态创建和对象,并从主方法调用它们

    一切都与代码优化有关

    你也可以增加 jvm 的内存,并在命令行中破坏应用程序时像这样java -Xmx1556m -Xms1024m 进行测试

    顺便说一句,感谢您提出这个问题,它让我有一些思考

    【讨论】:

    • 谢谢。这有很大帮助。问题出在我的电话上。如果某些东西== 0,我正在使用递归进行检查,但它始终为0,因为它从未通过原始数组列表。修复了代码,它现在可以工作了。你帮我找到了问题。
    • 很高兴知道它现在解决了:)。虽然我可以提供任何具体的帮助。
    猜你喜欢
    • 1970-01-01
    • 2019-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-14
    • 2011-03-23
    相关资源
    最近更新 更多