如何使用和何时使用迭代器
迭代器接口的对象可以用来遍历集合的所有元素。迭代器可以用来检查集合中的数据,但不能用来修改基础集合。一般来说,要使用迭代器循环遍历集合的内容,必须执行以下步骤:
- 通过调用集合的迭代器方法获取集合的起始迭代器。
- 建立一个循环,调用hasNext方法。让循环在hasNext方法返回true的时候迭代。
- 在循环内,通过调用next方法获取每个元素。
Aspose.Cells APIs提供了许多迭代器,但本文主要讨论以下三种类型。
- 单元格迭代器
- 行迭代器
- 列迭代器
如何使用迭代器
单元格迭代器
有各种方式可以访问单元格迭代器,根据应用程序的要求可以使用任何这些方法。以下是返回单元格迭代器的方法。
- Cells.iterator
- Row.iterator
- Range.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()); | |
} | |
} |
正如你所观察到的,上述两种方法使用的逻辑几乎相似,即循环遍历集合中的所有单元格以读取单元格的值。这可能会出现一些问题,如下所讨论的。
- MaxRow、MaxDataRow、MaxColumn、MaxDataColumn和MaxDisplayRange等API需要额外的时间来收集相应的统计信息。如果数据矩阵(行x列)很大,使用这些API可能会导致性能损失。
- 在大多数情况下,给定范围中并非所有单元格都被实例化。在这种情况下,检查矩阵中的每个单元格比仅检查初始化的单元格效率低。
- 在循环中访问单元格,如Cells.get(rowIndex, columnIndex)将导致范围中的所有单元格对象被实例化,这可能最终导致OutOfMemoryError。
结论
根据上述事实,以下是应使用迭代器的可能场景。
- 需要对单元格集合进行只读访问,即只需要检查单元格。
- 需要遍历大量单元格。
- 只需要遍历已初始化的单元格/行/列。