Package com.positive.charts.data

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

package com.positive.charts.data;

import java.io.Serializable;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.positive.charts.common.SortOrder;
import com.positive.charts.common.UnknownKeyException;
import com.positive.charts.data.util.KeyedValueComparator;
import com.positive.charts.data.util.KeyedValueComparatorType;
import com.positive.charts.data.util.ObjectUtilities;

/**
* An ordered list of (key, value) items. This class provides a default
* implementation of the {@link KeyedValues} interface.
*/
public class DefaultKeyedValues implements KeyedValues, Cloneable, Serializable {

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

  /** Storage for the data. */
  private List data;

  private final Map key2Index;

  /**
   * Creates a new collection (initially empty).
   */
  public DefaultKeyedValues() {
    this.data = new java.util.ArrayList();
    this.key2Index = new LinkedHashMap();
  }

  /**
   * Updates an existing value, or adds a new value to the collection.
   *
   * @param key
   *            the key (<code>null</code> not permitted).
   * @param value
   *            the value.
   */
  public void addValue(final Comparable key, final double value) {
    this.addValue(key, new Double(value));
  }

  /**
   * Adds a new value to the collection, or updates an existing value. This
   * method passes control directly to the
   * {@link #setValue(Comparable, Number)} method.
   *
   * @param key
   *            the key (<code>null</code> not permitted).
   * @param value
   *            the value (<code>null</code> permitted).
   */
  public void addValue(final Comparable key, final Number value) {
    this.setValue(key, value);
  }

  /**
   * Clears all values from the collection.
   *
   * @since 1.0.2
   */
  public void clear() {
    this.data.clear();
    this.key2Index.clear();
  }

  /**
   * Returns a clone.
   *
   * @return A clone.
   *
   * @throws CloneNotSupportedException
   *             this class will not throw this exception, but subclasses
   *             might.
   */
  public Object clone() throws CloneNotSupportedException {
    final DefaultKeyedValues clone = (DefaultKeyedValues) super.clone();
    clone.data = (List) ObjectUtilities.deepClone(this.data);
    return clone;
  }

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

    if (!(obj instanceof KeyedValues)) {
      return false;
    }

    final KeyedValues that = (KeyedValues) obj;
    final int count = this.getItemCount();
    if (count != that.getItemCount()) {
      return false;
    }

