Как и где использовать итераторы

Как использовать итераторы

Итератор ячеек

Существует несколько способов получения итератора ячеек, и можно использовать любой из этих методов в зависимости от требований приложения. Ниже приведены методы, возвращающие итераторы ячеек.

  1. Cells.iterator
  2. Row.iterator
  3. Range.iterator

Все упомянутые выше методы возвращают итератор, который позволяет обойти коллекцию ячеек, которая была инициализирована.

Приведенный ниже пример кода демонстрирует реализацию класса Iterator для коллекции ячеек.

// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-Java
String dataDir = Utils.getDataDir(CellsIterator.class);
// Load a file in an instance of Workbook
Workbook book = new Workbook(dataDir + "sample.xlsx");
// Get the iterator from Cells collection
Iterator cellIterator = book.getWorksheets().get(0).getCells().iterator();
// Traverse cells in the collection
while (cellIterator.hasNext()) {
Cell cell = (Cell) cellIterator.next();
;
System.out.println(cell.getName() + " " + cell.getValue());
}
// Get iterator from an object of Row
Iterator rowIterator = book.getWorksheets().get(0).getCells().getRows().get(0).iterator();
// Traverse cells in the given row
while (rowIterator.hasNext()) {
Cell cell = (Cell) rowIterator.next();
System.out.println(cell.getName() + " " + cell.getValue());
}
// Get iterator from an object of Range
Iterator rangeIterator = book.getWorksheets().get(0).getCells().createRange("A1:B10").iterator();
// Traverse cells in the range
while (rangeIterator.hasNext()) {
Cell cell = (Cell) rangeIterator.next();
System.out.println(cell.getName() + " " + cell.getValue());
}
Итератор строк

Итератор строк может быть получен при использовании метода RowCollection.iterator. Приведенный ниже пример кода демонстрирует реализацию итератора для класса RowCollection.

// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-Java
String dataDir = Utils.getDataDir(RowsIterator.class);
// Load a file in an instance of Workbook
Workbook book = new Workbook(dataDir + "sample.xlsx");
// Get the iterator for RowCollection
Iterator rowsIterator = book.getWorksheets().get(0).getCells().getRows().iterator();
// Traverse rows in the collection
while (rowsIterator.hasNext()) {
Row row = (Row) rowsIterator.next();
System.out.println(row.getIndex());
}
Итератор столбцов

Итератор столбцов доступен при использовании метода ColumnCollection.iterator. Приведенный ниже пример кода демонстрирует реализацию итератора для класса ColumnCollection.

// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-Java
String dataDir = Utils.getDataDir(ColumnsIterator.class);
// Load a file in an instance of Workbook
Workbook book = new Workbook(dataDir + "sample.xlsx");
// Get the iterator for ColumnsCollection
Iterator colsIterator = book.getWorksheets().get(0).getCells().getColumns().iterator();
// Traverse columns in the collection
while (colsIterator.hasNext()) {
Column col = (Column) colsIterator.next();
System.out.println(col.getIndex());
}

Где использовать итераторы

Чтобы обсудить преимущества использования итераторов, давайте рассмотрим реальный пример.

Сценарий

Требуется пройти по всем ячейкам в данной таблице, чтобы прочитать их значения. Существует несколько способов реализации этой цели. Некоторые из них показаны ниже.

Использование диапазона отображения
// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-Java
String dataDir = Utils.getDataDir(UsingDisplayRange.class);
// Load a file in an instance of Workbook
Workbook book = new Workbook(dataDir + "sample.xlsx");
// Get Cells collection of first worksheet
Cells cells = book.getWorksheets().get(0).getCells();
// Get the MaxDisplayRange
Range displayRange = cells.getMaxDisplayRange();
// Loop over all cells in the MaxDisplayRange
for (int row = displayRange.getFirstRow(); row < displayRange.getRowCount(); row++) {
for (int col = displayRange.getFirstColumn(); col < displayRange.getColumnCount(); col++) {
// Read the Cell value
System.out.println(displayRange.get(row, col).getStringValue());
}
}
Использование MaxDataRow и MaxDataColumn
// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-Java
String dataDir = Utils.getDataDir(UsingMaxDataRowAndMaxDataColumn.class);
// Load a file in an instance of Workbook
Workbook book = new Workbook(dataDir + "sample.xlsx");
// Get Cells collection of first worksheet
Cells cells = book.getWorksheets().get(0).getCells();
// Loop over all cells
for (int row = 0; row < cells.getMaxDataRow(); row++) {
for (int col = 0; col < cells.getMaxDataColumn(); col++) {
// Read the Cell value
System.out.println(cells.get(row, col).getStringValue());
}
}

Как можно заметить, что оба вышеупомянутых подхода используют более или менее аналогичную логику, то есть проходят по всем ячейкам в коллекции для чтения значений ячеек. Это может быть проблематичным по ряду причин, как обсуждается далее.

  1. API, такие как MaxRow, MaxDataRow, MaxColumn, MaxDataColumn и MaxDisplayRange, требуют дополнительного времени для сбора соответствующей статистики. Если матрица данных (строки x столбцы) большая, использование этих API может повлечь штраф производительности.
  2. В большинстве случаев не все ячейки в заданном диапазоне созданы. В таких ситуациях проверка каждой ячейки в матрице не так эффективна, как проверка только инициализированных ячеек.
  3. Обращение к ячейке в цикле как Cells.get(rowIndex, columnIndex) приведет к созданию всех объектов ячеек в диапазоне, что в конечном итоге может вызвать ошибку OutOfMemoryError.
Заключение

На основе вышеприведенных фактов перечислены возможные сценарии, в которых следует использовать итераторы.

  1. Требуется только чтение коллекции ячеек, то есть требуется только проверка ячеек.
  2. Необходимо пройти большое количество ячеек.
  3. Необходимо обойти только инициализированные ячейки/строки/столбцы.