com.landawn.abacus.util.Sheet Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of abacus-android Show documentation
Show all versions of abacus-android Show documentation
A general and simple library for Android
/*
* Copyright (c) 2015, Haiyang Li.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.landawn.abacus.util;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import com.landawn.abacus.DataSet;
import com.landawn.abacus.core.RowDataSet;
import com.landawn.abacus.exception.UncheckedIOException;
import com.landawn.abacus.parser.KryoParser;
import com.landawn.abacus.parser.ParserFactory;
import com.landawn.abacus.util.function.IntFunction;
import com.landawn.abacus.util.stream.IntStream;
import com.landawn.abacus.util.stream.ObjIteratorEx;
import com.landawn.abacus.util.stream.Stream;
/**
*
* {@code R} = Row, {@code C} = Column, {@code H} = Horizontal, {@code V} = Vertical.
*
*
* @since 0.8
*
* @author Haiyang Li
*/
public final class Sheet implements Cloneable {
private static final KryoParser kryoParser = ParserFactory.isKryoAvailable() ? ParserFactory.createKryoParser() : null;
private final Set _rowKeySet;
private final Set _columnKeySet;
private BiMap _rowKeyIndexMap;
private BiMap _columnKeyIndexMap;
private List> _columnList;
private boolean _initialized = false;
private boolean _isFrozen = false;
public Sheet() {
this(N.EMPTY_LIST, N.EMPTY_LIST);
}
public Sheet(Collection rowKeySet, Collection columnKeySet) {
this._rowKeySet = N.newLinkedHashSet(rowKeySet);
this._columnKeySet = N.newLinkedHashSet(columnKeySet);
}
public Sheet(Collection rowKeySet, Collection columnKeySet, Object[][] rows) {
this(rowKeySet, columnKeySet);
final int rowLength = this.rowLength();
final int columnLength = this.columnLength();
if (N.notNullOrEmpty(rows)) {
N.checkArgument(rows.length == rowLength, "The length of array is not equal to size of row/column key set");
for (Object[] e : rows) {
N.checkArgument(e.length == columnLength, "The length of array is not equal to size of row/column key set");
}
initIndexMap();
_columnList = new ArrayList<>(columnLength);
for (int i = 0; i < columnLength; i++) {
final List column = new ArrayList<>(rowLength);
for (int j = 0; j < rowLength; j++) {
column.add((E) rows[j][i]);
}
_columnList.add(column);
}
_initialized = true;
}
}
public static Sheet rows(Collection rowKeySet, Collection columnKeySet, Object[][] rows) {
return new Sheet<>(rowKeySet, columnKeySet, rows);
}
public static Sheet rows(Collection rowKeySet, Collection columnKeySet, Collection extends Collection extends E>> rows) {
final Sheet instance = new Sheet<>(rowKeySet, columnKeySet);
final int rowLength = instance.rowLength();
final int columnLength = instance.columnLength();
if (N.notNullOrEmpty(rows)) {
N.checkArgument(rows.size() == rowLength, "The size of collection is not equal to size of row/column key set");
for (Collection extends E> e : rows) {
N.checkArgument(e.size() == columnLength, "The size of collection is not equal to size of row/column key set");
}
instance.initIndexMap();
instance._columnList = new ArrayList<>(columnLength);
for (int i = 0; i < columnLength; i++) {
instance._columnList.add(new ArrayList(rowLength));
}
for (Collection extends E> row : rows) {
final Iterator extends E> iter = row.iterator();
for (int i = 0; i < columnLength; i++) {
instance._columnList.get(i).add(iter.next());
}
}
instance._initialized = true;
}
return instance;
}
public static Sheet columns(Collection rowKeySet, Collection columnKeySet, Object[][] columns) {
final Sheet instance = new Sheet<>(rowKeySet, columnKeySet);
final int rowLength = instance.rowLength();
final int columnLength = instance.columnLength();
if (N.notNullOrEmpty(columns)) {
N.checkArgument(columns.length == columnLength, "The length of array is not equal to size of row/column key set");
for (Object[] e : columns) {
N.checkArgument(e.length == rowLength, "The length of array is not equal to size of row/column key set");
}
instance.initIndexMap();
instance._columnList = new ArrayList<>(columnLength);
for (Object[] column : columns) {
instance._columnList.add(new ArrayList<>((List) Arrays.asList(column)));
}
instance._initialized = true;
}
return instance;
}
public static Sheet columns(Collection rowKeySet, Collection columnKeySet, Collection extends Collection extends E>> columns) {
final Sheet instance = new Sheet<>(rowKeySet, columnKeySet);
final int rowLength = instance.rowLength();
final int columnLength = instance.columnLength();
if (N.notNullOrEmpty(columns)) {
N.checkArgument(columns.size() == columnLength, "The size of collection is not equal to size of row/column key set");
for (Collection extends E> e : columns) {
N.checkArgument(e.size() == rowLength, "The size of collection is not equal to size of row/column key set");
}
instance.initIndexMap();
instance._columnList = new ArrayList<>(columnLength);
for (Collection extends E> column : columns) {
instance._columnList.add(new ArrayList<>(column));
}
instance._initialized = true;
}
return instance;
}
public Set rowKeySet() {
return _rowKeySet;
}
public Set columnKeySet() {
return _columnKeySet;
}
public E get(Object rowKey, Object columnKey) {
if (_initialized) {
final int rowIndex = getRowIndex(rowKey);
final int columnIndex = getColumnIndex(columnKey);
return get(rowIndex, columnIndex);
} else {
checkRowKey(rowKey);
checkColumnKey(columnKey);
return null;
}
}
/**
*
* @param rowIndex
* @param columnIndex
* @return
*/
public E get(int rowIndex, int columnIndex) {
if (_initialized) {
return _columnList.get(columnIndex).get(rowIndex);
} else {
checkRowIndex(rowIndex);
checkColumnIndex(columnIndex);
return null;
}
}
public E get(IntPair point) {
return get(point._1, point._2);
}
/**
*
* @param rowKey
* @param columnKey
* @param value
* @return
* @throws IllegalArgumentException
*/
public E put(R rowKey, C columnKey, E value) throws IllegalArgumentException {
checkFrozen();
init();
// if (!containsRow(rowKey)) {
// addRow(rowKey, null);
// }
//
// if (!containsColumn(columnKey)) {
// addColumn(columnKey, null);
// }
final int rowIndex = getRowIndex(rowKey);
final int columnIndex = getColumnIndex(columnKey);
return put(rowIndex, columnIndex, value);
}
public E put(int rowIndex, int columnIndex, E value) {
checkFrozen();
init();
final Object previousValue = _columnList.get(columnIndex).get(rowIndex);
_columnList.get(columnIndex).set(rowIndex, value);
return (E) previousValue;
}
public E put(IntPair point, E value) {
return put(point._1, point._2, value);
}
/**
*
* @param source
* @throws IllegalArgumentException
*/
public void putAll(Sheet extends R, ? extends C, ? extends E> source) throws IllegalArgumentException {
checkFrozen();
if (!this.rowKeySet().containsAll(source.rowKeySet())) {
throw new IllegalArgumentException(source.rowKeySet() + " are not all included in this sheet with row key set: " + this.rowKeySet());
}
if (!this.columnKeySet().containsAll(source.columnKeySet())) {
throw new IllegalArgumentException(source.columnKeySet() + " are not all included in this sheet with column key set: " + this.columnKeySet());
}
final Sheet tmp = (Sheet) source;
for (R r : tmp.rowKeySet()) {
for (C c : tmp.columnKeySet()) {
// this.put(r, c, tmp.get(r, c));
put(getRowIndex(r), getColumnIndex(c), tmp.get(r, c));
}
}
}
public E remove(Object rowKey, Object columnKey) {
checkFrozen();
if (_initialized) {
final int rowIndex = getRowIndex(rowKey);
final int columnIndex = getColumnIndex(columnKey);
return remove(rowIndex, columnIndex);
} else {
checkRowKey(rowKey);
checkColumnKey(columnKey);
return null;
}
}
public E remove(int rowIndex, int columnIndex) {
checkFrozen();
if (_initialized) {
return _columnList.get(columnIndex).set(rowIndex, null);
} else {
checkRowIndex(rowIndex);
checkColumnIndex(columnIndex);
return null;
}
}
public E remove(IntPair point) {
return remove(point._1, point._2);
}
public boolean contains(Object rowKey, Object columnKey) {
return get(rowKey, columnKey) != null;
}
public boolean containsValue(Object value) {
// if (value == null) {
// for (R r : rowKeySet()) {
// for (C c : columnKeySet()) {
// if (this.get(r, c) == null) {
// return true;
// }
// }
// }
// } else {
// for (R r : rowKeySet()) {
// for (C c : columnKeySet()) {
// if (value.equals(this.get(r, c))) {
// return true;
// }
// }
// }
// }
//
// return false;
if (this._initialized) {
for (List column : _columnList) {
if (column.contains(value)) {
return true;
}
}
return false;
} else {
return value == null;
}
}
public List getRow(Object rowKey) {
final int columnLength = columnLength();
final List row = new ArrayList<>(columnLength);
if (_initialized) {
final int rowIndex = getRowIndex(rowKey);
for (int columnIndex = 0; columnIndex < columnLength; columnIndex++) {
row.add(_columnList.get(columnIndex).get(rowIndex));
}
} else {
checkRowKey(rowKey);
N.fill(row, 0, columnLength, null);
}
return ImmutableList.of(row);
}
public void setRow(R rowKey, Collection extends E> row) {
final int columnLength = columnLength();
if (N.notNullOrEmpty(row) && row.size() != columnLength) {
throw new IllegalArgumentException("The size of specified row: " + row.size() + " doesn't match the length of column key set: " + columnLength);
}
init();
final int rowIndex = getRowIndex(rowKey);
if (N.isNullOrEmpty(row)) {
for (int columnIndex = 0; columnIndex < columnLength; columnIndex++) {
_columnList.get(columnIndex).set(rowIndex, null);
}
} else {
final Iterator extends E> iter = row.iterator();
for (int columnIndex = 0; columnIndex < columnLength; columnIndex++) {
_columnList.get(columnIndex).set(rowIndex, iter.next());
}
}
}
public void addRow(R rowKey, Collection extends E> row) {
checkFrozen();
if (_rowKeySet.contains(rowKey)) {
throw new IllegalArgumentException("Row '" + rowKey + "' already existed");
}
final int rowLength = rowLength();
final int columnLength = columnLength();
if (N.notNullOrEmpty(row) && row.size() != columnLength) {
throw new IllegalArgumentException("The size of specified row: " + row.size() + " doesn't match the length of column key set: " + columnLength);
}
init();
_rowKeySet.add(rowKey);
_rowKeyIndexMap.put(rowKey, rowLength);
if (N.isNullOrEmpty(row)) {
for (int columnIndex = 0; columnIndex < columnLength; columnIndex++) {
_columnList.get(columnIndex).add(null);
}
} else {
final Iterator extends E> iter = row.iterator();
for (int columnIndex = 0; columnIndex < columnLength; columnIndex++) {
_columnList.get(columnIndex).add(iter.next());
}
}
}
public void addRow(final int rowIndex, final R rowKey, final Collection extends E> row) {
checkFrozen();
final int rowLength = rowLength();
final int columnLength = columnLength();
if (rowIndex == rowLength) {
addRow(rowKey, row);
return;
}
if (rowIndex < 0 || rowIndex > rowLength) {
throw new IllegalArgumentException("Invalid row index: " + rowIndex + ". It must be: >= 0 and <= " + rowLength);
}
if (_rowKeySet.contains(rowKey)) {
throw new IllegalArgumentException("Row '" + rowKey + "' already existed");
}
if (N.notNullOrEmpty(row) && row.size() != columnLength) {
throw new IllegalArgumentException("The size of specified row: " + row.size() + " doesn't match the length of column key set: " + columnLength);
}
init();
final List tmp = new ArrayList<>(rowLength + 1);
tmp.addAll(_rowKeySet);
tmp.add(rowIndex, rowKey);
_rowKeySet.clear();
_rowKeySet.addAll(tmp);
for (int i = _rowKeyIndexMap.size() - 1; i >= rowIndex; i--) {
_rowKeyIndexMap.put(_rowKeyIndexMap.getByValue(i), i + 1);
}
_rowKeyIndexMap.put(rowKey, rowIndex);
if (N.isNullOrEmpty(row)) {
for (int columnIndex = 0; columnIndex < columnLength; columnIndex++) {
_columnList.get(columnIndex).add(rowIndex, null);
}
} else {
final Iterator extends E> iter = row.iterator();
for (int columnIndex = 0; columnIndex < columnLength; columnIndex++) {
_columnList.get(columnIndex).add(rowIndex, iter.next());
}
}
}
public void updateRow(R rowKey, Try.Function super E, E, X> func) throws X {
checkFrozen();
if (columnLength() > 0) {
this.init();
final int rowIndex = this.getRowIndex(rowKey);
for (List column : _columnList) {
column.set(rowIndex, func.apply(column.get(rowIndex)));
}
}
}
public void removeRow(Object rowKey) {
checkFrozen();
checkRowKey(rowKey);
_rowKeySet.remove(rowKey);
if (_rowKeyIndexMap != null) {
final int columnLength = columnLength();
final int newRowSize = rowLength();
final int removedRowIndex = _rowKeyIndexMap.remove(rowKey);
if (removedRowIndex == newRowSize) {
// removed last row.
} else {
for (int i = removedRowIndex; i < newRowSize; i++) {
_rowKeyIndexMap.put(_rowKeyIndexMap.getByValue(i + 1), i);
}
}
if (_initialized) {
for (int columnIndex = 0; columnIndex < columnLength; columnIndex++) {
_columnList.get(columnIndex).remove(removedRowIndex);
}
}
}
}
/**
* Move the specified row to the new position.
*
* @param rowKey
* @param newRowIndex
*/
public void moveRow(Object rowKey, int newRowIndex) {
checkFrozen();
this.checkRowIndex(newRowIndex);
final int rowIndex = this.getRowIndex(rowKey);
final List tmp = new ArrayList<>(rowLength());
tmp.addAll(_rowKeySet);
tmp.add(newRowIndex, tmp.remove(rowIndex));
_rowKeySet.clear();
_rowKeySet.addAll(tmp);
_rowKeyIndexMap = null;
if (_initialized && _columnList.size() > 0) {
for (List column : _columnList) {
column.add(newRowIndex, column.remove(rowIndex));
}
}
}
/**
* Swap the positions of the two specified rows.
*
* @param rowKeyA
* @param rowKeyB
*/
public void swapRows(Object rowKeyA, Object rowKeyB) {
checkFrozen();
final int rowIndexA = this.getRowIndex(rowKeyA);
final int rowIndexB = this.getRowIndex(rowKeyB);
final List tmp = new ArrayList<>(rowLength());
tmp.addAll(_rowKeySet);
final R tmpRowKeyA = tmp.get(rowIndexA);
tmp.set(rowIndexA, tmp.get(rowIndexB));
tmp.set(rowIndexB, tmpRowKeyA);
_rowKeySet.clear();
_rowKeySet.addAll(tmp);
_rowKeyIndexMap.forcePut(tmp.get(rowIndexA), rowIndexA);
_rowKeyIndexMap.forcePut(tmp.get(rowIndexB), rowIndexB);
if (_initialized && _columnList.size() > 0) {
E tmpVal = null;
for (List column : _columnList) {
tmpVal = column.get(rowIndexA);
column.set(rowIndexA, column.get(rowIndexB));
column.set(rowIndexB, tmpVal);
}
}
}
public void renameRow(R rowKey, R newRowKey) {
checkFrozen();
checkRowKey(rowKey);
if (this._rowKeySet.contains(newRowKey)) {
throw new IllegalArgumentException("Invalid new row key: " + N.toString(newRowKey) + ". It's already in the row key set.");
}
final int rowIndex = this.getRowIndex(rowKey);
final List tmp = new ArrayList<>(_rowKeySet);
tmp.set(rowIndex, newRowKey);
this._rowKeySet.clear();
this._rowKeySet.addAll(tmp);
if (N.notNullOrEmpty(this._rowKeyIndexMap)) {
this._rowKeyIndexMap.put(newRowKey, _rowKeyIndexMap.remove(rowKey));
}
}
public boolean containsRow(Object rowKey) {
return _rowKeySet.contains(rowKey);
}
public Map row(Object rowKey) {
final int columnLength = columnLength();
Map rowMap = new LinkedHashMap<>(N.initHashCapacity(columnLength));
if (_initialized) {
final int rowIndex = getRowIndex(rowKey);
int columnIndex = 0;
for (C columnKey : this.columnKeySet()) {
rowMap.put(columnKey, _columnList.get(columnIndex++).get(rowIndex));
}
} else {
checkRowKey(rowKey);
for (C columnKey : this.columnKeySet()) {
rowMap.put(columnKey, null);
}
}
return rowMap;
}
public Map> rowMap() {
final Map> result = new LinkedHashMap<>(N.initHashCapacity(this.rowKeySet().size()));
for (R rowKey : this.rowKeySet()) {
result.put(rowKey, row(rowKey));
}
return result;
}
public List getColumn(Object columnKey) {
final int rowLength = rowLength();
List column = null;
if (_initialized) {
column = _columnList.get(getColumnIndex(columnKey));
} else {
checkColumnKey(columnKey);
column = new ArrayList<>(rowLength);
N.fill(column, 0, rowLength, null);
}
return ImmutableList.of(column);
}
public void setColumn(C columnKey, Collection extends E> column) {
checkFrozen();
final int rowLength = rowLength();
if (N.notNullOrEmpty(column) && column.size() != rowLength) {
throw new IllegalArgumentException("The size of specified column: " + column.size() + " doesn't match the length of row key set: " + rowLength);
}
init();
final int columnIndex = getColumnIndex(columnKey);
if (N.isNullOrEmpty(column)) {
N.fill(_columnList.get(columnIndex), 0, rowLength, null);
} else {
_columnList.set(columnIndex, new ArrayList<>(column));
}
}
public void addColumn(C columnKey, Collection extends E> column) {
checkFrozen();
if (_columnKeySet.contains(columnKey)) {
throw new IllegalArgumentException("Column '" + columnKey + "' already existed");
}
final int rowLength = rowLength();
final int columnLength = columnLength();
if (N.notNullOrEmpty(column) && column.size() != rowLength) {
throw new IllegalArgumentException("The size of specified column: " + column.size() + " doesn't match the length of row key set: " + rowLength);
}
init();
_columnKeySet.add(columnKey);
_columnKeyIndexMap.put(columnKey, columnLength);
if (N.isNullOrEmpty(column)) {
List newColumn = new ArrayList<>();
N.fill(newColumn, 0, rowLength, null);
_columnList.add(newColumn);
} else {
_columnList.add(new ArrayList<>(column));
}
}
public void addColumn(int columnIndex, C columnKey, Collection extends E> column) {
checkFrozen();
final int rowLength = rowLength();
final int columnLength = columnLength();
if (columnIndex == columnLength) {
addColumn(columnKey, column);
return;
}
if (columnIndex < 0 || columnIndex > columnLength) {
throw new IllegalArgumentException("Invalid column index: " + columnIndex + ". It must be: >= 0 and <= " + columnLength);
}
if (_columnKeySet.contains(columnKey)) {
throw new IllegalArgumentException("Column '" + columnKey + "' already existed");
}
if (N.notNullOrEmpty(column) && column.size() != rowLength) {
throw new IllegalArgumentException("The size of specified column: " + column.size() + " doesn't match the length of row key set: " + rowLength);
}
init();
final List tmp = new ArrayList<>(columnLength + 1);
tmp.addAll(_columnKeySet);
tmp.add(columnIndex, columnKey);
_columnKeySet.clear();
_columnKeySet.addAll(tmp);
for (int i = _columnKeyIndexMap.size() - 1; i >= columnIndex; i--) {
_columnKeyIndexMap.put(_columnKeyIndexMap.getByValue(i), i + 1);
}
_columnKeyIndexMap.put(columnKey, columnIndex);
if (N.isNullOrEmpty(column)) {
List newColumn = new ArrayList<>();
N.fill(newColumn, 0, rowLength, null);
_columnList.add(columnIndex, newColumn);
} else {
_columnList.add(columnIndex, new ArrayList<>(column));
}
}
public void updateColumn(C columnKey, Try.Function super E, E, X> func) throws X {
checkFrozen();
if (rowLength() > 0) {
this.init();
final int rowLength = rowLength();
final List column = _columnList.get(this.getColumnIndex(columnKey));
for (int rowIndex = 0; rowIndex < rowLength; rowIndex++) {
column.set(rowIndex, func.apply(column.get(rowIndex)));
}
}
}
public void removeColumn(Object columnKey) {
checkFrozen();
checkColumnKey(columnKey);
_columnKeySet.remove(columnKey);
if (_columnKeyIndexMap != null) {
final int newColumnLength = columnLength();
final int removedColumnIndex = _columnKeyIndexMap.remove(columnKey);
if (removedColumnIndex == newColumnLength) {
// removed the last column
} else {
for (int i = removedColumnIndex; i < newColumnLength; i++) {
_columnKeyIndexMap.put(_columnKeyIndexMap.getByValue(i + 1), i);
}
}
if (_initialized) {
_columnList.remove(removedColumnIndex);
}
}
}
/**
* Move the specified column to the new position.
*
* @param columnKey
* @param newColumnIndex
*/
public void moveColumn(Object columnKey, int newColumnIndex) {
checkFrozen();
this.checkColumnIndex(newColumnIndex);
final int columnIndex = this.getColumnIndex(columnKey);
final List tmp = new ArrayList<>(columnLength());
tmp.addAll(_columnKeySet);
tmp.add(newColumnIndex, tmp.remove(columnIndex));
_columnKeySet.clear();
_columnKeySet.addAll(tmp);
_columnKeyIndexMap = null;
if (_initialized && _columnList.size() > 0) {
_columnList.add(newColumnIndex, _columnList.remove(columnIndex));
}
}
/**
* Swap the positions of the two specified columns.
*
* @param columnKeyA
* @param columnKeyB
*/
public void swapColumns(Object columnKeyA, Object columnKeyB) {
checkFrozen();
final int columnIndexA = this.getColumnIndex(columnKeyA);
final int columnIndexB = this.getColumnIndex(columnKeyB);
final List tmp = new ArrayList<>(rowLength());
tmp.addAll(_columnKeySet);
final C tmpColumnKeyA = tmp.get(columnIndexA);
tmp.set(columnIndexA, tmp.get(columnIndexB));
tmp.set(columnIndexB, tmpColumnKeyA);
_columnKeySet.clear();
_columnKeySet.addAll(tmp);
_columnKeyIndexMap.forcePut(tmp.get(columnIndexA), columnIndexA);
_columnKeyIndexMap.forcePut(tmp.get(columnIndexB), columnIndexB);
if (_initialized && _columnList.size() > 0) {
final List tmpColumnA = _columnList.get(columnIndexA);
_columnList.set(columnIndexA, _columnList.get(columnIndexB));
_columnList.set(columnIndexB, tmpColumnA);
}
}
public void renameColumn(C columnKey, C newColumnKey) {
checkFrozen();
this.checkColumnKey(columnKey);
if (this._columnKeySet.contains(newColumnKey)) {
throw new IllegalArgumentException("Invalid new column key: " + N.toString(newColumnKey) + ". It's already in the column key set.");
}
final int columnIndex = this.getColumnIndex(columnKey);
final List tmp = new ArrayList<>(_columnKeySet);
tmp.set(columnIndex, newColumnKey);
this._columnKeySet.clear();
this._columnKeySet.addAll(tmp);
if (N.notNullOrEmpty(this._columnKeyIndexMap)) {
this._columnKeyIndexMap.put(newColumnKey, _columnKeyIndexMap.remove(columnKey));
}
}
public boolean containsColumn(Object columnKey) {
return _columnKeySet.contains(columnKey);
}
public Map column(Object columnKey) {
final int rowLength = rowLength();
final Map columnMap = new LinkedHashMap<>(N.initHashCapacity(rowLength));
if (_initialized) {
final int columnIndex = getColumnIndex(columnKey);
final List column = _columnList.get(columnIndex);
int rowIndex = 0;
for (R rowKey : this.rowKeySet()) {
columnMap.put(rowKey, column.get(rowIndex++));
}
} else {
checkColumnKey(columnKey);
for (R rowKey : this.rowKeySet()) {
columnMap.put(rowKey, null);
}
}
return columnMap;
}
public Map> columnMap() {
final Map> result = new LinkedHashMap<>(N.initHashCapacity(this.columnKeySet().size()));
for (C columnKey : this.columnKeySet()) {
result.put(columnKey, column(columnKey));
}
return result;
}
/**
* Returns the size of row key set.
*
* @return
*/
public int rowLength() {
return _rowKeySet.size();
}
/**
* Returns the size of column key set.
*
* @return
*/
public int columnLength() {
return _columnKeySet.size();
}
public void updateAll(Try.Function super E, E, X> func) throws X {
checkFrozen();
if (rowLength() > 0 && columnLength() > 0) {
this.init();
final int rowLength = rowLength();
for (List column : _columnList) {
for (int rowIndex = 0; rowIndex < rowLength; rowIndex++) {
column.set(rowIndex, func.apply(column.get(rowIndex)));
}
}
}
}
/**
* Update all elements based on points
*
* @param func
*/
public void updateAll(Try.IntBiFunction func) throws X {
checkFrozen();
if (rowLength() > 0 && columnLength() > 0) {
this.init();
final int rowLength = rowLength();
int columnIndex = 0;
for (List column : _columnList) {
for (int rowIndex = 0; rowIndex < rowLength; rowIndex++) {
column.set(rowIndex, func.apply(rowIndex, columnIndex));
}
columnIndex++;
}
}
}
/**
* Update all elements based on points
*
* @param func
*/
public void updateAll(Try.TriFunction func) throws X {
checkFrozen();
if (rowLength() > 0 && columnLength() > 0) {
this.init();
final int rowLength = rowLength();
int columnIndex = 0;
C columnKey = null;
for (List column : _columnList) {
columnKey = _columnKeyIndexMap.getByValue(columnIndex);
for (int rowIndex = 0; rowIndex < rowLength; rowIndex++) {
column.set(rowIndex, func.apply(_rowKeyIndexMap.getByValue(rowIndex), columnKey, column.get(rowIndex)));
}
columnIndex++;
}
}
}
/**
*
* @param predicate
* @param newValue
*/
public void replaceIf(final Try.Predicate super E, X> predicate, final E newValue) throws X {
checkFrozen();
if (rowLength() > 0 && columnLength() > 0) {
this.init();
final int rowLength = rowLength();
for (List column : _columnList) {
for (int rowIndex = 0; rowIndex < rowLength; rowIndex++) {
if (predicate.test(column.get(rowIndex))) {
column.set(rowIndex, newValue);
}
}
}
}
}
/**
* Replace elements by Predicate.test(i, j)
based on points
*
* @param predicate
* @param newValue
*/
public void replaceIf(final Try.IntBiPredicate predicate, final E newValue) throws X {
checkFrozen();
if (rowLength() > 0 && columnLength() > 0) {
this.init();
final int rowLength = rowLength();
int columnIndex = 0;
for (List column : _columnList) {
for (int rowIndex = 0; rowIndex < rowLength; rowIndex++) {
if (predicate.test(rowIndex, columnIndex)) {
column.set(rowIndex, newValue);
}
}
columnIndex++;
}
}
}
/**
* Replace elements by Predicate.test(i, j)
based on points
*
* @param predicate
* @param newValue
*/
public void replaceIf(final Try.TriPredicate predicate, final E newValue) throws X {
checkFrozen();
if (rowLength() > 0 && columnLength() > 0) {
this.init();
final int rowLength = rowLength();
int columnIndex = 0;
R rowKey = null;
C columnKey = null;
E val = null;
for (List column : _columnList) {
columnKey = _columnKeyIndexMap.getByValue(columnIndex);
for (int rowIndex = 0; rowIndex < rowLength; rowIndex++) {
rowKey = _rowKeyIndexMap.getByValue(rowIndex);
val = column.get(rowIndex);
if (predicate.test(rowKey, columnKey, val)) {
column.set(rowIndex, newValue);
}
}
columnIndex++;
}
}
}
public Sheet copy() {
final Sheet copy = new Sheet<>(this._rowKeySet, this._columnKeySet);
if (this._initialized) {
copy.initIndexMap();
copy._columnList = new ArrayList<>(_columnList.size());
for (List column : _columnList) {
copy._columnList.add(new ArrayList<>(column));
}
copy._initialized = true;
}
return copy;
}
public Sheet copy(Collection rowKeySet, Collection columnKeySet) {
if (this._rowKeySet.containsAll(rowKeySet) == false) {
throw new IllegalArgumentException(
"Row keys: " + N.difference(rowKeySet, this._rowKeySet) + " are not included in this sheet row keys: " + this._rowKeySet);
}
if (this._columnKeySet.containsAll(columnKeySet) == false) {
throw new IllegalArgumentException(
"Column keys: " + N.difference(columnKeySet, this._columnKeySet) + " are not included in this sheet Column keys: " + this._columnKeySet);
}
final Sheet copy = new Sheet<>(rowKeySet, columnKeySet);
if (this._initialized) {
copy.initIndexMap();
copy._columnList = new ArrayList<>(copy.columnLength());
final int[] rowKeyIndices = new int[copy.rowLength()];
int idx = 0;
for (R rowKey : copy._rowKeySet) {
rowKeyIndices[idx++] = this.getRowIndex(rowKey);
}
for (C columnKey : copy._columnKeySet) {
final List column = _columnList.get(this.getColumnIndex(columnKey));
final List newColumn = new ArrayList<>(rowKeyIndices.length);
for (int rowIndex : rowKeyIndices) {
newColumn.add(column.get(rowIndex));
}
copy._columnList.add(newColumn);
}
copy._initialized = true;
}
return copy;
}
/**
* Deeply copy each element in this Sheet
by Serialization/Deserialization.
*
* @return
*/
@Override
public Sheet clone() {
return clone(this._isFrozen);
}
/**
* Deeply copy each element in this Sheet
by Serialization/Deserialization.
*
* @return
*/
public Sheet clone(boolean freeze) {
if (kryoParser == null) {
throw new RuntimeException("Kryo is required");
}
final Sheet copy = kryoParser.clone(this);
copy._isFrozen = freeze;
return copy;
}
public Sheet merge(Sheet extends R, ? extends C, ? extends E2> b,
Try.BiFunction super E, ? super E2, E3, X> mergeFunction) throws X {
final Set newRowKeySet = N.newLinkedHashSet(this.rowKeySet());
newRowKeySet.addAll(b.rowKeySet());
final Set newColumnKeySet = N.newLinkedHashSet(this.columnKeySet());
newColumnKeySet.addAll(b.columnKeySet());
final Sheet result = new Sheet<>(newRowKeySet, newColumnKeySet);
final int[] rowIndexes1 = new int[newRowKeySet.size()], rowIndexes2 = new int[newRowKeySet.size()];
final int[] columnIndexes1 = new int[newColumnKeySet.size()], columnIndexes2 = new int[newColumnKeySet.size()];
int idx = 0;
for (R rowKey : newRowKeySet) {
rowIndexes1[idx] = this.containsRow(rowKey) ? this.getRowIndex(rowKey) : -1;
rowIndexes2[idx] = b.containsRow(rowKey) ? b.getRowIndex(rowKey) : -1;
}
idx = 0;
for (C columnKey : newColumnKeySet) {
columnIndexes1[idx] = this.containsColumn(columnKey) ? this.getColumnIndex(columnKey) : -1;
columnIndexes2[idx] = b.containsColumn(columnKey) ? b.getColumnIndex(columnKey) : -1;
}
E e1 = null;
E2 e2 = null;
for (int rowIndex = 0, rowLen = newRowKeySet.size(); rowIndex < rowLen; rowIndex++) {
for (int columnIndex = 0, columnLen = newColumnKeySet.size(); columnIndex < columnLen; columnIndex++) {
e1 = rowIndexes1[rowIndex] > -1 && columnIndexes1[columnIndex] > -1 ? this.get(rowIndexes1[rowIndex], columnIndexes1[columnIndex]) : null;
e2 = rowIndexes2[rowIndex] > -1 && columnIndexes2[columnIndex] > -1 ? b.get(rowIndexes2[rowIndex], columnIndexes2[columnIndex]) : null;
result.put(rowIndex, columnIndex, mergeFunction.apply(e1, e2));
}
}
return result;
}
public Sheet transpose() {
final Sheet copy = new Sheet<>(this._columnKeySet, this._rowKeySet);
if (this._initialized) {
copy.initIndexMap();
final int rowLength = copy.rowLength();
final int columnLength = copy.columnLength();
copy._columnList = new ArrayList<>(columnLength);
for (int i = 0; i < columnLength; i++) {
final List column = new ArrayList<>(rowLength);
for (int j = 0; j < rowLength; j++) {
column.add(_columnList.get(j).get(i));
}
copy._columnList.add(column);
}
copy._initialized = true;
}
return copy;
}
public void freeze() {
_isFrozen = true;
}
public boolean frozen() {
return _isFrozen;
}
public void clear() {
checkFrozen();
if (_initialized && _columnList.size() > 0) {
for (List column : _columnList) {
N.fill(column, 0, column.size(), null);
}
}
}
public void trimToSize() {
if (_initialized && _columnList.size() > 0) {
for (List column : _columnList) {
if (column instanceof ArrayList) {
((ArrayList>) column).trimToSize();
}
}
}
}
public void forEachH(Try.TriConsumer action) throws X {
for (R rowKey : _rowKeySet) {
for (C columnKey : _columnKeySet) {
if (_initialized) {
action.accept(rowKey, columnKey, get(rowKey, columnKey));
} else {
action.accept(rowKey, columnKey, null);
}
}
}
}
public void forEachV(Try.TriConsumer action) throws X {
for (C columnKey : _columnKeySet) {
for (R rowKey : _rowKeySet) {
if (_initialized) {
action.accept(rowKey, columnKey, get(rowKey, columnKey));
} else {
action.accept(rowKey, columnKey, null);
}
}
}
}
/**
*
* @return a stream of Cells based on the order of row.
*/
public Stream> cellsH() {
return cellsH(0, rowLength());
}
public Stream> cellsH(final int rowIndex) {
return cellsH(rowIndex, rowIndex + 1);
}
/**
*
* @param fromRowIndex
* @param toRowIndex
* @return a stream of Cells based on the order of row.
*/
public Stream> cellsH(final int fromRowIndex, final int toRowIndex) {
N.checkFromToIndex(fromRowIndex, toRowIndex, rowLength());
if (rowLength() == 0 || columnLength() == 0) {
return Stream.empty();
}
final int columnLength = columnLength();
initIndexMap();
return Stream.of(new ObjIteratorEx>() {
private final long toIndex = toRowIndex * columnLength * 1L;
private long cursor = fromRowIndex * columnLength * 1L;
@Override
public boolean hasNext() {
return cursor < toIndex;
}
@Override
public Sheet.Cell next() {
if (cursor >= toIndex) {
throw new NoSuchElementException();
}
final int rowIndex = (int) (cursor / columnLength);
final int columnIndex = (int) (cursor++ % columnLength);
return new CellImpl<>(_rowKeyIndexMap.getByValue(rowIndex), _columnKeyIndexMap.getByValue(columnIndex),
_initialized ? _columnList.get(columnIndex).get(rowIndex) : null);
}
@Override
public void skip(long n) {
N.checkArgNotNegative(n, "n");
cursor = n < toIndex - cursor ? cursor + n : toIndex;
}
@Override
public long count() {
return toIndex - cursor;
}
});
}
/**
*
* @return a stream of Cells based on the order of column.
*/
public Stream> cellsV() {
return cellsV(0, columnLength());
}
/**
*
* @param columnIndex
* @return
*/
public Stream> cellsV(final int columnIndex) {
return cellsV(columnIndex, columnIndex + 1);
}
/**
*
* @param fromColumnIndex
* @param toColumnIndex
* @return a stream of Cells based on the order of column.
*/
public Stream> cellsV(final int fromColumnIndex, final int toColumnIndex) {
N.checkFromToIndex(fromColumnIndex, toColumnIndex, columnLength());
if (rowLength() == 0 || columnLength() == 0) {
return Stream.empty();
}
final int rowLength = rowLength();
initIndexMap();
return Stream.of(new ObjIteratorEx>() {
private final long toIndex = toColumnIndex * rowLength * 1L;
private long cursor = fromColumnIndex * rowLength * 1L;
@Override
public boolean hasNext() {
return cursor < toIndex;
}
@Override
public Sheet.Cell next() {
if (cursor >= toIndex) {
throw new NoSuchElementException();
}
final int rowIndex = (int) (cursor % rowLength);
final int columnIndex = (int) (cursor++ / rowLength);
return new CellImpl<>(_rowKeyIndexMap.getByValue(rowIndex), _columnKeyIndexMap.getByValue(columnIndex),
_initialized ? _columnList.get(columnIndex).get(rowIndex) : null);
}
@Override
public void skip(long n) {
N.checkArgNotNegative(n, "n");
cursor = n < toIndex - cursor ? cursor + n : toIndex;
}
@Override
public long count() {
return toIndex - cursor;
}
});
}
/**
*
* @return a stream based on the order of row.
*/
public Stream>> cellsR() {
return cellsR(0, rowLength());
}
/**
*
* @param fromRowIndex
* @param toRowIndex
* @return a stream based on the order of row.
*/
public Stream>> cellsR(final int fromRowIndex, final int toRowIndex) {
N.checkFromToIndex(fromRowIndex, toRowIndex, rowLength());
if (rowLength() == 0 || columnLength() == 0) {
return Stream.empty();
}
final int columnLength = columnLength();
return Stream.of(new ObjIteratorEx>>() {
private volatile int rowIndex = fromRowIndex;
@Override
public boolean hasNext() {
return rowIndex < toRowIndex;
}
@Override
public Stream> next() {
if (rowIndex >= toRowIndex) {
throw new NoSuchElementException();
}
return Stream.of(new ObjIteratorEx>() {
private final int curRowIndex = rowIndex++;
private final R r = _rowKeyIndexMap.getByValue(curRowIndex);
private int columnIndex = 0;
@Override
public boolean hasNext() {
return columnIndex < columnLength;
}
@Override
public Cell next() {
if (columnIndex >= columnLength) {
throw new NoSuchElementException();
}
final int curColumnIndex = columnIndex++;
return new CellImpl<>(r, _columnKeyIndexMap.getByValue(curColumnIndex),
_initialized ? _columnList.get(curColumnIndex).get(curRowIndex) : null);
}
@Override
public void skip(long n) {
N.checkArgNotNegative(n, "n");
columnIndex = n < columnLength - columnIndex ? columnIndex + (int) n : columnLength;
}
@Override
public long count() {
return columnLength - columnIndex;
}
});
}
@Override
public void skip(long n) {
N.checkArgNotNegative(n, "n");
rowIndex = n < toRowIndex - rowIndex ? rowIndex + (int) n : toRowIndex;
}
@Override
public long count() {
return toRowIndex - rowIndex;
}
});
}
/**
*
* @return a stream based on the order of column.
*/
public Stream>> cellsC() {
return cellsC(0, columnLength());
}
/**
*
* @param fromColumnIndex
* @param toColumnIndex
* @return a stream based on the order of column.
*/
public Stream>> cellsC(final int fromColumnIndex, final int toColumnIndex) {
N.checkFromToIndex(fromColumnIndex, toColumnIndex, columnLength());
if (rowLength() == 0 || columnLength() == 0) {
return Stream.empty();
}
final int rowLength = rowLength();
return Stream.of(new ObjIteratorEx>>() {
private int columnIndex = fromColumnIndex;
@Override
public boolean hasNext() {
return columnIndex < toColumnIndex;
}
@Override
public Stream> next() {
if (columnIndex >= toColumnIndex) {
throw new NoSuchElementException();
}
final int curColumnIndex = columnIndex++;
final C c = _columnKeyIndexMap.getByValue(curColumnIndex);
if (_initialized) {
final List column = _columnList.get(curColumnIndex);
return IntStream.range(0, rowLength).mapToObj(new IntFunction>() {
@Override
public Cell apply(int rowIndex) {
return new CellImpl<>(_rowKeyIndexMap.getByValue(rowIndex), c, column.get(rowIndex));
}
});
} else {
return IntStream.range(0, rowLength).mapToObj(new IntFunction>() {
@Override
public Cell apply(int rowIndex) {
return new CellImpl<>(_rowKeyIndexMap.getByValue(rowIndex), c, null);
}
});
}
}
@Override
public void skip(long n) {
N.checkArgNotNegative(n, "n");
columnIndex = n < toColumnIndex - columnIndex ? columnIndex + (int) n : toColumnIndex;
}
@Override
public long count() {
return toColumnIndex - columnIndex;
}
});
}
public Stream pointsH() {
return pointsH(0, rowLength());
}
public Stream pointsH(int rowIndex) {
return pointsH(rowIndex, rowIndex + 1);
}
public Stream pointsH(int fromRowIndex, int toRowIndex) {
N.checkFromToIndex(fromRowIndex, toRowIndex, rowLength());
final int columnLength = columnLength();
return IntStream.range(fromRowIndex, toRowIndex).flatMapToObj(new IntFunction>() {
@Override
public Stream apply(final int rowIndex) {
return IntStream.range(0, columnLength).mapToObj(new IntFunction() {
@Override
public IntPair apply(final int columnIndex) {
return IntPair.of(rowIndex, columnIndex);
}
});
}
});
}
public Stream pointsV() {
return pointsV(0, columnLength());
}
public Stream pointsV(int columnIndex) {
return pointsV(columnIndex, columnIndex + 1);
}
public Stream pointsV(int fromColumnIndex, int toColumnIndex) {
N.checkFromToIndex(fromColumnIndex, toColumnIndex, columnLength());
final int rowLength = rowLength();
return IntStream.range(fromColumnIndex, toColumnIndex).flatMapToObj(new IntFunction>() {
@Override
public Stream apply(final int columnIndex) {
return IntStream.range(0, rowLength).mapToObj(new IntFunction() {
@Override
public IntPair apply(final int rowIndex) {
return IntPair.of(rowIndex, columnIndex);
}
});
}
});
}
public Stream> pointsR() {
return pointsR(0, rowLength());
}
public Stream> pointsR(int fromRowIndex, int toRowIndex) {
N.checkFromToIndex(fromRowIndex, toRowIndex, rowLength());
final int columnLength = columnLength();
return IntStream.range(fromRowIndex, toRowIndex).mapToObj(new IntFunction>() {
@Override
public Stream apply(final int rowIndex) {
return IntStream.range(0, columnLength).mapToObj(new IntFunction() {
@Override
public IntPair apply(final int columnIndex) {
return IntPair.of(rowIndex, columnIndex);
}
});
}
});
}
public Stream> pointsC() {
return pointsR(0, columnLength());
}
public Stream> pointsC(int fromColumnIndex, int toColumnIndex) {
N.checkFromToIndex(fromColumnIndex, toColumnIndex, columnLength());
final int rowLength = rowLength();
return IntStream.range(fromColumnIndex, toColumnIndex).mapToObj(new IntFunction>() {
@Override
public Stream apply(final int columnIndex) {
return IntStream.range(0, rowLength).mapToObj(new IntFunction() {
@Override
public IntPair apply(final int rowIndex) {
return IntPair.of(rowIndex, columnIndex);
}
});
}
});
}
/**
*
* @return a stream based on the order of row.
*/
public Stream streamH() {
return streamH(0, rowLength());
}
/**
*
* @param rowIndex
* @return
*/
public Stream streamH(final int rowIndex) {
return streamH(rowIndex, rowIndex + 1);
}
/**
*
* @param fromRowIndex
* @param toRowIndex
* @return a stream based on the order of row.
*/
public Stream streamH(final int fromRowIndex, final int toRowIndex) {
N.checkFromToIndex(fromRowIndex, toRowIndex, rowLength());
if (rowLength() == 0 || columnLength() == 0) {
return Stream.empty();
}
return Stream.of(new ObjIteratorEx() {
private final int columnLength = columnLength();
private final long toIndex = toRowIndex * columnLength * 1L;
private long cursor = fromRowIndex * columnLength * 1L;
@Override
public boolean hasNext() {
return cursor < toIndex;
}
@Override
public E next() {
if (cursor >= toIndex) {
throw new NoSuchElementException();
}
if (_initialized) {
return _columnList.get((int) (cursor % columnLength)).get((int) (cursor++ / columnLength));
} else {
cursor++;
return null;
}
}
@Override
public void skip(long n) {
N.checkArgNotNegative(n, "n");
cursor = n < toIndex - cursor ? cursor + n : toIndex;
}
@Override
public long count() {
return toIndex - cursor;
}
});
}
/**
*
* @return a stream based on the order of column.
*/
public Stream streamV() {
return streamV(0, columnLength());
}
/**
*
* @param columnIndex
* @return
*/
public Stream streamV(final int columnIndex) {
return streamV(columnIndex, columnIndex + 1);
}
/**
*
* @param fromColumnIndex
* @param toColumnIndex
* @return a stream based on the order of column.
*/
public Stream streamV(final int fromColumnIndex, final int toColumnIndex) {
N.checkFromToIndex(fromColumnIndex, toColumnIndex, columnLength());
if (rowLength() == 0 || columnLength() == 0) {
return Stream.empty();
}
return Stream.of(new ObjIteratorEx() {
private final int rowLength = rowLength();
private final long toIndex = toColumnIndex * rowLength * 1L;
private long cursor = fromColumnIndex * rowLength * 1L;
@Override
public boolean hasNext() {
return cursor < toIndex;
}
@Override
public E next() {
if (cursor >= toIndex) {
throw new NoSuchElementException();
}
if (_initialized) {
return _columnList.get((int) (cursor / rowLength)).get((int) (cursor++ % rowLength));
} else {
cursor++;
return null;
}
}
@Override
public void skip(long n) {
N.checkArgNotNegative(n, "n");
cursor = n < toIndex - cursor ? cursor + n : toIndex;
}
@Override
public long count() {
return toIndex - cursor;
}
});
}
/**
*
* @return a stream based on the order of row.
*/
public Stream> streamR() {
return streamR(0, rowLength());
}
/**
*
* @param fromRowIndex
* @param toRowIndex
* @return a stream based on the order of row.
*/
public Stream> streamR(final int fromRowIndex, final int toRowIndex) {
N.checkFromToIndex(fromRowIndex, toRowIndex, rowLength());
if (rowLength() == 0 || columnLength() == 0) {
return Stream.empty();
}
return Stream.of(new ObjIteratorEx>() {
private final int toIndex = toRowIndex;
private volatile int cursor = fromRowIndex;
@Override
public boolean hasNext() {
return cursor < toIndex;
}
@Override
public Stream next() {
if (cursor >= toIndex) {
throw new NoSuchElementException();
}
return Stream.of(new ObjIteratorEx() {
private final int rowIndex = cursor++;
private final int toIndex2 = columnLength();
private int cursor2 = 0;
@Override
public boolean hasNext() {
return cursor2 < toIndex2;
}
@Override
public E next() {
if (cursor2 >= toIndex2) {
throw new NoSuchElementException();
}
if (_initialized) {
return _columnList.get(cursor2++).get(rowIndex);
} else {
cursor2++;
return null;
}
}
@Override
public void skip(long n) {
N.checkArgNotNegative(n, "n");
cursor2 = n < toIndex2 - cursor2 ? cursor2 + (int) n : toIndex2;
}
@Override
public long count() {
return toIndex2 - cursor2;
}
});
}
@Override
public void skip(long n) {
N.checkArgNotNegative(n, "n");
cursor = n < toIndex - cursor ? cursor + (int) n : toIndex;
}
@Override
public long count() {
return toIndex - cursor;
}
});
}
/**
*
* @return a stream based on the order of column.
*/
public Stream> streamC() {
return streamC(0, columnLength());
}
/**
*
* @param fromColumnIndex
* @param toColumnIndex
* @return a stream based on the order of column.
*/
public Stream> streamC(final int fromColumnIndex, final int toColumnIndex) {
N.checkFromToIndex(fromColumnIndex, toColumnIndex, columnLength());
if (rowLength() == 0 || columnLength() == 0) {
return Stream.empty();
}
return Stream.of(new ObjIteratorEx>() {
private final int toIndex = toColumnIndex;
private int cursor = fromColumnIndex;
@Override
public boolean hasNext() {
return cursor < toIndex;
}
@Override
public Stream next() {
if (cursor >= toIndex) {
throw new NoSuchElementException();
}
if (_initialized) {
return Stream.of(_columnList.get(cursor++));
} else {
cursor++;
return Stream.repeat(null, rowLength());
}
}
@Override
public void skip(long n) {
N.checkArgNotNegative(n, "n");
cursor = n < toIndex - cursor ? cursor + (int) n : toIndex;
}
@Override
public long count() {
return toIndex - cursor;
}
});
}
/**
*
* @return a DataSet based on row.
*/
public DataSet toDataSetH() {
final int rowLength = rowLength();
final int columnLength = columnLength();
final List dataSetColumnNameList = new ArrayList<>(columnLength);
for (C columnKey : _columnKeySet) {
dataSetColumnNameList.add(N.toString(columnKey));
}
final List> dataSetColumnList = new ArrayList<>(columnLength);
if (_initialized) {
for (List column : _columnList) {
dataSetColumnList.add(new ArrayList | | | | |