    for (int i = 0; i < count; i++) {
      final Comparable k1 = this.getKey(i);
      final Comparable k2 = that.getKey(i);
      if (!k1.equals(k2)) {
        return false;
      }
      final Number v1 = this.getValue(i);
      final Number v2 = that.getValue(i);
      if (v1 == null) {
        if (v2 != null) {
          return false;
        }
      } else {
        if (!v1.equals(v2)) {
          return false;
        }
      }
    }
    return true;
  }

  /**
   * Returns the index for a given key.
   *
   * @param key
   *            the key (<code>null</code> not permitted).
   *
   * @return The index, or <code>-1</code> if the key is not recognised.
   *
   * @throws IllegalArgumentException
   *             if <code>key</code> is <code>null</code>.
   */
  public int getIndex(final Comparable key) {
    if (key == null) {
      throw new IllegalArgumentException("Null 'key' argument.");
    }

    int i = -1;
    final Integer nI = (Integer) this.key2Index.get(key);
    if (nI != null) {
      i = nI.intValue();
    }

    return i;
    // int i = 0;
    // Iterator iterator = this.data.iterator();
    // while (iterator.hasNext()) {
    // KeyedValue kv = (KeyedValue) iterator.next();
    // if (kv.getKey().equals(key)) {
    // return i;
    // }
    // i++;
    // }
    // return -1; // key not found
  }

  /**
   * Returns the number of items (values) in the collection.
   *
   * @return The item count.
   */
  public int getItemCount() {
    return this.data.size();
  }

  /**
   * Returns a key.
   *
   * @param index
   *            the item index (zero-based).
   *
   * @return The row key.
   *
   * @throws IndexOutOfBoundsException
   *             if <code>item</code> is out of bounds.
   */
  public Comparable getKey(final int index) {
    Comparable result = null;
    final KeyedValue item = (KeyedValue) this.data.get(index);
    if (item != null) {
      result = item.getKey();
    }
    return result;
  }

  /**
   * Returns the keys for the values in the collection.
   *
   * @return The keys (never <code>null</code>).
   */
  public List getKeys() {
    final List result = new java.util.ArrayList();
    for (final Iterator iter = this.data.iterator(); iter.hasNext();) {
      final KeyedValue kv = (KeyedValue) iter.next();
      result.add(kv.getKey());
    }
    return result;
  }

  /**
   * Returns the value for a given key.
   *
   * @param key
   *            the key.
   *
   * @return The value (possibly <code>null</code>).
   *
   * @throws UnknownKeyException
   *             if the key is not recognised.
   */
  public Number getValue(final Comparable key) {
    final int index = this.getIndex(key);
    if (index < 0) {
      throw new UnknownKeyException("Key not found: " + key);
    }
    return this.getValue(index);
  }

  /**
   * Returns a value.
   *
   * @param item
   *            the item of interest (zero-based index).
   *
   * @return The value.
   *
   * @throws IndexOutOfBoundsException
   *             if <code>item</code> is out of bounds.
   */
  public Number getValue(final int item) {
    Number result = null;
    final KeyedValue kval = (KeyedValue) this.data.get(item);
    if (kval != null) {
      result = kval.getValue();
    }
    return result;
  }

  /**
   * Returns a hash code.
   *
   * @return A hash code.
   */
  public int hashCode() {
    return (this.data != null ? this.data.hashCode() : 0);
  }

  protected void rebuildKey2Index() {
    int i = 0;
    final Iterator iterator = this.data.iterator();
    while (iterator.hasNext()) {
      final KeyedValue kv = (KeyedValue) iterator.next();
      this.key2Index.put(kv.getKey(), new Integer(i));
      i++;
    }
  }

  /**
   * Removes a value from the collection. If there is no item with the
   * specified key, this method does nothing.
   *
   * @param key
   *            the item key (<code>null</code> not permitted).
   *
   * @throws IllegalArgumentException
   *             if <code>key</code> is <code>null</code>.
   */
  public void removeValue(final Comparable key) {
    final int index = this.getIndex(key);
    if (index >= 0) {
      this.removeValue(index);
    }
  }

  /**
   * Removes a value from the collection.
   *
   * @param index
   *            the index of the item to remove (in the range <code>0</code>
   *            to <code>getItemCount() - 1</code>).
   *
   * @throws IndexOutOfBoundsException
   *             if <code>index</code> is not within the specified range.
   */
  public void removeValue(final int index) {
    final DefaultKeyedValue kv = (DefaultKeyedValue) this.data.get(index);
    this.key2Index.remove(kv.getKey());
    this.data.remove(index);
  }

  /**
   * Updates an existing value, or adds a new value to the collection.
   *
   * @param key
   *            the key (<code>null</code> not permitted).
   * @param value
   *            the value.
   */
  public void setValue(final Comparable key, final double value) {
    this.setValue(key, new Double(value));
  }

  /**
   * Updates an existing value, or adds a new value to the collection.
   *
   * @param key
   *            the key (<code>null</code> not permitted).
   * @param value
   *            the value (<code>null</code> permitted).
   */
  public void setValue(final Comparable key, final Number value) {
    if (key == null) {
      throw new IllegalArgumentException("Null 'key' argument.");
    }
    final int keyIndex = this.getIndex(key);
    if (keyIndex >= 0) {
      final DefaultKeyedValue kv = (DefaultKeyedValue) this.data
          .get(keyIndex);
      kv.setValue(value);
    } else {
      final KeyedValue kv = new DefaultKeyedValue(key, value);
      this.data.add(kv);
      final int index = this.data.size() - 1;
      this.key2Index.put(key, new Integer(index));
    }
  }

  /**
   * Sorts the items in the list by key.
   *
   * @param order
   *            the sort order (<code>null</code> not permitted).
   */
  public void sortByKeys(final SortOrder order) {
    final Comparator comparator = new KeyedValueComparator(
        KeyedValueComparatorType.BY_KEY, order);
    Collections.sort(this.data, comparator);

    this.rebuildKey2Index();
  }

  /**
   * Sorts the items in the list by value. If the list contains
   * <code>null</code> values, they will sort to the end of the list,
   * irrespective of the sort order.
   *
   * @param order
   *            the sort order (<code>null</code> not permitted).
   */
  public void sortByValues(final SortOrder order) {
    final Comparator comparator = new KeyedValueComparator(
        KeyedValueComparatorType.BY_VALUE, order);
    Collections.sort(this.data, comparator);

    this.rebuildKey2Index();
  }

}
TOP

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

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.