【问题标题】:String operation in recursive function causing stackoverflow递归函数中的字符串操作导致stackoverflow
【发布时间】:2014-06-26 13:41:57
【问题描述】:

我正在构建经过一百万行左右的递归函数,我在执行期间从该函数中获取了 stackOverFlow。

protected String[] getConnectedCities(String line) {
    return line.trim().toLowerCase().replace(DELIMITER + " ", DELIMITER)
            .split(DELIMITER);
}

这是完整的代码:

    protected final Map<String, City> processLine(
        final Map<String, City> dataMap) {
    try {
        String line = "";
        if ((line = bReader.readLine()) == null) {
            return dataMap;
        }
        // Check if direct relation can be found
        String connectedCities[] = parseLine(line);
        line = null;
        saveConnection(dataMap, connectedCities);

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return processLine(dataMap);
}

我不确定我做错了什么,我认为它与 String 行有关,但不太确定它是什么。

谢谢。

【问题讨论】:

  • 如果这是递归一百万级,那么最终不会意外导致堆栈溢出,将需要非常大的堆栈内存区域来处理。您真的是要使用递归,而不是在循环中一次读取文件行并处理每一行吗?
  • 感谢 dethorpe 的回复,我在考虑减少 log n 的处理时间,否则处理整个文件需要很长时间。
  • 我怀疑像这样递归会比简单地循环文件更快。也许可以尝试读取更大的文件块然后循环遍历它们,可以使用多个线程并行处理这些块。
  • 其实问题不在读取文件,我使用MappedBufferByte将文件加载到内存中。我的主要问题是如何以更有效的方式处理它。文件大约是 200 MB 的一行一行,每行两个单词用“,”分隔

标签: java stack-overflow


【解决方案1】:

您做的最后一件事是再次调用 processLine。这将具有与文件中的行一样多的回避级别,直到上面的 return 语句退出。这在技术上是尾递归,但 Java 可能不理解。

【讨论】:

  • 感谢您的回答 Arkediy,我主要关心的是尽量减少文件的处理时间。我想我需要更多地重构代码。
猜你喜欢
  • 2019-05-11
  • 2012-10-10
  • 1970-01-01
  • 1970-01-01
  • 2013-04-24
  • 2011-04-01
  • 1970-01-01
  • 2019-12-15
  • 1970-01-01
相关资源
最近更新 更多