package dynaop.util;
import java.lang.reflect.Array;
import java.util.Iterator;
/**
* Implements <code>hashCode()</code> and <code>equals()</code>
* functionality for an array. Useful when keying a <code>Map</code>
* with arrays, comparing two arrays for equality, or implementing toString()
* for an array.
*
* <p>Does not make a defensive copy; behavior
* changes with associated array. Does not account for circularly
* linked arrays.
*
* @author Bob Lee (crazybob@crazybob.org)
*/
public class ArrayObject {
private final Object array;
/**
* Constructs a object for a given array.
*/
public ArrayObject(Object array) {
if (array == null) throw new NullPointerException();
this.array = array;
}
public int hashCode() {
int hashCode = 0;
for (Iterator i = this.iterator(); i.hasNext();) {
Object element = i.next();
if (element != null)
hashCode = hashCode * 37 + element.hashCode();
}
return hashCode;
}
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof ArrayObject)) return false;
ArrayObject arrayObject = (ArrayObject) o;
if (this.length() != arrayObject.length()) return false;
Iterator i1 = this.iterator();
Iterator i2 = arrayObject.iterator();
while (i1.hasNext()) {
Object o1 = i1.next();
Object o2 = i2.next();
if (!(o1==null ? o2==null : o1.equals(o2)))
return false;
}
return true;
}
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append('[');
for (Iterator i = this.iterator(); i.hasNext();) {
buffer.append(i.next());
if (i.hasNext()) buffer.append(", ");
}
buffer.append(']');
return buffer.toString();
}
/**
* Constructs element iterator. Recursively wraps nested arrays.
*/
private Iterator iterator() {
final int length = this.length();
return new Iterator() {
private int index = 0;
public boolean hasNext() {
return index < length;
}
public Object next() {
Object element = Array.get(ArrayObject.this.array, index++);
return (element == null) ? null :
(element.getClass().isArray()) ?
new ArrayObject(element) : element;
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
/**
* Gets length of enclosed array.
*/
private int length() {
return Array.getLength(this.array);
}
/**
* Creates a defensive copy of an array.
*/
public static Object clone(Object array) {
int length = Array.getLength(array);
Object copy = Array.newInstance(array.getClass().getComponentType(),
length);
System.arraycopy(array, 0, copy, 0, length);
return copy;
}
}
|