Difference between revisions of "User:Chase-san/VDA"
Jump to navigation
Jump to search
m (minor fix) |
m (reformatting) |
||
Line 13: | Line 13: | ||
* | * | ||
* @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 30: | ||
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 62: | ||
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 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 160: | ||
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 167: | ||
return new VDA<T>(dims); | return new VDA<T>(dims); | ||
} | } | ||
− | + | ||
/** | /** | ||
* Creates the final data array | * Creates the final data array | ||
Line 164: | Line 173: | ||
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 | ||
Line 180: | Line 190: | ||
private int getIndex(int[] pos) { | private 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 205: | ||
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]; | ||
} | } |
Revision as of 01:35, 1 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!
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 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 */ private 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; } }