带有迭代器hasNext()和next()的无限while循环



我正在做一个Java项目,该项目使用Apache POI来操作.docx文件。两天前,我遇到了一个问题,但我无法解决。我真的不知道我的错误在哪里,是什么原因造成的。我唯一知道的是,这个bug在做什么。

两天前,一切都很好。我选择了我的.docx,点击了单选按钮,这些按钮定义了要执行的更改,然后我点击了"提交"按钮开始了这项工作。它的工作原理是这样的:使用Apache POI方法从.docx中获取所有文本,在每次Run中迭代,更改关键字和语法,并将更新后的Paragraph及其Run放回文档中。对于第二个单选按钮的更改,重复该过程。最后,经过两个单选按钮的更改后,文档的文件名中会有一个后缀。如果我现在选择一个特殊的单选按钮,操作将成功地贯穿整个文档。但是,在第二次运行(由第二个单选按钮定义)的操作过程中,执行似乎在特定点冻结,因为Eclipse控制台没有显示任何更改。事实上,如果我终止应用程序,并查看生成的文档,我会看到,同一段文本被反复粘贴到文档中。这份文件大约有11页长。这种错误的粘贴在几秒钟内增加了330多页。这让我想到,一定存在一个无限的循环。其他任何事情对我来说都没有多大意义。

奇怪的是,我从来没有改变过那个算法上的任何东西(我想)。我做的最后一件事是将我的Java版本更新到8u45,但由于我回滚到以前的版本,并且错误仍然存在,所以我看起来更新不会以某种方式导致错误。

我希望你们中的一个人能给我一些建议。我不认为,在这里发布我的代码是有用的,因为它几乎是其他方法的完整副本,效果很好,但我无论如何都会这么做。这种代码的平静是我使用while循环的唯一部分(在选择了bug单选按钮之后)。所有其他循环都用于循环。让我困惑的是:

  • 第一个单选按钮(有缺陷的按钮)在做什么,以便以下更改的执行以无限循环结束
  • 如果它是一个中缀循环,它是如何在我的文档中写入的?正如您所看到的,我只在离开while循环时将内容写入文档。当我在Eclipse中手动终止它时,文档中不应该有任何文本。

    public static void changeSingleMaleToMultiMale(String path, String title, XWPFDocument document) throws Exception
    {
    XWPFDocument oldDoc = document;
    Iterator<XWPFParagraph> iterator = document.getParagraphsIterator();
    int length = title.length();
    int counter = 0;
    while(iterator.hasNext())
    {
    XWPFParagraph paragraph = iterator.next();              
    System.out.println("____ unchangedn" + paragraph.getText() + "n____nn");
    List<XWPFRun> runs = paragraph.getRuns();
    
    for(int i = 0; i < runs.size(); i++)
    {
    String text = runs.get(i).toString();
    
    if(text.contains(title))
    {
    runs.get(i).setText(StringFunctions.fromSingleMaleToMultiMale(text, title, length), 0); 
    }   
    }
    System.out.println("____ updatedn" + paragraph.getText() + "n____nn");
    document.setParagraph(paragraph, counter);
    counter++;
    }
    try {
    FileOutputStream output = new FileOutputStream(path.substring(0, path.length()-5) + "Aktualisiert.docx");
    document.write(output);
    output.close();
    } catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    

有人经历过类似的事情吗?如果能给我一个小小的提示来解决这个问题,我会很高兴的。

UPDATE:通过选择上面提到的单选按钮调用的错误代码不会影响其他单选按钮所调用的方法。只是看起来像这样。事实上,代码的bug般的平静将如此巨大的文本写入到我的变量中,在这一点上,我认为,输出流仍然忙于将如此庞大的文本写入我的文档,而下面的方法正在尝试访问文档。到目前为止,这回答了上面列表中的第一个问题。另一个问题和问题仍然悬而未决。

几天前我找到了解决方案。

没有无限循环,即使它看起来像这样,因为同一段文本被粘贴到我的文档中数千次。

经过一段时间的绝望,我试图找出为什么我的循环不能正确工作,我决定吞下苦果,一步一步地找出错误的原因。

因此,我将大部分代码放入注释中,并逐步取消对每段代码的注释。我发现,循环被正确地实现了,错误被隐藏在一个方法中,这有助于替换文档中的一些文本。

我得到了这样的东西:

String checkString = "";

作为变量的简单初始值。

在某些特殊情况下,"checkString"会得到一个String,在其他一些情况下,它应该保留为空String。

错误发生在处理第二个案例时。我有一个if子句,它是这样定义的:

if(baseString.contains(checkString))

你看到这里了吗,如果"checkString"是一个空字符串,会发生什么?是的,当然,在任何情况下,"baseString"都包含"。如果条款是真的,每次都是。if子句中的其他行做了一些工作,这导致了看起来像是无限粘贴文本。

if(checkString != "" && baseString.contains(checkString))

修复了所有问题。

错误的表现方式让我思考,错误无处不在,但不是在那种方法中。有趣的是,那些简单的虫子让我如此疯狂。

最新更新