/**
* Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.financial.analytics;
import java.util.Arrays;
import org.apache.commons.lang.Validate;
import com.opengamma.financial.analytics.QuickSorter.ArrayQuickSorter;
/**
* @param <TKey> the type of the keys
* @param <TValue> the type of the values
* @param <TTolerance> the type of the tolerance
*/
public abstract class LabelledObjectMatrix1D<TKey extends Comparable<? super TKey>, TValue, TTolerance> {
private final String _labelsTitle;
private final String _valuesTitle;
private final TKey[] _keys;
private final Object[] _labels;
private final TValue[] _values;
private final TTolerance _defaultTolerance;
public LabelledObjectMatrix1D(final TKey[] keys, final TValue[] values, final TTolerance defaultTolerance) {
this(keys, LabelledMatrixUtils.toString(keys), values, defaultTolerance);
}
public LabelledObjectMatrix1D(final TKey[] keys, final Object[] labels, final TValue[] values, final TTolerance defaultTolerance) {
this(keys, labels, null, values, null, defaultTolerance);
}
public LabelledObjectMatrix1D(final TKey[] keys, final String labelsTitle, final TValue[] values, final String valuesTitle, final TTolerance defaultTolerance) {
this(keys, LabelledMatrixUtils.toString(keys), labelsTitle, values, valuesTitle, defaultTolerance);
}
public LabelledObjectMatrix1D(TKey[] keys, Object[] labels, String labelsTitle, TValue[] values, String valuesTitle, TTolerance defaultTolerance) {
Validate.notNull(keys, "labels");
Validate.notNull(labels, "label names");
Validate.notNull(values, "values");
final int n = keys.length;
Validate.isTrue(n == labels.length, "length of keys array must match length of label names array");
Validate.isTrue(n == values.length, "length of keys array must match length of values array");
_keys = Arrays.copyOf(keys, n);
_labels = Arrays.copyOf(labels, n);
_labelsTitle = labelsTitle;
_values = Arrays.copyOf(values, n);
_valuesTitle = valuesTitle;
_defaultTolerance = defaultTolerance;
quickSort();
}
public TKey[] getKeys() {
return _keys;
}
public Object[] getLabels() {
return _labels;
}
public String getLabelsTitle() {
return _labelsTitle;
}
public TValue[] getValues() {
return _values;
}
public String getValuesTitle() {
return _valuesTitle;
}
public int size() {
return _keys.length;
}
protected TTolerance getDefaultTolerance() {
return _defaultTolerance;
}
/**
* Compares two keys and indicates whether the first would be considered less than, equal to or greater than the
* second.
*
* @param key1 the first key to compare, not null
* @param key2 the second key to compare, not null
* @param tolerance the tolerance for equality of the keys
* @return the value 0 if {@code key1} is equal to {@code key2}; a value less than 0 if {@code key1} is less than
* {@code key2}; and a value greater than 0 if {@code key1} is greater than {@code key2}.
*/
public abstract int compare(TKey key1, TKey key2, TTolerance tolerance);
/**
* Compares two keys using the default equality tolerance, and indicates whether the first would be considered less
* than, equal to or greater than the second.
*
* @param key1 the first key to compare, not null
* @param key2 the second key to compare, not null
* @return the value 0 if {@code key1} is equal to {@code key2}; a value less than 0 if {@code key1} is less than
* {@code key2}; and a value greater than 0 if {@code key1} is greater than {@code key2}.
*/
public int compare(final TKey key1, final TKey key2) {
return compare(key1, key2, getDefaultTolerance());
}
private void quickSort() {
(new ArrayQuickSorter<TKey>(_keys) {
@Override
protected int compare(final TKey first, final TKey second) {
return LabelledObjectMatrix1D.this.compare(first, second);
}
@Override
protected void swap(final int first, final int second) {
super.swap(first, second);
swap(_labels, first, second);
swap(_values, first, second);
}
}).sort();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + Arrays.hashCode(_keys);
result = prime * result + Arrays.hashCode(_labels);
result = prime * result + ((_labelsTitle == null) ? 0 : _labelsTitle.hashCode());
result = prime * result + Arrays.hashCode(_values);
result = prime * result + ((_valuesTitle == null) ? 0 : _valuesTitle.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final LabelledObjectMatrix1D<?, ?, ?> other = (LabelledObjectMatrix1D<?, ?, ?>) obj;
if (!Arrays.equals(_keys, other._keys)) {
return false;
}
if (!Arrays.equals(_labels, other._labels)) {
return false;
}
if (_labelsTitle == null) {
if (other._labelsTitle != null) {
return false;
}
} else if (!_labelsTitle.equals(other._labelsTitle)) {
return false;
}
if (!Arrays.equals(_values, other._values)) {
return false;
}
if (_valuesTitle == null) {
if (other._valuesTitle != null) {
return false;
}
} else if (!_valuesTitle.equals(other._valuesTitle)) {
return false;
}
return true;
}
}