Difference between revisions of "User:Chase-san/VDA"
Jump to navigation
Jump to search
m (minor fix) |
(My packages are how they are for a reason (this applies to more than just robocode).) |
||
(8 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
+ | [[Category:Code Snippets|VDA]] | ||
A variable dimension array I wrote up trying to figure out a way I could have a variable number of segment buffers without having to know how many I had in advance. It turned out pretty well! | A variable dimension array I wrote up trying to figure out a way I could have a variable number of segment buffers without having to know how many I had in advance. It turned out pretty well! | ||
− | < | + | This and all my other code in which I display on the robowiki falls under the [http://en.wikipedia.org/wiki/Zlib_License ZLIB License]. |
+ | |||
+ | <syntaxhighlight> | ||
package org.csdgn.utils; | package org.csdgn.utils; | ||
Line 13: | Line 16: | ||
* | * | ||
* @author Chase | * @author Chase | ||
− | * | + | * |
− | * @param <T> Type of data contained | + | * @param <T> |
+ | * Type of data contained | ||
*/ | */ | ||
public class VDA<T> implements Serializable, Cloneable { | public class VDA<T> implements Serializable, Cloneable { | ||
private static final long serialVersionUID = 3816532930303382063L; | private static final long serialVersionUID = 3816532930303382063L; | ||
− | + | ||
private T[] data = null; | private T[] data = null; | ||
private int[] dims = null; | private int[] dims = null; | ||
private boolean constructed = false; | private boolean constructed = false; | ||
− | + | ||
/** | /** | ||
* Initializes the VDA with 0 dimensions. | * Initializes the VDA with 0 dimensions. | ||
Line 29: | Line 33: | ||
dims = new int[0]; | dims = new int[0]; | ||
} | } | ||
− | + | ||
/** | /** | ||
* Initializes the VDA with the given number of dimensions | * Initializes the VDA with the given number of dimensions | ||
+ | * | ||
* @param dimensions | * @param dimensions | ||
*/ | */ | ||
− | public VDA(int ... dimensions) { | + | public VDA(int... dimensions) { |
if(dimensions == null) | if(dimensions == null) | ||
throw new NullPointerException(); | throw new NullPointerException(); | ||
dims = (int[])dimensions.clone(); | dims = (int[])dimensions.clone(); | ||
} | } | ||
− | + | ||
/** | /** | ||
− | * @param size Must be at least 2 | + | * @param size |
+ | * Must be at least 2 | ||
*/ | */ | ||
public void add(int size) { | public void add(int size) { | ||
if(size < 2) | if(size < 2) | ||
throw new IllegalArgumentException("Dimension size must be at least 2."); | throw new IllegalArgumentException("Dimension size must be at least 2."); | ||
− | dims = Arrays.copyOf(dims, dims.length+1); | + | dims = Arrays.copyOf(dims, dims.length + 1); |
− | dims[dims.length-1] = size; | + | dims[dims.length - 1] = size; |
constructed = false; | constructed = false; | ||
} | } | ||
− | + | ||
/** | /** | ||
− | * @param index Must be between 0 and number of dimensions | + | * @param index |
+ | * Must be between 0 and number of dimensions | ||
*/ | */ | ||
public void remove(int index) { | public void remove(int index) { | ||
Line 58: | Line 65: | ||
throw new IndexOutOfBoundsException(); | throw new IndexOutOfBoundsException(); | ||
int[] tmp = dims; | int[] tmp = dims; | ||
− | dims = Arrays.copyOf(dims, dims.length-1); | + | dims = Arrays.copyOf(dims, dims.length - 1); |
if(index < dims.length) { | if(index < dims.length) { | ||
− | System.arraycopy(tmp, index+1, dims, index, dims.length - index); | + | System.arraycopy(tmp, index + 1, dims, index, dims.length - index); |
} | } | ||
constructed = false; | constructed = false; | ||
} | } | ||
− | + | ||
/** | /** | ||
* Get the value at the given dimension | * Get the value at the given dimension | ||
*/ | */ | ||
− | public T get(int ... pos) { | + | public T get(int... pos) { |
if(pos == null) | if(pos == null) | ||
throw new NullPointerException(); | throw new NullPointerException(); | ||
if(dims.length == 0 || pos.length != dims.length) | if(dims.length == 0 || pos.length != dims.length) | ||
throw new IllegalArgumentException("Incorrect or Bad Dimensionality."); | throw new IllegalArgumentException("Incorrect or Bad Dimensionality."); | ||
− | if(!constructed) construct(); | + | if(!constructed) |
+ | construct(); | ||
return data[getIndex(pos)]; | return data[getIndex(pos)]; | ||
} | } | ||
− | + | ||
/** | /** | ||
* Set the value at the given dimension | * Set the value at the given dimension | ||
*/ | */ | ||
− | public void set(T value, int ... pos) { | + | public void set(T value, int... pos) { |
if(pos == null) | if(pos == null) | ||
throw new NullPointerException(); | throw new NullPointerException(); | ||
if(dims.length == 0 || pos.length != dims.length) | if(dims.length == 0 || pos.length != dims.length) | ||
throw new IllegalArgumentException("Incorrect or Bad Dimensionality."); | throw new IllegalArgumentException("Incorrect or Bad Dimensionality."); | ||
− | if(!constructed) construct(); | + | if(!constructed) |
+ | construct(); | ||
data[getIndex(pos)] = value; | data[getIndex(pos)] = value; | ||
} | } | ||
− | + | /** | |
+ | * Returns the size of this VDA | ||
+ | * @return | ||
+ | */ | ||
+ | public int[] getSize() { | ||
+ | return dims.clone(); | ||
+ | } | ||
+ | |||
/** | /** | ||
* Returns the bottom array at the given position | * Returns the bottom array at the given position | ||
*/ | */ | ||
− | public Object[] getSubArray(int ... pos) { | + | public Object[] getSubArray(int... pos) { |
if(pos.length != dims.length - 1) | if(pos.length != dims.length - 1) | ||
− | throw new UnsupportedOperationException( | + | throw new UnsupportedOperationException("Dimensionality must be one less than the total supported."); |
− | + | if(!constructed) | |
− | if(!constructed) construct(); | + | construct(); |
int start = getIndex(pos); | int start = getIndex(pos); | ||
− | int length = dims[dims.length-1]; | + | int length = dims[dims.length - 1]; |
T[] output = createArray(length); | T[] output = createArray(length); | ||
System.arraycopy(data, start, output, 0, length); | System.arraycopy(data, start, output, 0, length); | ||
return output; | return output; | ||
} | } | ||
− | + | ||
/** | /** | ||
* Sets the bottom array at the given position | * Sets the bottom array at the given position | ||
*/ | */ | ||
− | public void setSubArray(T[] array, int ... pos) { | + | public void setSubArray(T[] array, int... pos) { |
if(pos.length != dims.length - 1) | if(pos.length != dims.length - 1) | ||
− | throw new UnsupportedOperationException( | + | throw new UnsupportedOperationException("Dimensionality must be one less than the total supported."); |
− | + | if(!constructed) | |
− | if(!constructed) construct(); | + | construct(); |
int start = getIndex(pos); | int start = getIndex(pos); | ||
− | int length = Math.min(dims[dims.length-1], array.length); | + | int length = Math.min(dims[dims.length - 1], array.length); |
System.arraycopy(array, 0, data, start, length); | System.arraycopy(array, 0, data, start, length); | ||
} | } | ||
− | + | ||
/** | /** | ||
* @return the array that backs this VDA | * @return the array that backs this VDA | ||
*/ | */ | ||
public Object[] getBackingArray() { | public Object[] getBackingArray() { | ||
− | if(!constructed) construct(); | + | if(!constructed) |
+ | construct(); | ||
return data; | return data; | ||
} | } | ||
− | + | ||
/** | /** | ||
* Returns an array containing all of the elements in this VDA | * Returns an array containing all of the elements in this VDA | ||
*/ | */ | ||
public Object[] toArray() { | public Object[] toArray() { | ||
− | if(!constructed) construct(); | + | if(!constructed) |
+ | construct(); | ||
return data.clone(); | return data.clone(); | ||
} | } | ||
− | + | ||
/** | /** | ||
* Returns an array containing all of the elements in this VDA | * Returns an array containing all of the elements in this VDA | ||
*/ | */ | ||
− | + | @SuppressWarnings("unchecked") | |
public T[] toArray(T[] a) { | public T[] toArray(T[] a) { | ||
− | + | if(!constructed) | |
− | + | construct(); | |
− | + | return (T[])Arrays.copyOf(data, data.length, a.getClass()); | |
− | + | } | |
+ | |||
/** | /** | ||
− | * Sets this VDA to be equal to the given VDA. Data and dimensions are copied. | + | * Sets this VDA to be equal to the given VDA. Data and dimensions are |
+ | * copied. | ||
*/ | */ | ||
public void set(VDA<T> vda) { | public void set(VDA<T> vda) { | ||
Line 151: | Line 171: | ||
constructed = vda.constructed; | constructed = vda.constructed; | ||
} | } | ||
− | + | ||
/** | /** | ||
* Returns a shallow copy of this VDA (dimensions but not data) | * Returns a shallow copy of this VDA (dimensions but not data) | ||
Line 158: | Line 178: | ||
return new VDA<T>(dims); | return new VDA<T>(dims); | ||
} | } | ||
− | + | ||
/** | /** | ||
* Creates the final data array | * Creates the final data array | ||
Line 164: | Line 184: | ||
private void construct() { | private void construct() { | ||
Integer size = 1; | Integer size = 1; | ||
− | for(Integer i : dims) size *= i; | + | for(Integer i : dims) |
+ | size *= i; | ||
data = createArray(size); | data = createArray(size); | ||
constructed = true; | constructed = true; | ||
} | } | ||
− | + | ||
@SuppressWarnings("unchecked") | @SuppressWarnings("unchecked") | ||
private T[] createArray(int size) { | private T[] createArray(int size) { | ||
− | //Warning: Dangerous | + | // Warning: Dangerous |
return (T[])new Object[size]; | return (T[])new Object[size]; | ||
} | } | ||
− | + | ||
/** | /** | ||
* Gets the main arrays index from pos | * Gets the main arrays index from pos | ||
*/ | */ | ||
− | + | public int getIndex(int[] pos) { | |
Integer index = 0; | Integer index = 0; | ||
− | for(int i=0; i<pos.length; ++i) { | + | for(int i = 0; i < pos.length; ++i) { |
if(pos[i] < 0 || pos[i] >= dims[i]) | if(pos[i] < 0 || pos[i] >= dims[i]) | ||
− | throw new IndexOutOfBoundsException( | + | throw new IndexOutOfBoundsException("Index " + pos[i] + " is out of bounds for dimension " + i + "."); |
− | + | ||
− | + | index += sizeUnder(i) * pos[i]; | |
− | index += sizeUnder(i)*pos[i]; | ||
} | } | ||
System.out.println("Index " + index); | System.out.println("Index " + index); | ||
return index; | return index; | ||
} | } | ||
+ | |||
/** | /** | ||
* Gets the number of elements under the given level | * Gets the number of elements under the given level | ||
Line 195: | Line 216: | ||
private int sizeUnder(int level) { | private int sizeUnder(int level) { | ||
Integer size = 1; | Integer size = 1; | ||
− | for(int i=level+1; i<dims.length; ++i) { | + | for(int i = level + 1; i < dims.length; ++i) { |
size *= dims[i]; | size *= dims[i]; | ||
} | } | ||
Line 201: | Line 222: | ||
} | } | ||
} | } | ||
− | </ | + | </syntaxhighlight> |
Latest revision as of 03:40, 9 July 2010
A variable dimension array I wrote up trying to figure out a way I could have a variable number of segment buffers without having to know how many I had in advance. It turned out pretty well!
This and all my other code in which I display on the robowiki falls under the ZLIB License.
package org.csdgn.utils;
import java.io.Serializable;
import java.util.Arrays;
/**
* Variable Dimension Array, an array class with flexible dimensionality.
*
* Just remember (int ... x) means it accepts (0,0,0) and new int[]{0,0,0}.
*
* @author Chase
*
* @param <T>
* Type of data contained
*/
public class VDA<T> implements Serializable, Cloneable {
private static final long serialVersionUID = 3816532930303382063L;
private T[] data = null;
private int[] dims = null;
private boolean constructed = false;
/**
* Initializes the VDA with 0 dimensions.
*/
public VDA() {
dims = new int[0];
}
/**
* Initializes the VDA with the given number of dimensions
*
* @param dimensions
*/
public VDA(int... dimensions) {
if(dimensions == null)
throw new NullPointerException();
dims = (int[])dimensions.clone();
}
/**
* @param size
* Must be at least 2
*/
public void add(int size) {
if(size < 2)
throw new IllegalArgumentException("Dimension size must be at least 2.");
dims = Arrays.copyOf(dims, dims.length + 1);
dims[dims.length - 1] = size;
constructed = false;
}
/**
* @param index
* Must be between 0 and number of dimensions
*/
public void remove(int index) {
if(index < 0 || index >= dims.length)
throw new IndexOutOfBoundsException();
int[] tmp = dims;
dims = Arrays.copyOf(dims, dims.length - 1);
if(index < dims.length) {
System.arraycopy(tmp, index + 1, dims, index, dims.length - index);
}
constructed = false;
}
/**
* Get the value at the given dimension
*/
public T get(int... pos) {
if(pos == null)
throw new NullPointerException();
if(dims.length == 0 || pos.length != dims.length)
throw new IllegalArgumentException("Incorrect or Bad Dimensionality.");
if(!constructed)
construct();
return data[getIndex(pos)];
}
/**
* Set the value at the given dimension
*/
public void set(T value, int... pos) {
if(pos == null)
throw new NullPointerException();
if(dims.length == 0 || pos.length != dims.length)
throw new IllegalArgumentException("Incorrect or Bad Dimensionality.");
if(!constructed)
construct();
data[getIndex(pos)] = value;
}
/**
* Returns the size of this VDA
* @return
*/
public int[] getSize() {
return dims.clone();
}
/**
* Returns the bottom array at the given position
*/
public Object[] getSubArray(int... pos) {
if(pos.length != dims.length - 1)
throw new UnsupportedOperationException("Dimensionality must be one less than the total supported.");
if(!constructed)
construct();
int start = getIndex(pos);
int length = dims[dims.length - 1];
T[] output = createArray(length);
System.arraycopy(data, start, output, 0, length);
return output;
}
/**
* Sets the bottom array at the given position
*/
public void setSubArray(T[] array, int... pos) {
if(pos.length != dims.length - 1)
throw new UnsupportedOperationException("Dimensionality must be one less than the total supported.");
if(!constructed)
construct();
int start = getIndex(pos);
int length = Math.min(dims[dims.length - 1], array.length);
System.arraycopy(array, 0, data, start, length);
}
/**
* @return the array that backs this VDA
*/
public Object[] getBackingArray() {
if(!constructed)
construct();
return data;
}
/**
* Returns an array containing all of the elements in this VDA
*/
public Object[] toArray() {
if(!constructed)
construct();
return data.clone();
}
/**
* Returns an array containing all of the elements in this VDA
*/
@SuppressWarnings("unchecked")
public T[] toArray(T[] a) {
if(!constructed)
construct();
return (T[])Arrays.copyOf(data, data.length, a.getClass());
}
/**
* Sets this VDA to be equal to the given VDA. Data and dimensions are
* copied.
*/
public void set(VDA<T> vda) {
data = (T[])vda.data.clone();
dims = (int[])vda.dims.clone();
constructed = vda.constructed;
}
/**
* Returns a shallow copy of this VDA (dimensions but not data)
*/
public Object clone() {
return new VDA<T>(dims);
}
/**
* Creates the final data array
*/
private void construct() {
Integer size = 1;
for(Integer i : dims)
size *= i;
data = createArray(size);
constructed = true;
}
@SuppressWarnings("unchecked")
private T[] createArray(int size) {
// Warning: Dangerous
return (T[])new Object[size];
}
/**
* Gets the main arrays index from pos
*/
public int getIndex(int[] pos) {
Integer index = 0;
for(int i = 0; i < pos.length; ++i) {
if(pos[i] < 0 || pos[i] >= dims[i])
throw new IndexOutOfBoundsException("Index " + pos[i] + " is out of bounds for dimension " + i + ".");
index += sizeUnder(i) * pos[i];
}
System.out.println("Index " + index);
return index;
}
/**
* Gets the number of elements under the given level
*/
private int sizeUnder(int level) {
Integer size = 1;
for(int i = level + 1; i < dims.length; ++i) {
size *= dims[i];
}
return size;
}
}