/* ---------------------------------------------------------------------
* Numenta Platform for Intelligent Computing (NuPIC)
* Copyright (C) 2014-2016, Numenta, Inc. Unless you have an agreement
* with Numenta, Inc., for a separate license for this software code, the
* following terms and conditions apply:
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Affero Public License for more details.
*
* You should have received a copy of the GNU Affero Public License
* along with this program. If not, see http://www.gnu.org/licenses.
*
* http://numenta.org/licenses/
* ---------------------------------------------------------------------
*/
package org.numenta.nupic.util;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.numenta.nupic.model.Persistable;
/**
* An immutable fixed data structure whose values are retrieved
* via a given index. This data structure emulates multiple method
* return values possible in Python.
*
* @author David Ray
*/
public class Tuple implements Persistable, Comparable<Tuple> {
private static final long serialVersionUID = 1L;
/** The internal container array */
protected Object[] container;
private int hashcode;
private Comparator<Tuple> comparator;
public Tuple() {}
/**
* Instantiates a new {@code Tuple}
* @param objects
*/
public Tuple(Object... objects) {
remake(objects);
}
/**
* Constructs a {@code Tuple} that will use the supplied
* {@link Comparator} to implement the {@link Comparable}
* interface.
* @param c the Comparator function to use to compare the
* contents of the is {@code Tuple}
* @param objects the objects contained within
*/
public Tuple(Comparator<Tuple> c, Object...objects) {
this.comparator = c;
remake(objects);
}
/**
* Remakes the internals for this Tuple.
* @param objects
*/
protected void remake(Object...objects) {
container = new Object[objects.length];
for(int i = 0;i < objects.length;i++) container[i] = objects[i];
this.hashcode = hashCode();
}
/**
* Returns the object previously inserted into the
* specified index.
*
* @param index the index representing the insertion order.
* @return
*/
public Object get(int index) {
return container[index];
}
/**
* Returns the number of items in this {@code Tuple}
*
* @return
*/
public int size() {
return container.length;
}
/**
* Returns an <em>unmodifiable</em> view of the underlying data.
* @return
*/
public List<Object> all() {
return Collections.unmodifiableList(Arrays.asList(container));
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for(int i = 0;i < container.length;i++) {
try {
new Double((double) container[i]);
sb.append(container[i]);
}catch(Exception e) { sb.append("'").append(container[i]).append("'");}
sb.append(":");
}
sb.setLength(sb.length() - 1);
return sb.toString();
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + Arrays.hashCode(container);
return result;
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Tuple other = (Tuple) obj;
if (this.hashcode != other.hashcode)
return false;
return true;
}
/**
* Uses the supplied {@link Comparator} to compare this {@code Tuple}
* with the specified {@link Tuple}
*/
@Override
public int compareTo(Tuple t) {
if(comparator == null) {
throw new IllegalStateException("Tuples used for comparison should be " +
"instantiated using the constructor taking a Comparator");
}
return comparator.compare(this, t);
}
}