Как и где использовать итераторы
Объект интерфейса итератора можно использовать для обхода всех элементов коллекции. Итераторы можно использовать для проверки данных в коллекции, но их нельзя использовать для модификации базовой коллекции. В общем, чтобы использовать итератор для перебора содержимого коллекции, нужно выполнить следующие шаги:
- Получить итератор в начало коллекции, вызвав метод итератора коллекции.
- Настроить цикл, который делает вызов метода hasNext. Пусть цикл работает до тех пор, пока метод hasNext возвращает true.
- Внутри цикла получить каждый элемент, вызвав метод next.
API Aspose.Cells предоставляет множество итераторов, однако в этой статье главным образом обсуждаются три типа, перечисленных ниже.
- Итератор ячеек
- Итератор строк
- Итератор столбцов
Как использовать итераторы
Итератор ячеек
Существует несколько способов получения итератора ячеек, и можно использовать любой из этих методов в зависимости от требований приложения. Ниже приведены методы, возвращающие итераторы ячеек.
- Cells.iterator
- Row.iterator
- 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()); | |
} | |
} |
Как можно заметить, что оба вышеупомянутых подхода используют более или менее аналогичную логику, то есть проходят по всем ячейкам в коллекции для чтения значений ячеек. Это может быть проблематичным по ряду причин, как обсуждается далее.
- API, такие как MaxRow, MaxDataRow, MaxColumn, MaxDataColumn и MaxDisplayRange, требуют дополнительного времени для сбора соответствующей статистики. Если матрица данных (строки x столбцы) большая, использование этих API может повлечь штраф производительности.
- В большинстве случаев не все ячейки в заданном диапазоне созданы. В таких ситуациях проверка каждой ячейки в матрице не так эффективна, как проверка только инициализированных ячеек.
- Обращение к ячейке в цикле как Cells.get(rowIndex, columnIndex) приведет к созданию всех объектов ячеек в диапазоне, что в конечном итоге может вызвать ошибку OutOfMemoryError.
Заключение
На основе вышеприведенных фактов перечислены возможные сценарии, в которых следует использовать итераторы.
- Требуется только чтение коллекции ячеек, то есть требуется только проверка ячеек.
- Необходимо пройти большое количество ячеек.
- Необходимо обойти только инициализированные ячейки/строки/столбцы.