public class ResizableDoubleArray extends java.lang.Object implements DoubleArray, java.io.Serializable
A variable length DoubleArray
implementation that automatically
handles expanding and contracting its internal storage array as elements
are added and removed.
The internal storage array starts with capacity determined by the
initialCapacity
property, which can be set by the constructor.
The default initial capacity is 16. Adding elements using
addElement(double)
appends elements to the end of the array. When
there are no open entries at the end of the internal storage array, the
array is expanded. The size of the expanded array depends on the
expansionMode
and expansionFactor
properties.
The expansionMode
determines whether the size of the array is
multiplied by the expansionFactor
(MULTIPLICATIVE_MODE) or if
the expansion is additive (ADDITIVE_MODE -- expansionFactor
storage locations added). The default expansionMode
is
MULTIPLICATIVE_MODE and the default expansionFactor
is 2.0.
The addElementRolling(double)
method adds a new element to the end
of the internal storage array and adjusts the "usable window" of the
internal array forward by one position (effectively making what was the
second element the first, and so on). Repeated activations of this method
(or activation of discardFrontElements(int)
) will effectively orphan
the storage locations at the beginning of the internal storage array. To
reclaim this storage, each time one of these methods is activated, the size
of the internal storage array is compared to the number of addressable
elements (the numElements
property) and if the difference
is too large, the internal array is contracted to size
numElements + 1.
The determination of when the internal
storage array is "too large" depends on the expansionMode
and
contractionFactor
properties. If the expansionMode
is MULTIPLICATIVE_MODE
, contraction is triggered when the
ratio between storage array length and numElements
exceeds
contractionFactor.
If the expansionMode
is ADDITIVE_MODE,
the number of excess storage locations
is compared to contractionFactor.
To avoid cycles of expansions and contractions, the
expansionFactor
must not exceed the
contractionFactor.
Constructors and mutators for both of these
properties enforce this requirement, throwing IllegalArgumentException if it
is violated.
Modifier and Type | Field and Description |
---|---|
static int |
ADDITIVE_MODE
additive expansion mode
|
protected float |
contractionCriteria
The contraction criteria determines when the internal array will be
contracted to fit the number of elements contained in the element
array + 1.
|
protected float |
expansionFactor
The expansion factor of the array.
|
protected int |
expansionMode
Determines whether array expansion by
expansionFactor
is additive or multiplicative. |
protected int |
initialCapacity
The initial capacity of the array.
|
protected double[] |
internalArray
The internal storage array.
|
static int |
MULTIPLICATIVE_MODE
multiplicative expansion mode
|
protected int |
numElements
The number of addressable elements in the array.
|
protected int |
startIndex
The position of the first addressable element in the internal storage
array.
|
Constructor and Description |
---|
ResizableDoubleArray()
Create a ResizableArray with default properties.
|
ResizableDoubleArray(int initialCapacity)
Create a ResizableArray with the specified initial capacity.
|
ResizableDoubleArray(int initialCapacity,
float expansionFactor)
Create a ResizableArray with the specified initial capacity
and expansion factor.
|
ResizableDoubleArray(int initialCapacity,
float expansionFactor,
float contractionCriteria)
Create a ResizableArray with the specified initialCapacity,
expansionFactor, and contractionCriteria.
|
ResizableDoubleArray(int initialCapacity,
float expansionFactor,
float contractionCriteria,
int expansionMode)
Create a ResizableArray with the specified properties.
|
ResizableDoubleArray(ResizableDoubleArray original)
Copy constructor.
|
Modifier and Type | Method and Description |
---|---|
void |
addElement(double value)
Adds an element to the end of this expandable array.
|
double |
addElementRolling(double value)
Adds an element to the end of the array and removes the first
element in the array.
|
protected void |
checkContractExpand(float contraction,
float expansion)
Checks the expansion factor and the contraction criteria and throws an
IllegalArgumentException if the contractionCriteria is less than the
expansionCriteria
|
void |
clear()
Clear the array, reset the size to the initialCapacity and the number
of elements to zero.
|
void |
contract()
Contracts the storage array to the (size of the element set) + 1 - to
avoid a zero length array.
|
ResizableDoubleArray |
copy()
Returns a copy of the ResizableDoubleArray.
|
static void |
copy(ResizableDoubleArray source,
ResizableDoubleArray dest)
Copies source to dest, copying the underlying data, so dest is
a new, independent copy of source.
|
void |
discardFrontElements(int i)
Discards the
i |
void |
discardMostRecentElements(int i)
Discards the
i |
boolean |
equals(java.lang.Object object)
Returns true iff object is a ResizableDoubleArray with the same properties
as this and an identical internal storage array.
|
protected void |
expand()
Expands the internal storage array using the expansion factor.
|
float |
getContractionCriteria()
The contraction criteria defines when the internal array will contract
to store only the number of elements in the element array.
|
double |
getElement(int index)
Returns the element at the specified index
|
double[] |
getElements()
Returns a double array containing the elements of this
ResizableArray . |
float |
getExpansionFactor()
The expansion factor controls the size of a new array when an array
needs to be expanded.
|
int |
getExpansionMode()
The
expansionMode determines whether the internal storage
array grows additively (ADDITIVE_MODE) or multiplicatively
(MULTIPLICATIVE_MODE) when it is expanded. |
double[] |
getInternalValues()
Returns the internal storage array.
|
int |
getNumElements()
Returns the number of elements currently in the array.
|
double[] |
getValues()
Deprecated.
replaced by
getInternalValues() as of 2.0 |
int |
hashCode()
Returns a hash code consistent with equals.
|
void |
setContractionCriteria(float contractionCriteria)
Sets the contraction criteria for this ExpandContractDoubleArray.
|
void |
setElement(int index,
double value)
Sets the element at the specified index.
|
void |
setExpansionFactor(float expansionFactor)
Sets the expansionFactor.
|
void |
setExpansionMode(int expansionMode)
Sets the
expansionMode . |
protected void |
setInitialCapacity(int initialCapacity)
Sets the initial capacity.
|
void |
setNumElements(int i)
This function allows you to control the number of elements contained
in this array, and can be used to "throw out" the last n values in an
array.
|
int |
start()
Returns the starting index of the internal array.
|
double |
substituteMostRecentElement(double value)
Substitutes
value for the most recently added value. |
public static final int ADDITIVE_MODE
public static final int MULTIPLICATIVE_MODE
protected float contractionCriteria
protected float expansionFactor
internalArray.length * expansionFactor
if expansionMode
is set to MULTIPLICATIVE_MODE, or
internalArray.length + expansionFactor
if
expansionMode
is set to ADDITIVE_MODE.protected int expansionMode
expansionFactor
is additive or multiplicative.protected int initialCapacity
protected double[] internalArray
protected int numElements
protected int startIndex
internalArray[startIndex],...,internalArray[startIndex + numElements -1]
public ResizableDoubleArray()
initialCapacity = 16
expansionMode = MULTIPLICATIVE_MODE
expansionFactor = 2.5
contractionFactor = 2.0
public ResizableDoubleArray(int initialCapacity)
expansionMode = MULTIPLICATIVE_MODE
expansionFactor = 2.5
contractionFactor = 2.0
initialCapacity
- The initial size of the internal storage arrayjava.lang.IllegalArgumentException
- if initialCapacity is not > 0public ResizableDoubleArray(int initialCapacity, float expansionFactor)
Create a ResizableArray with the specified initial capacity and expansion factor. The remaining properties take default values:
expansionMode = MULTIPLICATIVE_MODE
contractionFactor = 0.5 + expansionFactor
Throws IllegalArgumentException if the following conditions are not met:
initialCapacity > 0
expansionFactor > 1
initialCapacity
- The initial size of the internal storage arrayexpansionFactor
- the array will be expanded based on this
parameterjava.lang.IllegalArgumentException
- if parameters are not validpublic ResizableDoubleArray(int initialCapacity, float expansionFactor, float contractionCriteria)
Create a ResizableArray with the specified initialCapacity,
expansionFactor, and contractionCriteria. The expansionMode
will default to MULTIPLICATIVE_MODE.
Throws IllegalArgumentException if the following conditions are not met:
initialCapacity > 0
expansionFactor > 1
contractionFactor >= expansionFactor
initialCapacity
- The initial size of the internal storage arrayexpansionFactor
- the array will be expanded based on this
parametercontractionCriteria
- The contraction Criteria.java.lang.IllegalArgumentException
- if parameters are not validpublic ResizableDoubleArray(int initialCapacity, float expansionFactor, float contractionCriteria, int expansionMode)
Create a ResizableArray with the specified properties.
Throws IllegalArgumentException if the following conditions are not met:
initialCapacity > 0
expansionFactor > 1
contractionFactor >= expansionFactor
expansionMode in {MULTIPLICATIVE_MODE, ADDITIVE_MODE}
initialCapacity
- the initial size of the internal storage arrayexpansionFactor
- the array will be expanded based on this
parametercontractionCriteria
- the contraction CriteriaexpansionMode
- the expansion modejava.lang.IllegalArgumentException
- if parameters are not validpublic ResizableDoubleArray(ResizableDoubleArray original)
original
- array to copypublic void addElement(double value)
addElement
in interface DoubleArray
value
- to be added to end of arraypublic double addElementRolling(double value)
Adds an element to the end of the array and removes the first element in the array. Returns the discarded first element. The effect is similar to a push operation in a FIFO queue.
Example: If the array contains the elements 1, 2, 3, 4 (in that order) and addElementRolling(5) is invoked, the result is an array containing the entries 2, 3, 4, 5 and the value returned is 1.
addElementRolling
in interface DoubleArray
value
- the value to be added to the arraypublic double substituteMostRecentElement(double value)
value
for the most recently added value.
Returns the value that has been replaced. If the array is empty (i.e.
if numElements
is zero), a MathRuntimeException is thrown.value
- new value to substitute for the most recently added valueprotected void checkContractExpand(float contraction, float expansion)
expansion
- factor to be checkedcontraction
- criteria to be checkedjava.lang.IllegalArgumentException
- if the contractionCriteria is less than
the expansionCriteria.public void clear()
clear
in interface DoubleArray
public void contract()
public void discardFrontElements(int i)
i initial elements of the array. For example,
if the array contains the elements 1,2,3,4, invoking
discardFrontElements(2)
will cause the first two elements
to be discarded, leaving 3,4 in the array. Throws illegalArgumentException
if i exceeds numElements.
i
- the number of elements to discard from the front of the arrayjava.lang.IllegalArgumentException
- if i is greater than numElements.public void discardMostRecentElements(int i)
i last elements of the array. For example,
if the array contains the elements 1,2,3,4, invoking
discardMostRecentElements(2)
will cause the last two elements
to be discarded, leaving 1,2 in the array. Throws illegalArgumentException
if i exceeds numElements.
i
- the number of elements to discard from the end of the arrayjava.lang.IllegalArgumentException
- if i is greater than numElements.protected void expand()
if expansionMode
is set to MULTIPLICATIVE_MODE,
the new array size will be internalArray.length * expansionFactor.
If expansionMode
is set to ADDITIVE_MODE, the length
after expansion will be internalArray.length + expansionFactor
public float getContractionCriteria()
expansionMode
is MULTIPLICATIVE_MODE
,
contraction is triggered when the ratio between storage array length
and numElements
exceeds contractionFactor
.
If the expansionMode
is ADDITIVE_MODE
, the
number of excess storage locations is compared to
contractionFactor.
public double getElement(int index)
getElement
in interface DoubleArray
index
- index to fetch a value fromjava.lang.ArrayIndexOutOfBoundsException
- if index
is less than
zero or is greater than getNumElements() - 1
.public double[] getElements()
ResizableArray
. This method returns a copy, not a
reference to the underlying array, so that changes made to the returned
array have no effect on this ResizableArray.
getElements
in interface DoubleArray
public float getExpansionFactor()
expansionMode
determines whether the size of the array is multiplied by the
expansionFactor
(MULTIPLICATIVE_MODE) or if
the expansion is additive (ADDITIVE_MODE -- expansionFactor
storage locations added). The default expansionMode
is
MULTIPLICATIVE_MODE and the default expansionFactor
is 2.0.public int getExpansionMode()
expansionMode
determines whether the internal storage
array grows additively (ADDITIVE_MODE) or multiplicatively
(MULTIPLICATIVE_MODE) when it is expanded.public int getNumElements()
getNumElements
in interface DoubleArray
@Deprecated public double[] getValues()
getInternalValues()
as of 2.0startIndex
is
required (available via the start()
method). This method should
only be used in cases where copying the internal array is not practical.
The getElements()
method should be used in all other cases.public double[] getInternalValues()
startIndex
is
required (available via the start()
method). This method should
only be used in cases where copying the internal array is not practical.
The getElements()
method should be used in all other cases.public void setContractionCriteria(float contractionCriteria)
contractionCriteria
- contraction criteriapublic void setElement(int index, double value)
getNumElements() - 1
, the numElements
property
is increased to index +1
and additional storage is allocated
(if necessary) for the new element and all (uninitialized) elements
between the new element and the previous end of the array).setElement
in interface DoubleArray
index
- index to store a value invalue
- value to store at the specified indexjava.lang.ArrayIndexOutOfBoundsException
- if index
is less than
zero.public void setExpansionFactor(float expansionFactor)
expansionFactor > 1
contractionFactor >= expansionFactor
expansionFactor
- the new expansion factor value.java.lang.IllegalArgumentException
- if expansionFactor is <= 1 or greater
than contractionFactorpublic void setExpansionMode(int expansionMode)
expansionMode
. The specified value must be one of
ADDITIVE_MODE, MULTIPLICATIVE_MODE.expansionMode
- The expansionMode to set.java.lang.IllegalArgumentException
- if the specified mode value is not validprotected void setInitialCapacity(int initialCapacity)
initialCapacity
- of the arrayjava.lang.IllegalArgumentException
- if initialCapacity
is not
positive.public void setNumElements(int i)
i
- a new number of elementsjava.lang.IllegalArgumentException
- if i
is negative.public int start()
internalArray[startIndex],...,internalArray[startIndex + numElements -1]
public static void copy(ResizableDoubleArray source, ResizableDoubleArray dest)
Copies source to dest, copying the underlying data, so dest is a new, independent copy of source. Does not contract before the copy.
Obtains synchronization locks on both source and dest (in that order) before performing the copy.
Neither source nor dest may be null; otherwise a NullPointerException is thrown
source
- ResizableDoubleArray to copydest
- ResizableArray to replace with a copy of the source arraypublic ResizableDoubleArray copy()
public boolean equals(java.lang.Object object)
equals
in class java.lang.Object
object
- object to be compared for equality with thispublic int hashCode()
hashCode
in class java.lang.Object