DataFrame implements Iterable<Column<?>> { @Override public Iterator<Column<?>> iterator() { return columns.iterator(); } private  DataFrame(Array<Column<?>> columns); private  DataFrame(Array<Column<?>> columns, Map<String, String> metaData); static DataFrame empty(); static DataFrame of(Column<?> column); static DataFrame ofAll(Column<?>... columns); static DataFrame ofAll(Iterable<? extends Column<?>> columns); int getRowCount(); int getColumnCount(); IndexedSeq<ColumnId> getColumnIds(); IndexedSeq<Column<?>> getColumns(); IndexedSeq<String> getColumnNames(); C getColumnId(int columnIndex, ColumnType<C> type); IntColumn getColumn(IntColumnId columnId); DoubleColumn getColumn(DoubleColumnId columnId); BooleanColumn getColumn(BooleanColumnId columnId); StringColumn getColumn(StringColumnId columnId); TimestampColumn getColumn(TimestampColumnId columnId); CategoryColumn getColumn(CategoryColumnId columnId); GenericColumn<V, I> getColumn(I columnId); Column<?> getColumn(ColumnId columnId); int getValueAt(int rowIndex, IntColumnId columnId); double getValueAt(int rowIndex, DoubleColumnId columnId); boolean getValueAt(int rowIndex, BooleanColumnId columnId); String getValueAt(int rowIndex, StringColumnId columnId); Instant getValueAt(int rowIndex, TimestampColumnId columnId); String getValueAt(int rowIndex, CategoryColumnId columnId); V getValueAt(int rowIndex, I columnId); @Override Iterator<Column<?>> iterator(); DataFrame withMetaData(Map<String, String> metaData); Map<String, String> getMetaData();  }
@Test public void iterator() { StringColumn stringColumn = StringColumn.builder(NAME).build(); IntColumn intColumn = IntColumn.builder(AGE).build(); Iterator<Column<?>> iterator = DataFrame.ofAll(stringColumn, intColumn).iterator(); assertTrue(iterator.hasNext()); iterator.next(); assertTrue(iterator.hasNext()); iterator.next(); assertFalse(iterator.hasNext()); }