【问题标题】:XSSFSheet removeRow(row) method throws ConcurrentModificationExceptionXSSFSheet removeRow(row) 方法抛出 ConcurrentModificationException
【发布时间】:2014-11-04 16:43:03
【问题描述】:

我正在尝试读取 xlsx 文件。我正在使用 poi 3.10-FINAL。

我的代码是

FileInputStream fs = new FileInputStream("abc.xlsx");
XSSFWorkbook wb = new XSSFWorkbook(fs);
row_count = 0;

for (int k = 0; k < wb.getNumberOfSheets(); k++) {
    XSSFSheet sheet = wb.getSheetAt(k);
    if (sheet.getLastRowNum() > 0) {
        Iterator<Row> rowIterator = sheet.iterator();

        while (rowIterator.hasNext()) {
            Row row = rowIterator.next(); // throws ConcurrentModificationException
            if (row_count == 0) {
                col_count = row.getLastCellNum();
                //Do something
            } else {
                if (row.getCell(1).equals("XYZ")) {
                    sheet.removeRow(row);  //throws XmlValueDisconnectedException
                }
            }
            row_count++;
        }
    }
}

当我在没有sheet.removeRow(row) 的情况下执行我的代码时,它可以正常工作。但是当我添加 removeRow 调用时,它会引发 XmlValueDisconnectedException 异常。

谁能帮我解释一下为什么会出现这个异常。

更新:

我很惊讶,但现在我收到了ConcurrentModificationException 异常。一旦它执行 removeRow() 然后当它返回到 rowIterator.next() 时,它就会抛出异常。我已经在代码中提到了异常的位置。 堆栈跟踪是

java.util.ConcurrentModificationException
    at java.util.TreeMap$PrivateEntryIterator.nextEntry(Unknown Source)
    at java.util.TreeMap$ValueIterator.next(Unknown Source)
    at com.test.app.services.ExecuteImport.uploadFile(ExecuteImport.java:144)
    at com.test.app.controller.MyController.upload(MyController.java:271)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

谢谢。

【问题讨论】:

  • 请添加堆栈跟踪
  • 请找到我更新的问题
  • 那么您就有了答案,您在遍历集合时尝试删除。你不能那样做。
  • 那怎么删除呢?

标签: java apache-poi xlsx


【解决方案1】:

如果您在迭代时尝试使用迭代器删除一行,则会“混淆”迭代器。 这样做:

List<Row> toRemove = new ArrayList<Row>()
  while (rowIterator.hasNext()) {
            Row row = rowIterator.next(); // throws ConcurrentModificationException
            if (row_count == 0) {
                col_count = row.getLastCellNum();
                //Do something
            } else {
                if (row.getCell(1).equals("XYZ")) {
                  toRemove.add(row);
                }
            }
            row_count++;
        }
// loop the list and call sheet.removeRow() on every entry
    ...

另见http://docs.oracle.com/javase/7/docs/api/java/util/ConcurrentModificationException.html

【讨论】:

  • 谢谢,使用您的代码不会引发任何异常。但是我有一个问题,在迭代 toRemove 列表并调用 removeRow 方法后,我的 excel 没有得到更新。我需要将其写回相同的位置吗?
  • 可以,但要确保它没有被其他程序打开和使用。
  • 感谢您的帮助。我接受你的回答。我只有一个问题,removeRow 方法是删除行的内容,但不是删除行。所以我在 excel 中得到了空白行。
  • 您需要移动剩余的行。见stackoverflow.com/questions/24927438/…。但是你需要在你的情况下把它们调高
  • 我有同样的问题,我尝试在循环中使用 iterator.remove 方法,所以不会抛出并发修改异常。但是删除当前行的功能不起作用
猜你喜欢
  • 2013-02-12
  • 2013-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-25
  • 2017-10-18
相关资源
最近更新 更多