Package com.positive.charts.data

Source Code of com.positive.charts.data.DefaultKeyedValues2D

package com.positive.charts.data;

import java.io.Serializable;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import com.positive.charts.common.UnknownKeyException;

/**
* A data structure that stores zero, one or many values, where each value is
* associated with two keys (a 'row' key and a 'column' key). The keys should be
* (a) instances of {@link Comparable} and (b) immutable.
*/
public class DefaultKeyedValues2D implements KeyedValues2D, Serializable {

  /** For serialization. */
  private static final long serialVersionUID = -5514169970951994748L;

  /** The row keys. */
  private final List rowKeys;

  /** The column keys. */
  private final List columnKeys;

  /** The row data. */
  private final List rows;

  /** If the row keys should be sorted by their comparable order. */
  private final boolean sortRowKeys;

  /**
   * Creates a new instance (initially empty).
   */
  public DefaultKeyedValues2D() {
    this(false);
  }

  /**
   * Creates a new instance (initially empty).
   *
   * @param sortRowKeys
   *            if the row keys should be sorted.
   */
  public DefaultKeyedValues2D(final boolean sortRowKeys) {
    this.rowKeys = new java.util.ArrayList();
    this.columnKeys = new java.util.ArrayList();
    this.rows = new java.util.ArrayList();
    this.sortRowKeys = sortRowKeys;
  }

  /**
   * Adds a value to the table. Performs the same function as
   * #setValue(Number, Comparable, Comparable).
   *
   * @param value
   *            the value (<code>null</code> permitted).
   * @param rowKey
   *            the row key (<code>null</code> not permitted).
   * @param columnKey
   *            the column key (<code>null</code> not permitted).
   */
  public void addValue(final Number value, final Comparable rowKey,
      final Comparable columnKey) {
    // defer argument checking
    this.setValue(value, rowKey, columnKey);
  }

  /**
   * Clears all the data and associated keys.
   */
  public void clear() {
    this.rowKeys.clear();
    this.columnKeys.clear();
    this.rows.clear();
  }

  /**
   * Tests if this object is equal to another.
   *
   * @param o
   *            the other object (<code>null</code> permitted).
   *
   * @return A boolean.
   */
  public boolean equals(final Object o) {

    if (o == null) {
      return false;
    }
    if (o == this) {
      return true;
    }

    if (!(o instanceof KeyedValues2D)) {
      return false;
    }
    final KeyedValues2D kv2D = (KeyedValues2D) o;
    if (!this.getRowKeys().equals(kv2D.getRowKeys())) {
      return false;
    }
    if (!this.getColumnKeys().equals(kv2D.getColumnKeys())) {
      return false;
    }
    final int rowCount = this.getRowCount();
    if (rowCount != kv2D.getRowCount()) {
      return false;
    }

    final int colCount = this.getColumnCount();
    if (colCount != kv2D.getColumnCount()) {
      return false;
    }

    for (int r = 0; r < rowCount; r++) {
      for (int c = 0; c < colCount; c++) {
        final Number v1 = this.getValue(r, c);
        final Number v2 = kv2D.getValue(r, c);
        if (v1 == null) {
          if (v2 != null) {
            return false;
          }
        } else {
          if (!v1.equals(v2)) {
            return false;
          }
        }
      }
    }
    return true;
  }

  /**
   * Returns the column count.
   *
   * @return The column count.
   */
  public int getColumnCount() {
    return this.columnKeys.size();
  }

  /**
   * Returns the column index for a given key.
   *
   * @param key
   *            the key (<code>null</code> not permitted).
   *
   * @return The column index.
   */
  public int getColumnIndex(final Comparable key) {
    if (key == null) {
      throw new IllegalArgumentException("Null 'key' argument.");
    }
    return this.columnKeys.indexOf(key);
  }

  /**
   * Returns the key for a given column.
   *
   * @param column
   *            the column.
   *
   * @return The key.
   */
  public Comparable getColumnKey(final int column) {
    return (Comparable) this.columnKeys.get(column);
  }

  /**
   * Returns the column keys.
   *
   * @return The column keys.
   */
  public List getColumnKeys() {
    return Collections.unmodifiableList(this.columnKeys);
  }

  /**
   * Returns the row count.
   *
   * @return The row count.
   */
  public int getRowCount() {
    return this.rowKeys.size();
  }

  /**
   * Returns the row index for a given key.
   *
   * @param key
   *            the key (<code>null</code> not permitted).
   *
   * @return The row index.
   */
  public int getRowIndex(final Comparable key) {
    if (key == null) {
      throw new IllegalArgumentException("Null 'key' argument.");
    }
    if (this.sortRowKeys) {
      return Collections.binarySearch(this.rowKeys, key);
    } else {
      return this.rowKeys.indexOf(key);
    }
  }

  /**
   * Returns the key for a given row.
   *
   * @param row
   *            the row index (zero based).
   *
   * @return The row index.
   */
  public Comparable getRowKey(final int row) {
    return (Comparable) this.rowKeys.get(row);
  }

  /**
   * Returns the row keys.
   *
   * @return The row keys.
   */
  public List getRowKeys() {
    return Collections.unmodifiableList(this.rowKeys);
  }

