MorphicVector.java
package edu.udel.cis.vsl.tass.morph;
import java.util.Arrays;
import java.util.EmptyStackException;
import java.util.Iterator;
public class MorphicVector<T extends Morphic> extends MorphicObject implements
Iterable<T> {
private static int initialLength = 2;
private int size;
/**
* Invariant: data.length >= size. Invariant: forall size <= j <
* data.length. data[j] == null.
*/
private Morphic[] data;
/** Construct new component vector with size 0 (and initial length). */
MorphicVector() {
data = new Morphic[initialLength];
size = 0;
}
/**
* Start a new component vector with this length and size. All entries
* initially null.
*/
MorphicVector(int size) {
data = new Morphic[size];
this.size = size;
}
MorphicVector(MorphicVector<T> oldVector) {
size = oldVector.size;
data = Arrays.copyOf(oldVector.data, size);
}
public int size() {
return size;
}
public void add(T element) {
assert !isCommitted();
setElementExtend(size, element);
size++;
}
@SuppressWarnings("unchecked")
public T get(int index) throws ArrayIndexOutOfBoundsException {
if (index >= size) {
throw new ArrayIndexOutOfBoundsException(index);
}
return (T) data[index];
}
public void set(int index, T element) throws ArrayIndexOutOfBoundsException {
assert !isCommitted();
if (index >= size) {
throw new ArrayIndexOutOfBoundsException(index);
}
data[index] = element;
}
public void push(T element) {
add(element);
}
@SuppressWarnings("unchecked")
public T pop() throws EmptyStackException {
assert !isCommitted();
if (size == 0) {
throw new EmptyStackException();
} else {
size--;
T result = (T) data[size];
data[size] = null;
return result;
}
}
@SuppressWarnings("unchecked")
public T peek() throws EmptyStackException {
if (size == 0) {
throw new EmptyStackException();
} else {
return (T) data[size - 1];
}
}
public T removeElementAt(int position)
throws ArrayIndexOutOfBoundsException {
T result = get(position);
for (int i = position; i < size - 1; i++)
data[i] = data[i + 1];
size--;
data[size] = null;
return result;
}
private void setElementExtend(int index, T value) {
int length = data.length;
if (length == 0)
length = 1;
while (index >= length)
length *= 2;
if (length != data.length) {
data = Arrays.copyOf(data, length);
}
data[index] = value;
}
public void setExtend(int index, T value) {
if (index >= size)
setSize(index + 1);
set(index, value);
}
public void setSize(int newSize) {
if (newSize == size) {
return;
} else if (newSize < size) {
for (int i = newSize; i < size; i++)
data[i] = null;
} else {
setElementExtend(newSize - 1, null);
}
size = newSize;
}
@Override
protected boolean computeEquals(Morphic component) {
if (component instanceof MorphicVector<?>) {
MorphicVector<?> that = (MorphicVector<?>) component;
if (size != that.size())
return false;
for (int i = 0; i < size; i++) {
Morphic thisElement = data[i];
Morphic thatElement = that.data[i];
if (thisElement == null) {
if (thatElement != null)
return false;
} else {
if (thatElement == null || !thisElement.equals(thatElement))
return false;
}
}
return true;
}
return false;
}
@Override
protected int computeHashCode() {
int result = 0;
for (int i = 0; i < size; i++) {
Morphic datum = data[i];
if (datum != null)
result += datum.hashCode();
}
return result;
}
@SuppressWarnings("unchecked")
public void canonicalizeChildren(MorphicFactoryIF<? super T> elementFactory) {
for (int i = 0; i < size; i++) {
Morphic datum = data[i];
if (datum != null) {
Morphic newDatum = elementFactory.canonic((T) datum);
if (datum != newDatum)
data[i] = newDatum;
}
}
}
public int numChildren() {
return size;
}
@Override
protected void commitChildren() {
for (Morphic datum : data) {
if (datum != null)
datum.commit();
}
}
@Override
public Iterator<T> iterator() {
return new MorphicVectorIterator<T>(data, size);
}
@Override
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("[");
for (int i = 0; i < size; i++) {
if (i > 0)
buffer.append(", ");
buffer.append(data[i]);
}
buffer.append("]");
return buffer.toString();
}
class MorphicVectorIterator<S extends Morphic> implements Iterator<S> {
Morphic[] data;
int size;
int index = 0;
MorphicVectorIterator(Morphic[] data, int size) {
this.data = data;
this.size = size;
}
@Override
public boolean hasNext() {
return index < size;
}
@SuppressWarnings("unchecked")
@Override
public S next() {
S result = (S) data[index];
index++;
return result;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
}