Метод XSSFSheet removeRow(row) вызывает ConcurrentModificationException

Я пытаюсь прочитать файл xlsx. Я использую пои 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)

Спасибо.


person Naman Gala    schedule 04.11.2014    source источник
comment
Пожалуйста, добавьте трассировку стека   -  person Mirco    schedule 04.11.2014
comment
Пожалуйста, найдите мой обновленный вопрос   -  person Naman Gala    schedule 04.11.2014
comment
Затем у вас есть ответ, который вы пытаетесь удалить, пока перебираете коллекцию. Вы не можете этого сделать.   -  person Iootu    schedule 04.11.2014
comment
Тогда как я могу удалить его?   -  person Naman Gala    schedule 04.11.2014


Ответы (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

person Mirco    schedule 04.11.2014
comment
Спасибо, используя ваш код, он не выдает никаких исключений. Но у меня есть одна проблема: после повторения списка toRemove и вызова метода removeRow мой excel не обновляется. Мне нужно записать его обратно в то же место? - person Naman Gala; 04.11.2014
comment
Да, но убедитесь, что он не открыт и не используется другой программой. - person Mirco; 04.11.2014
comment
Спасибо за вашу помощь. Я принимаю ваш ответ. У меня есть только один вопрос: метод removeRow удаляет содержимое строки, но не удаляет строку. Поэтому я получаю пустую строку в excel. - person Naman Gala; 04.11.2014
comment
Вам нужно сместить оставшиеся ряды. См. stackoverflow.com/questions/24927438/. Но вам нужно сдвинуть их вверх в вашем случае - person Mirco; 04.11.2014
comment
У меня та же проблема, я пытался использовать метод iterator.remove внутри цикла, поэтому исключение concurrentmodification не выдается. Но функция удаления текущей строки не работает - person Akhil S Kamath; 17.11.2017