  /**
   * Returns the value for the given row and column keys. This method will
   * throw an {@link UnknownKeyException} if either key is not defined in the
   * data structure.
   *
   * @param rowKey
   *            the row key (<code>null</code> not permitted).
   * @param columnKey
   *            the column key (<code>null</code> not permitted).
   *
   * @return The value (possibly <code>null</code>).
   */
  public Number getValue(final Comparable rowKey, final Comparable columnKey) {
    if (rowKey == null) {
      throw new IllegalArgumentException("Null 'rowKey' argument.");
    }
    if (columnKey == null) {
      throw new IllegalArgumentException("Null 'columnKey' argument.");
    }
    final int row = this.getRowIndex(rowKey);
    if (row >= 0) {
      final DefaultKeyedValues rowData = (DefaultKeyedValues) this.rows
          .get(row);
      return rowData.getValue(columnKey);
    } else {
      throw new UnknownKeyException("Unrecognised rowKey: " + rowKey);
    }
  }

  /**
   * Returns the value for a given row and column.
   *
   * @param row
   *            the row index.
   * @param column
   *            the column index.
   *
   * @return The value.
   */
  public Number getValue(final int row, final int column) {
    Number result = null;
    final DefaultKeyedValues rowData = (DefaultKeyedValues) this.rows
        .get(row);
    if (rowData != null) {
      final Comparable columnKey = (Comparable) this.columnKeys
          .get(column);
      // the row may not have an entry for this key, in which case the
      // return value is null
      final int index = rowData.getIndex(columnKey);
      if (index >= 0) {
        result = rowData.getValue(index);
      }
    }
    return result;
  }

  /**
   * Returns a hash code.
   *
   * @return A hash code.
   */
  public int hashCode() {
    int result;
    result = this.rowKeys.hashCode();
    result = 29 * result + this.columnKeys.hashCode();
    result = 29 * result + this.rows.hashCode();
    return result;
  }

  /**
   * Removes a column.
   *
   * @param columnKey
   *            the column key (<code>null</code> not permitted).
   */
  public void removeColumn(final Comparable columnKey) {
    final Iterator iterator = this.rows.iterator();
    while (iterator.hasNext()) {
      final DefaultKeyedValues rowData = (DefaultKeyedValues) iterator
          .next();
      rowData.removeValue(columnKey);
    }
    this.columnKeys.remove(columnKey);
  }

  /**
   * Removes a column.
   *
   * @param columnIndex
   *            the column index.
   */
  public void removeColumn(final int columnIndex) {
    final Comparable columnKey = this.getColumnKey(columnIndex);
    this.removeColumn(columnKey);
  }

  /**
   * Removes a row.
   *
   * @param rowKey
   *            the row key.
   */
  public void removeRow(final Comparable rowKey) {
    this.removeRow(this.getRowIndex(rowKey));
  }

  /**
   * Removes a row.
   *
   * @param rowIndex
   *            the row index.
   */
  public void removeRow(final int rowIndex) {
    this.rowKeys.remove(rowIndex);
    this.rows.remove(rowIndex);
  }

  /**
   * Removes a value.
   *
   * @param rowKey
   *            the row key (<code>null</code> not permitted).
   * @param columnKey
   *            the column key (<code>null</code> not permitted).
   */
  public void removeValue(final Comparable rowKey, final Comparable columnKey) {
    this.setValue(null, rowKey, columnKey);

    // 1. check whether the row is now empty.
    boolean allNull = true;
    final int rowIndex = this.getRowIndex(rowKey);
    DefaultKeyedValues row = (DefaultKeyedValues) this.rows.get(rowIndex);

    for (int item = 0, itemCount = row.getItemCount(); item < itemCount; item++) {
      if (row.getValue(item) != null) {
        allNull = false;
        break;
      }
    }

    if (allNull) {
      this.rowKeys.remove(rowIndex);
      this.rows.remove(rowIndex);
    }

    // 2. check whether the column is now empty.
    allNull = true;
    final int columnIndex = this.getColumnIndex(columnKey);

    for (int item = 0, itemCount = this.rows.size(); item < itemCount; item++) {
      row = (DefaultKeyedValues) this.rows.get(item);
      if (row.getValue(columnIndex) != null) {
        allNull = false;
        break;
      }
    }

    if (allNull) {
      for (int item = 0, itemCount = this.rows.size(); item < itemCount; item++) {
        row = (DefaultKeyedValues) this.rows.get(item);
        row.removeValue(columnIndex);
      }
      this.columnKeys.remove(columnIndex);
    }
  }

  /**
   * Adds or updates a value.
   *
   * @param value
   *            the value (<code>null</code> permitted).
   * @param rowKey
   *            the row key (<code>null</code> not permitted).
   * @param columnKey
   *            the column key (<code>null</code> not permitted).
   */
  public void setValue(final Number value, final Comparable rowKey,
      final Comparable columnKey) {

    DefaultKeyedValues row;
    int rowIndex = this.getRowIndex(rowKey);

    if (rowIndex >= 0) {
      row = (DefaultKeyedValues) this.rows.get(rowIndex);
    } else {
      row = new DefaultKeyedValues();
      if (this.sortRowKeys) {
        rowIndex = -rowIndex - 1;
        this.rowKeys.add(rowIndex, rowKey);
        this.rows.add(rowIndex, row);
      } else {
        this.rowKeys.add(rowKey);
        this.rows.add(row);
      }
    }
    row.setValue(columnKey, value);

    final int columnIndex = this.columnKeys.indexOf(columnKey);
    if (columnIndex < 0) {
      this.columnKeys.add(columnKey);
    }
  }

}
TOP

Related Classes of com.positive.charts.data.DefaultKeyedValues2D

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.