Class AbstractArray
- Direct Known Subclasses:
AbstractBitArray
,AbstractByteArray
,AbstractCharArray
,AbstractDoubleArray
,AbstractFloatArray
,AbstractIntArray
,AbstractLongArray
,AbstractObjectArray
,AbstractShortArray
Implementation of basic functions of MutableArray
interface.
This class implements only Array
interface and doesn't implement
UpdatableArray
/ MutableArray
. (It is necessary to allow read-only arrays,
implementing Array
only, to be inheritors of AbstractArray.
In other case, the user would be able to use illegal constructions as the following:
Array ar = some immutable array (inheritor of AbstractArray); ((AbstractArray)ar)set(0, newValue);
This package guarantees that such illegal array operations are syntactically impossible.
Instead of implementing full MutableArray
interface,
this class provides default implementation for some methods of UpdatableArray
/ MutableArray
via separate protected static methods: defaultCopy(UpdatableArray, Array)
,
defaultSwap(UpdatableArray, UpdatableArray)
, defaultAppend(MutableArray, Array)
.
- Author:
- Daniel Alievsky
-
Field Summary
Modifier and TypeFieldDescriptionprotected long
The current array's capacity.protected long
The current array's length.protected Array[]
The underlying arrays passed by the last constructor argument. -
Constructor Summary
ModifierConstructorDescriptionprotected
AbstractArray
(long initialCapacityAndLength) protected
AbstractArray
(long initialCapacity, long initialLength) Equivalent toAbstractArray(initialCapacity, initialLength, new Array[0])
.protected
AbstractArray
(long initialCapacity, long initialLength, Array... underlyingArrays) Creates an array with the given initial capacity and length. -
Method Summary
Modifier and TypeMethodDescriptionabstract Array
Returns a copy-on-next-write view of this array.abstract Array
Returns an immutable view of this array.abstract Array
Returns a trusted immutable view of this array.buffer()
This implementation returnsbuffer(suitableMode)
, where suitableMode is this instanceof UpdatableArray ? DataBuffer.AccessMode.READ_WRITE : DataBuffer.AccessMode.READ.buffer
(long capacity) This implementation returnsbuffer(suitableMode, capacity)
, where capacity is the argument of this method and suitableMode is this instanceof UpdatableArray ? DataBuffer.AccessMode.READ_WRITE : DataBuffer.AccessMode.READ.buffer
(DataBuffer.AccessMode mode) This implementation returnsbuffer(mode, someCapacity)
, where mode is the argument of this method and someCapacity is the result ofdefaultBufferCapacity(thisArray)
method.buffer
(DataBuffer.AccessMode mode, long capacity) This method is fully implemented in this class.This implementation returns ByteOrder.nativeOrder().long
capacity()
This implementation returnscapacity
& Long.MAX_VALUE.static void
checkCopyArguments
(UpdatableArray thisArray, Array src) Checks whether the passed arguments correct forUpdatableArray.copy(Array)
and throws corresponding exception if no.protected final void
checkSubArrArguments
(long position, long count) Checks whether the passed arguments correct forsubArr(long, long)
and throws corresponding exception if no.protected final void
checkSubArrayArguments
(long fromIndex, long toIndex) Checks whether the passed arguments correct forsubArray(long, long)
and throws corresponding exception if no.static void
checkSwapArguments
(UpdatableArray thisArray, UpdatableArray another) Checks whether the passed arguments correct forUpdatableArray.swap(UpdatableArray)
and throws corresponding exception if no.abstract void
Tries to check, whether some unallowed mutations of thistrusted immutable
array took place, and throwUnallowedMutationError
in this case.protected static MutableArray
defaultAppend
(MutableArray thisArray, Array appendedArray) Simplest implementation ofMutableArray.append(Array)
, based onMutableArray.length(long)
,UpdatableArray.subArr(long, long)
andUpdatableArray.copy(Array)
methods.protected static DataBuffer
defaultBuffer
(Array thisArray, DataBuffer.AccessMode mode, long capacity) Default implementation ofbuffer(net.algart.arrays.DataBuffer.AccessMode, long)
method.static int
defaultBufferCapacity
(Array thisArray) Returns the data buffer capacity used bybuffer(net.algart.arrays.DataBuffer.AccessMode)
andbuffer()
methods.protected static void
defaultCopy
(UpdatableArray thisArray, Array src) Equivalent todefaultCopy(thisArray, src, false)
.protected static void
defaultCopy
(UpdatableArray thisArray, Array src, boolean allowNulls) Possible implementation ofUpdatableArray.copy(Array)
based onArray.getData(long, Object)
andUpdatableArray.setData(long, Object)
methods (for some temporary array).protected static void
defaultSwap
(UpdatableArray thisArray, UpdatableArray another) Possible implementation ofUpdatableArray.swap(UpdatableArray)
based onArray.getData(long, Object)
andUpdatableArray.setData(long, Object)
methods (for some temporary array).abstract Class<?>
Returns the type of array elements.boolean
This method is fully implemented in this class and is not be overridden usually.static boolean
Default implementation ofArray.equals(Object)
method.final void
flushResources
(ArrayContext context) This implementation just callsflushResources(context, false)
.void
flushResources
(ArrayContext context, boolean forcePhysicalWriting) This implementation calls the same method with the same arguments for all underlying arrays, passed via the last argument of theconstructor
.final void
freeResources
(ArrayContext context) This implementation just callsfreeResources(context, false)
.void
freeResources
(ArrayContext context, boolean forcePhysicalWriting) This implementation calls the same method for all underlying arrays, passed via the last argument of theconstructor
.abstract void
Copies min(this.length() - arrayPos
, destArray.length}) elements of this array, starting from arrayPos index, into the specified Java array of corresponding type, starting from 0 index.abstract void
Copies count elements of this array, starting from arrayPos index, into the specified Java array of corresponding type, starting from destArrayOffset index.abstract Object
getElement
(long index) Returns the element #index.final int
hashCode()
This method is fully implemented in this class and cannot be overridden (it is declared as final method here).static int
Default implementation ofArray.hashCode()
method.abstract boolean
Returns true if this array is copy-on-next-write.abstract boolean
Returns true if this instance is immutable, i.e. there are no ways to change its content or state.boolean
isLazy()
This implementation returnsunderlyingArrays
.length > 0.boolean
isNew()
This implementation returns a private boolean field, that is false by default, but can be changed by protectedsetNewStatus(boolean)
method.boolean
This implementation returns a private boolean field, that is false by default, but can be changed by protectedsetNewReadOnlyViewStatus()
method.abstract boolean
Returns true if this instance is unresizable, i.e. there are no ways to change its length or capacity.boolean
This method ofPArray
interface is fully implemented in this class.ja()
This implementation performs the following code:long
length()
This implementation returnslength
& Long.MAX_VALUE.void
loadResources
(ArrayContext context) This implementation does nothing.mutableClone
(MemoryModel memoryModel) abstract Class<? extends MutableArray>
Returns the canonical resizable AlgART type of arrays with the same element types: the class of one of 9 basic interfaces, describing all kinds of resizable AlgART arrays for 8 primitive and any non-primitive element types.newJavaArray
(int length) This implementation returns java.lang.reflect.Array.newInstance(elementType(), length).protected final void
Sets to true the value of the private boolean field returned byisNewReadOnlyView()
method.protected final void
setNewStatus
(boolean value) Sets the value of the private boolean field returned byisNew()
method.This implementation returnsstandardObjectClone()
.protected final AbstractArray
Performs default Object.clone() call and clears in its result bothnew status
andnew-read-only-view status
.subArr
(long position, long count) This implementation returnssubArray
(position, position + count).abstract Array
subArray
(long fromIndex, long toIndex) Returns a view of the portion of this array between fromIndex, inclusive, and toIndex, exclusive.abstract String
toString()
Returns a brief string description of this object.type()
Returns the canonical AlgART type of this array: the class of one of 9 basic interfaces, describing all kinds of AlgART arrays for 8 primitive and any non-primitive element types.updatableClone
(MemoryModel memoryModel) This implementation performs the following: memoryModel.newUnresizableArray
(thisArray).copy
(thisArray).abstract Class<? extends UpdatableArray>
Returns the canonical updatable AlgART type of arrays with the same element types: the class of one of 9 basic interfaces, describing all kinds of updatable AlgART arrays for 8 primitive and any non-primitive element types.
-
Field Details
-
capacity
protected long capacityThe current array's capacity. -
length
protected long lengthThe current array's length. -
underlyingArrays
The underlying arrays passed by the last constructor argument. It is the same reference, which was passed to the constructor (not its clone).
-
-
Constructor Details
-
AbstractArray
Creates an array with the given initial capacity and length. Does not check the initialCapacity and initialLength arguments: they may contain any values, for example, negative. Some implementations may use bit #63 for service goals.If the created array is a view of some another AlgART arrays, as result of
Arrays.asFuncArray
method, all these arrays should be passed by underlyingArrays argument. TheArray.flushResources(ArrayContext)
,Array.flushResources(ArrayContext, boolean)
andArray.freeResources(ArrayContext, boolean)
methods in the created instance, and also in all its views created bysubArray(long, long)
,subArr(long, long)
orasImmutable()
methods, will call the same methods of all underlying arrays specified by this argument.- Parameters:
initialCapacity
- initial capacity of the array.initialLength
- initial length of the array.underlyingArrays
- the created arrays is a view of the arrays passed by this argument.- Throws:
NullPointerException
- if underlyingArrays is null.
-
AbstractArray
protected AbstractArray(long initialCapacity, long initialLength) Equivalent toAbstractArray(initialCapacity, initialLength, new Array[0])
.- Parameters:
initialCapacity
- initial capacity of the array.initialLength
- initial length of the array.
-
AbstractArray
protected AbstractArray(long initialCapacityAndLength) - Parameters:
initialCapacityAndLength
- initial capacity and length of the array.
-
-
Method Details
-
elementType
Description copied from interface:Array
Returns the type of array elements. For arrays of primitive types, returns:- boolean.class for
BitArray
, - char.class for
CharArray
, - byte.class for
ByteArray
, - short.class for
ShortArray
, - int.class for
IntArray
), - long.class for
LongArray
, - float.class for
FloatArray
, - double.class for
DoubleArray
.
There is a guarantee that this method works very quickly (usually it just returns a value of some private field).
- Specified by:
elementType
in interfaceArray
- Returns:
- the type of array elements.
- See Also:
- boolean.class for
-
type
Description copied from interface:Array
Returns the canonical AlgART type of this array: the class of one of 9 basic interfaces, describing all kinds of AlgART arrays for 8 primitive and any non-primitive element types. More precisely, returns:BitArray
.class, if this object is an instance ofBitArray
,CharArray
.class, if this object is an instance ofCharArray
,ByteArray
.class, if this object is an instance ofByteArray
,ShortArray
.class, if this object is an instance ofShortArray
,IntArray
.class, if this object is an instance ofIntArray
,LongArray
.class, if this object is an instance ofLongArray
,FloatArray
.class, if this object is an instance ofFloatArray
,DoubleArray
.class, if this object is an instance ofDoubleArray
,ObjectArray
.class, if this object is an instance ofObjectArray
.
There is a guarantee that this method works very quickly (usually it just returns a constant value).
-
updatableType
Description copied from interface:Array
Returns the canonical updatable AlgART type of arrays with the same element types: the class of one of 9 basic interfaces, describing all kinds of updatable AlgART arrays for 8 primitive and any non-primitive element types. More precisely, returns:UpdatableBitArray
.class, if this object is an instance ofBitArray
,UpdatableCharArray
.class, if this object is an instance ofCharArray
,UpdatableByteArray
.class, if this object is an instance ofByteArray
,UpdatableShortArray
.class, if this object is an instance ofShortArray
,UpdatableIntArray
.class, if this object is an instance ofIntArray
,UpdatableLongArray
.class, if this object is an instance ofLongArray
,UpdatableFloatArray
.class, if this object is an instance ofFloatArray
,UpdatableDoubleArray
.class, if this object is an instance ofDoubleArray
,UpdatableObjectArray
.class, if this object is an instance ofObjectArray
.
There is a guarantee that this method works very quickly (usually it just returns a constant value).
- Specified by:
updatableType
in interfaceArray
- Returns:
- canonical AlgART type of an updatable array of the same kind.
-
mutableType
Description copied from interface:Array
Returns the canonical resizable AlgART type of arrays with the same element types: the class of one of 9 basic interfaces, describing all kinds of resizable AlgART arrays for 8 primitive and any non-primitive element types. More precisely, returns:MutableBitArray
.class, if this object is an instance ofBitArray
,MutableCharArray
.class, if this object is an instance ofCharArray
,MutableByteArray
.class, if this object is an instance ofByteArray
,MutableShortArray
.class, if this object is an instance ofShortArray
,MutableIntArray
.class, if this object is an instance ofIntArray
,MutableLongArray
.class, if this object is an instance ofLongArray
,MutableFloatArray
.class, if this object is an instance ofFloatArray
,MutableDoubleArray
.class, if this object is an instance ofDoubleArray
,MutableObjectArray
.class, if this object is an instance ofObjectArray
.
There is a guarantee that this method works very quickly (usually it just returns a constant value).
- Specified by:
mutableType
in interfaceArray
- Returns:
- canonical AlgART type of a resizable array of the same kind.
-
length
public long length()This implementation returnslength
& Long.MAX_VALUE. (The high bit of length may be used for service goals.) -
capacity
public long capacity()This implementation returnscapacity
& Long.MAX_VALUE. (The high bit of capacity may be used for service goals.) -
getElement
Description copied from interface:Array
Returns the element #index. It this array contains elements of primitive types, the value is automatically wrapped in an object (Boolean, Byte, etc.).It is a low-level method. For arrays of primitive elements, implementing one of corresponding interfaces
BitArray
,CharArray
,ByteArray
,ShortArray
,IntArray
,LongArray
,FloatArray
,DoubleArray
, we recommend to use more efficient equivalent method of that interfaces:BitArray.getBit(long)
,CharArray.getChar(long)
,ByteArray.getByte(long)
,ShortArray.getShort(long)
,IntArray.getInt(long)
,LongArray.getLong(long)
,FloatArray.getFloat(long)
,DoubleArray.getDouble(long)
. For other arrays, implementingObjectArray
, we recommend to useObjectArray.get(long)
.- Specified by:
getElement
in interfaceArray
- Parameters:
index
- index of element to get.- Returns:
- the element at the specified position in this array.
-
getData
Description copied from interface:Array
Copies count elements of this array, starting from arrayPos index, into the specified Java array of corresponding type, starting from destArrayOffset index.For non-primitive element type (
ObjectArray
,UpdatableObjectArray
,MutableObjectArray
subinterfaces), this method may allocate new instances for Java array elements destArray[destArrayOffset]..destArray[destArrayOffset+count-1], but also may change the state of already existing non-null elements: it depends on implementation. In any case, you can be sure that if some of target elements destArray[k]==null, this method always allocate new element.Note: if IndexOutOfBoundsException occurs due to attempt to write data outside the passed Java array, the target Java array can be partially filled. In other words, this method can be non-atomic regarding this failure. All other possible exceptions are checked in the very beginning of this method before any other actions (the standard way for checking exceptions).
-
getData
Description copied from interface:Array
Copies min(this.length() - arrayPos
, destArray.length}) elements of this array, starting from arrayPos index, into the specified Java array of corresponding type, starting from 0 index.For non-primitive element type (
ObjectArray
,UpdatableObjectArray
,MutableObjectArray
subinterfaces), this method may allocate new instances for Java array elements destArray[0]..destArray[count-1], but also may change the state of already existing non-null elements: it depends on implementation. In any case, you can be sure that if some of target elements destArray[k]==null, this method always allocate new element. -
newJavaArray
This implementation returns java.lang.reflect.Array.newInstance(elementType(), length).- Specified by:
newJavaArray
in interfaceArray
- Parameters:
length
- the length of created Java-array.- Returns:
- Java-array with the specified length and the same type of elements.
- Throws:
NegativeArraySizeException
- if the specified length is negative.
-
isZeroFilled
public boolean isZeroFilled()This method ofPArray
interface is fully implemented in this class. If this instance does not implementPArray
(i.e. if it isObjectArray
), this method throws UnsupportedOperationException.- Returns:
- true if and only if all elements of this array are zero, or if this array is empty.
- Throws:
UnsupportedOperationException
- if this instance is an array of non-primitive elements.
-
subArray
Description copied from interface:Array
Returns a view of the portion of this array between fromIndex, inclusive, and toIndex, exclusive.- If fromIndex and toIndex are equal, the returned array is empty.
- The returned array is backed by this array, so — if this array is not immutable — any changes of the elements of the returned array are reflected in this array, and vice-versa.
- The capacity of returned array (returned by
Array.capacity()
method) will be equal to the its length (returned byArray.length()
, that is toIndex-fromIndex. - The
type of elements
of the returned array is the same as the type of elements of this array. - The returned array is
immutable
,trusted immutable
orcopy-on-next-write
, if, and only if, this array is immutable, trusted immutable or copy-on-next-write correspondingly. - If (and only if) this array implements
UpdatableArray
interface, then the returned array also implements it. If (and only if) this array implementsDirectAccessible
interface, then the returned array also implements it. The returned array never implementsMutableArray
interface; it is always unresizable.
Like List.subList method, this method eliminates the need for explicit range operations. For example, you may use
Arrays.sort(UpdatableArray, ArrayComparator)
method for sorting a fragment of the array.Unlike List.subList, the semantics of the array returned by this method is well-defined in any case, even in case of resizing of the source array. Namely, if the internal storage of this or returned array is reallocated, then the returned array will cease to be a view of this array. The only possible reasons for reallocation are the following: calling
MutableArray.length(long)
,MutableArray.ensureCapacity(long)
orMutableArray.trim()
methods for this array, or any modification of this or returned array in a case when this array iscopy-on-next-write
. Also, if the length of this array will be reduced, it can lead to clearing some elements in returned array: see comments toMutableArray.length(long)
method. -
subArr
This implementation returnssubArray
(position, position + count). Please note that the exception message can be not fully correct for the very exotic case position+count>Long.MAX_VALUE.- Specified by:
subArr
in interfaceArray
- Parameters:
position
- start position (inclusive) of the subarray.count
- number of elements in the subarray.- Returns:
- a view of the specified range within this array.
- Throws:
IndexOutOfBoundsException
- for illegal position and count (position < 0 || count < 0 || position + count > length).- See Also:
-
buffer
This method is fully implemented in this class.The returned buffer will be direct, if mode is not
PRIVATE
, this array is notimmutable
, is notcopy-on-next-write
, and either it implementsDirectAccessible
interface and itshasJavaArray()
method returns true, or it is a bit array created by thesimple memory model
.- Specified by:
buffer
in interfaceArray
- Parameters:
mode
- the access mode for new buffer.capacity
- the capacity of the buffer- Returns:
- new data buffer for accessing this array.
- Throws:
NullPointerException
- if mode argument is null.IllegalArgumentException
- if the mode is not theDataBuffer.AccessMode.READ
, but this arrays does not implementUpdatableArray
interface, or if the specified capacity is negative or too high (>=0..237 for bits or >=0..231 for other element types).- See Also:
-
buffer
This implementation returnsbuffer(mode, someCapacity)
, where mode is the argument of this method and someCapacity is the result ofdefaultBufferCapacity(thisArray)
method.- Specified by:
buffer
in interfaceArray
- Parameters:
mode
- the access mode for new buffer.- Returns:
- new data buffer for accessing this array.
- Throws:
NullPointerException
- if mode argument is null.IllegalArgumentException
- if the mode is not theDataBuffer.AccessMode.READ
, but this arrays does not implementUpdatableArray
interface.
-
buffer
This implementation returnsbuffer(suitableMode, capacity)
, where capacity is the argument of this method and suitableMode is this instanceof UpdatableArray ? DataBuffer.AccessMode.READ_WRITE : DataBuffer.AccessMode.READ.- Specified by:
buffer
in interfaceArray
- Parameters:
capacity
- the capacity of the buffer.- Returns:
- new data buffer for accessing this array.
- Throws:
IllegalArgumentException
- if the specified capacity is negative or too high (>=0..237 for bits or >=0..231 for other element types).
-
buffer
This implementation returnsbuffer(suitableMode)
, where suitableMode is this instanceof UpdatableArray ? DataBuffer.AccessMode.READ_WRITE : DataBuffer.AccessMode.READ. -
asImmutable
Description copied from interface:Array
Returns an immutable view of this array. If this array is already immutable (i.e.Array.isImmutable()
is true), returns a reference to this object.A array is considered to be immutable, if there are no ways to modify its content or state with help of this instance. In particular, immutable arrays never implement
UpdatableArray
orDirectAccessible
interfaces. Moreover, any third-party implementation of Array interface must return an instance of a class, which has no methods or fields allowing to change this instance.Query operations on the returned array "read through" to this array. The returned view is also unresizable (see
UpdatableArray.asUnresizable()
).The returned view (when it is not a reference to this object) contains the same elements as this array, but independent length, start offset, capacity, copy-on-next-write and possible other information about array characteristics besides its elements, as for
Array.shallowClone()
method. If modifications of this array characteristics lead to reallocation of the internal storage, then the returned array ceases to be a view of this array. The only possible reasons for reallocation are the following: callingMutableArray.length(long)
,MutableArray.ensureCapacity(long)
orMutableArray.trim()
methods for this array, or any modification of this or returned array in a case when this array iscopy-on-next-write
.By default, the array factories (
memory models
) create mutable arrays, but they can be converted to immutable by this method.Note:
Array.isNew()
method, called for the result of this method, always returns false — because it does not implementUpdatableArray
.Also note:
Array.isNewReadOnlyView()
method, called for the result of this method, always returns the same value asArray.isNewReadOnlyView()
for this object. Really,- it this object is immutable (
Array.isImmutable()
==true), then it is obvious (this method just returns a reference to this array); - it this object is not immutable (
Array.isImmutable()
==false), then, according to the contract toArray.isNewReadOnlyView()
method,Array.isNewReadOnlyView()
must return false for this array (in other caseArray.isImmutable()
would return true) and it also must return false for the returned array (because it is a view of another array and not an original view of external data — see the beginning of the comment toArray.isNewReadOnlyView()
).
- Specified by:
asImmutable
in interfaceArray
- Returns:
- an immutable view of this array (or a reference to this array if it is already immutable).
- See Also:
- it this object is immutable (
-
isImmutable
public abstract boolean isImmutable()Description copied from interface:Array
Returns true if this instance is immutable, i.e. there are no ways to change its content or state. (SeeArray.asImmutable()
method for more details.)It is possible that array is immutable in fact, but this method returns false: for example, if the array is mapped to read-only file. However, it is guaranteed: if the array was created via
Array.asImmutable()
method, this method returns true.Typically, this method returns true if the array:
- does not implement
UpdatableArray
interface; - does not implement
DirectAccessible
interface, or implements it, butDirectAccessible.hasJavaArray()
method returns false.
But you should not use these conditions to check whether an array is immutable; please use this method instead. In principle, it is possible that both these conditions are satisfied, but the array is though mutable. Maybe, some class from another package (or from future versions of this package), implementing
Array
interface, does not implement neitherUpdatableArray
, norDirectAccessible
, but offers another methods allowing to change its state or content.Note: if this method returns true, it does not mean that its content cannot be modified at all. Quite the contrary, usually an immutable array a is just an immutable view of another mutable array b (created via a=b.
Array.asImmutable()
call), and the original array b does allow to change the content of the immutable array a. Immutability means only that there are no ways to modify the content or state of the object a, if this object a is the only reference to its content, which you have. The same note is true for immutable collections, created by the standard Collections.unmodifiableList and analogous methods. Please compare this with the behaviour of another methodArray.isNewReadOnlyView()
.There is a guarantee that this method works very quickly (usually it just returns a constant or a value of some private field).
- Specified by:
isImmutable
in interfaceArray
- Returns:
- true if this instance is immutable.
- See Also:
- does not implement
-
asTrustedImmutable
Description copied from interface:Array
Returns a trusted immutable view of this array. If this array is already trusted immutable, returns a reference to this object.A array is considered to be "trusted" immutable, if it potentially can change its elements, but the Java code working with this array promises that it will not change them. The returned instance never implements
UpdatableArray
, but may implementDirectAccessible
, that allow quick access to its elements. As forusual immutable view
, query operations on the returned array "read through" to this array.The only standard way allowing to change elements of returned array is using
DirectAccessible.javaArray()
method, in a case when the array is backed by an accessible array. But the Java code, processing the trusted immutable array, must use this method only for quick reading elements and not try to change them. If, despite the promise, the elements of the trusted immutable array will be changed, theUnallowedMutationError
may be thrown by the call ofArray.checkUnallowedMutation()
method.In some implementations — for example, if
DirectAccessible
interface is not supported by this array — this method may return the same result asArray.asImmutable()
.The returned view is always unresizable.
The returned view (when it is not a reference to this object) contains the same elements as this array, but independent length, start offset, capacity, copy-on-next-write and possible other information about array characteristics besides its elements, as for
Array.shallowClone()
method. If modifications of this array characteristics lead to reallocation of the internal storage, then the returned array ceases to be a view of this array. The only possible reasons for reallocation are the following: callingMutableArray.length(long)
,MutableArray.ensureCapacity(long)
orMutableArray.trim()
methods for this array, or any modification of this or returned array in a case when this array iscopy-on-next-write
.Trusted immutable view is a compromise between absolute safety, provided by
usual immutable view
, and maximal efficiency, achieved while using the original non-protected array. Please see the package description to learn more about possible usage of this method.- Specified by:
asTrustedImmutable
in interfaceArray
- Returns:
- a trusted immutable view of this array (or a reference to this array if it is already trusted immutable).
- See Also:
-
checkUnallowedMutation
Description copied from interface:Array
Tries to check, whether some unallowed mutations of thistrusted immutable
array took place, and throwUnallowedMutationError
in this case. Does nothing if this array implementUpdatableArray
interface or if it is truly immutable.Implementation of this method usually checks whether the hash code was changed since array creation.
We recommend to call this method in finally sections after using the trusted immutable array. If it is impossible to create necessary finally section, you may use
Finalizer
class (or an equivalent tool) to schedule call of this method for theshallow clone
of this array on deallocation of this array:Finalizer fin = ...(some global application finalizer); final Array dup = thisArray.shallowClone(); // - must be here, not inside the following inner class, to allow deallocation of thisArray fin.invokeOnDeallocation(thisArray, new Runnable() { void run() { try { dup.checkUnallowedMutation(); } catch (UnallowedMutationError ex) { myLogger.severe(ex.toString()); } } });
Important: while using this finalization scheme, this array must not becopy-on-next-write
! Illegal modifications of copy-on-next-write array will not change it's shallow clone and will not be detected.- Specified by:
checkUnallowedMutation
in interfaceArray
- Throws:
UnallowedMutationError
- if some unallowed mutations of this array took place.- See Also:
-
asCopyOnNextWrite
Description copied from interface:Array
Returns a copy-on-next-write view of this array. If this array is immutable (and only in this case), returns a reference to this object. If (and only if) this array implementsUpdatableArray
interface, then the returned array also implements it. If (and only if) this array implementsMutableArray
interface, then the returned array also implements it.Copy-on-next-write array is an array with the following special feature: the next attempt (but not further!) to modify this array, or any other access that can lead to its modification (like
DirectAccessible.javaArray()
method), will lead to reallocation of the underlying storage, used for array elements, before performing the operation. In other words, you have a guarantee: if this array is a view of some another array or data (for example, asubarray
or aview of Java array
, that there are no ways to change that data via accessing the returned array. Any changes, it they will occur, will be performed with the newly allocated storage only.Please be careful: it you will want to change arrays created by this method, the result may be unexpected! For example, an attempt to copy other arrays into copy-on-next-write array by some methods like
Arrays.copy(ArrayContext, UpdatableArray, Array)
will probable do nothing. The reason is working with the array via its subarrays — for example,Arrays.copy
method splits the source and target arrays into subarrays and copies these subarrays. (UsualUpdatableArray.copy(Array)
method and other mutation methods of the resulting array will work normally.) The main goal of copy-on-next-write arrays is protection againts unwanted changing an original array; it is supposed that the client, in normal situation, will only read such arrays and will not try to change them.There are no guarantees that the returned array will be a view of this one, even immediately after creation. Some implementations of updatable arrays may just return the full (deep) copy of this object, alike
Array.mutableClone(MemoryModel)
method, and in this caseTooLargeArrayException
is possible. All implementations from this package, excepting AbstractUpdatableXxxArray classes, returns a view; but in AbstractUpdatableXxxArray classes this method is equivalent toupdatableClone
(Arrays.SMM
).Please note that copy-on-next-write arrays are not traditional copy-on-write objects like CopyOnWriteArrayList! In particular, copy-on-next-write arrays are not thread-safe.
The main purpose of using copy-on-next-write arrays is more efficient alternative to
cloning
and creatingquite immutable views
, when we need to be sure that original data will not be corrupted. Please see the package description to learn more about possible usage of this technique.- Specified by:
asCopyOnNextWrite
in interfaceArray
- Returns:
- a copy-on-next-write view of this array (or a reference to this array if it is immutable).
- See Also:
-
isCopyOnNextWrite
public abstract boolean isCopyOnNextWrite()Description copied from interface:Array
Returns true if this array is copy-on-next-write. In other words, if this method returns true, it means that the next attempt (but not further) to modify this array, or any other access that can lead to its modification (likeDirectAccessible.javaArray()
method), will lead to reallocation of the underlying storage. After reallocation, the array will cease to be copy-on-next-write: further calls of this method will return false.This method can be useful if it's possible to select another, more optimal algorithm branch, allowing to avoid reallocation for copy-on-next-write arrays. The typical example is usage of
DirectAccessible
interface. That interface, providing direct access to the internal Java array (which is a storage of the array elements), can optimize most of the algorithms processing an array. However, reallocation of the Java array, that will be a result of callingDirectAccessible.javaArray()
for copy-on-next-write array, can make such "optimization" very unwanted.The only standard way to make copy-on-next-write is calling
Array.asCopyOnNextWrite()
method.There is a guarantee that this method works very quickly (usually it just returns a constant or a value of some private field).
- Specified by:
isCopyOnNextWrite
in interfaceArray
- Returns:
- true if this array is copy-on-next-write.
- See Also:
-
isUnresizable
public abstract boolean isUnresizable()Description copied from interface:Array
Returns true if this instance is unresizable, i.e. there are no ways to change its length or capacity.It is guaranteed that if the array was created via
Array.asImmutable()
method, this method returns true.Typically, this method returns true if the array does not implement
MutableArray
. But you should not use this condition to check whether an array is unresizable; please use this method instead. Maybe, some class from another package (or from future versions of this package), implementing thisArray
interface, does not implementMutableArray
, but offer another methods allowing to change its state or content.There is a guarantee that this method works very quickly (usually it just returns a constant or a value of some private field).
- Specified by:
isUnresizable
in interfaceArray
- Returns:
- true if this instance is unresizable.
- See Also:
-
isNew
public boolean isNew()This implementation returns a private boolean field, that is false by default, but can be changed by protectedsetNewStatus(boolean)
method.- Specified by:
isNew
in interfaceArray
- Returns:
- whether this array instance if new: a new object, allocated by some
MemoryModel
. - See Also:
-
isNewReadOnlyView
public boolean isNewReadOnlyView()This implementation returns a private boolean field, that is false by default, but can be changed by protectedsetNewReadOnlyViewStatus()
method.- Specified by:
isNewReadOnlyView
in interfaceArray
- Returns:
- whether this array instance is a newly created view of some external data, providing read-only access to this data.
-
isLazy
public boolean isLazy()This implementation returnsunderlyingArrays
.length > 0. Please override this if the access to underlying arrays is very quick (as forMatrix.subMatrix(long[], long[])
or, vice versa, if there no underlying arrays, but getting an element requires some calculation (as forArrays.asIndexFuncArray(net.algart.math.functions.Func, Class, long)
).- Specified by:
isLazy
in interfaceArray
- Returns:
- true if and only if
underlyingArrays
is non-empty.
-
byteOrder
This implementation returns ByteOrder.nativeOrder(). -
shallowClone
This implementation returnsstandardObjectClone()
.Be careful: if you are extending this class to implement full
MutableArray
interface, your should investigate, whether you need to override this method to provide real independence of the length, start offset, capacity, copy-on-next-write and other information about any array characteristics besides its elements.- Specified by:
shallowClone
in interfaceArray
- Returns:
- a shallow copy of this object.
- See Also:
-
mutableClone
- Specified by:
mutableClone
in interfaceArray
- Parameters:
memoryModel
- the memory model, used for allocation a new copy of this array.- Returns:
- a mutable copy of this array.
- Throws:
NullPointerException
- if the argument is null.UnsupportedElementTypeException
- if thisArray.Array.elementType()
is not supported by the specified memory model.TooLargeArrayException
- if thelength
of this array is too large for this the specified memory model.- See Also:
-
updatableClone
This implementation performs the following: memoryModel.newUnresizableArray
(thisArray).copy
(thisArray).- Specified by:
updatableClone
in interfaceArray
- Parameters:
memoryModel
- the memory model, used for allocation a new copy of this array.- Returns:
- an updatable copy of this array.
- Throws:
NullPointerException
- if the argument is null.UnsupportedElementTypeException
- if thisArray.Array.elementType()
is not supported by the specified memory model.TooLargeArrayException
- if thelength
of this array is too large for this the specified memory model.- See Also:
-
ja
This implementation performs the following code:return this instanceof DirectAccessible da && da.hasJavaArray() && da.javaArrayOffset() == 0 && java.lang.reflect.Array.getLength(da.javaArray()) == this.length() ? da.javaArray() : Arrays.toJavaArray(this);
-
loadResources
This implementation does nothing. You need to override it to provide (in a case of subarray) preloading correct part all underlying arrays, passed via the last argument of theconstructor
.- Specified by:
loadResources
in interfaceArray
- Parameters:
context
- the context of execution; may be null, then it will be ignored.- See Also:
-
flushResources
This implementation just callsflushResources(context, false)
.- Specified by:
flushResources
in interfaceArray
- Parameters:
context
- the context of execution; may be null, then it will be ignored.- See Also:
-
flushResources
This implementation calls the same method with the same arguments for all underlying arrays, passed via the last argument of theconstructor
. Please override it if you want to provide (in a case of subarray) flushing correct part of the underlying arrays.- Specified by:
flushResources
in interfaceArray
- Parameters:
context
- the context of execution; may be null, then it will be ignored.forcePhysicalWriting
- is it necessary to try forcing physical writing all associated resources to the external device.- See Also:
-
freeResources
This implementation just callsfreeResources(context, false)
.- Specified by:
freeResources
in interfaceArray
- Parameters:
context
- the context of execution; may be null, then it will be ignored.- See Also:
-
freeResources
This implementation calls the same method for all underlying arrays, passed via the last argument of theconstructor
. Please override it if you want to provide (in a case of subarray) freeing correct part of the underlying arrays.- Specified by:
freeResources
in interfaceArray
- Parameters:
context
- the context of execution; may be null, then it will be ignored.forcePhysicalWriting
- is it necessary to try forcing physical writing all associated resources to the external device.- See Also:
-
toString
Description copied from interface:Array
Returns a brief string description of this object.The result of this method may depend on implementation and usually contains a short description of the array length, capacity, element type.
Note: for
character arrays
, unlike CharSequence.toString(), this method works as for all other array types. If you need to convert a character array to a string, containing all characters of the array, you may useArrays.toString(CharArray)
method. -
hashCode
public final int hashCode()This method is fully implemented in this class and cannot be overridden (it is declared as final method here).For non-primitive element type (
ObjectArray
subinterfaces), this implementation is based on calls of hashCode method of the class of elements (elementType()
).This method is equivalent to the following call:
hashCode(this)
. -
equals
This method is fully implemented in this class and is not be overridden usually.For non-primitive element type (
ObjectArray
subinterface), this implementation is based on calls of equals method of the class of elements (elementType()
).This method is equivalent to the following call:
equals(this, obj)
.In some cases, you may override this method to provide better performance or to exclude dependence on elements' equals method. (For example, this method is overridden in
combined arrays
.) -
hashCode
Default implementation ofArray.hashCode()
method.All classes implementing
Array
interface, that do not extendAbstractArray
, must use this method or fully equivalent algorithm to ensure correct arrays behavior. Classes that extendAbstractArray
always inherit standard implementationAbstractArray.hashCode()
.- Parameters:
array
- the AlgART array.- Returns:
- the hash code of this array.
-
equals
Default implementation ofArray.equals(Object)
method.All classes implementing
Array
interface must use this method or fully equivalent algorithm to ensure correct arrays behavior. Classes that extendAbstractArray
may just inherit standard implementationAbstractArray.equals(Object)
.- Parameters:
obj1
- first compared object.obj2
- second compared object.- Returns:
- true if obj2 is an array and the specified arrays are equal.
-
defaultBufferCapacity
Returns the data buffer capacity used bybuffer(net.algart.arrays.DataBuffer.AccessMode)
andbuffer()
methods. The result is calculated so that the buffer occupies ~16-32 KB RAM.In any case, you can be sure that the result will not be greater than Integer.MAX_VALUE-64.
- Parameters:
thisArray
- this array.- Returns:
- default data buffer capacity, suitable for this array.
-
checkCopyArguments
Checks whether the passed arguments correct forUpdatableArray.copy(Array)
and throws corresponding exception if no. More precisely, this method throws IllegalArgumentException if is not possible to assign elements of src array to elements of thisArray, i.e. if !thisArray.elementType()
.isAssignableFrom(src.elementType()
).Note: for primitive array types (
PArray
and its inheritors), this method throws an exception if and only ifthisArray. .elementType()
!=src.elementType()
- Parameters:
thisArray
- this array.src
- the source array.- Throws:
NullPointerException
- if thisArray or src argument is null.IllegalArgumentException
- if the source and destination element types do not match.
-
checkSwapArguments
Checks whether the passed arguments correct forUpdatableArray.swap(UpdatableArray)
and throws corresponding exception if no. More precisely, this method throws IllegalArgumentException if another array thisArray have different element types, i.e. if thisArray.elementType()
!=another.elementType()
.- Parameters:
thisArray
- this array.another
- another array.- Throws:
NullPointerException
- if thisArray or src argument is null.IllegalArgumentException
- if another and this element types do not match.
-
standardObjectClone
Performs default Object.clone() call and clears in its result bothnew status
andnew-read-only-view status
. In other words, it is a usual clone with the only difference, thatArray.isNew()
andArray.isNewReadOnlyView()
methods returns false in the returned object. (It is a requirement of the contracts of these methods.)The call of this method is a suitable implementation of
shallowClone()
method for most cases.Please note that this method clones a reference
underlyingArrays
and does not tries to create a clone of this Java array.- Returns:
- result of default Object.clone()
-
checkSubArrayArguments
protected final void checkSubArrayArguments(long fromIndex, long toIndex) Checks whether the passed arguments correct forsubArray(long, long)
and throws corresponding exception if no.- Parameters:
fromIndex
- low endpoint (inclusive) of the subarray.toIndex
- high endpoint (exclusive) of the subarray.- Throws:
IndexOutOfBoundsException
- for illegal fromIndex and toIndex (fromIndex < 0 || toIndex >length()
|| fromIndex > toIndex).
-
checkSubArrArguments
protected final void checkSubArrArguments(long position, long count) Checks whether the passed arguments correct forsubArr(long, long)
and throws corresponding exception if no.- Parameters:
position
- start position (inclusive) of the subarray.count
- number of elements in the subarray.- Throws:
IndexOutOfBoundsException
- for illegal position and count (position < 0 || count < 0 || position + count >length()
).
-
setNewStatus
protected final void setNewStatus(boolean value) Sets the value of the private boolean field returned byisNew()
method.This method is called with true argument while allocating new AlgART array and reallocating internal storage, for example, in
copy-on-next-write
arrays. This method is called with false argument inUpdatableArray.setNonNew()
method only. In your inheritors of this class, you must not provide an ability (via public methods) to call this method with true argument.If the argument is false, this instance must implement
UpdatableArray
interface. In other case, UnsupportedOperationException will be thrown.The access to the "new status", provided by this and
isNew()
method, is always internally synchronized (the corresponding private field is volatile). So, changing "new-read-only-view status" by this method will be immediately visible in all threads using this instance.- Parameters:
value
- new "new status".- Throws:
UnsupportedOperationException
- if the argument is false and this instance does not implementUpdatableArray
interface.
-
setNewReadOnlyViewStatus
protected final void setNewReadOnlyViewStatus()Sets to true the value of the private boolean field returned byisNewReadOnlyView()
method.This method is called creating a view of external data, providing read-only access to this data. In this package, it is called only by
LargeMemoryModel.asArray(Object, Class, long, long, java.nio.ByteOrder)
method, its strict equivalentsasBitArray
,asCharArray
, etc. and byLargeMemoryModel.asMatrix(Object, MatrixInfo)
method, and only in a case when the data offset, specified while calling these methods, is zero.In your inheritors of this class, you must not provide an ability (via public methods) to call this method.
If the argument is false, this instance must implement
UpdatableArray
interface. In other case, UnsupportedOperationException will be thrown.The access to the "new-read-only-view status", provided by this and
isNewReadOnlyView()
method, is always internally synchronized (the corresponding private field is volatile). So, changing "new-read-only-view status" by this method will be immediately visible in all threads using this instance.- Throws:
UnsupportedOperationException
- if this instance implementsUpdatableArray
interface.
-
defaultBuffer
protected static DataBuffer defaultBuffer(Array thisArray, DataBuffer.AccessMode mode, long capacity) Default implementation ofbuffer(net.algart.arrays.DataBuffer.AccessMode, long)
method.- Parameters:
thisArray
- this array.mode
- the access mode for new buffer.capacity
- the capacity of the buffer- Returns:
- new data buffer for accessing this array.
- Throws:
NullPointerException
- if mode argument is null.IllegalArgumentException
- if the mode is not theDataBuffer.AccessMode.READ
, but this arrays does not implementUpdatableArray
interface, or if the specified capacity is negative or too high (>=0..237 for bits or >=0..231 for other element types).
-
defaultCopy
Equivalent todefaultCopy(thisArray, src, false)
.- Parameters:
thisArray
- this array.src
- the source array.- Throws:
NullPointerException
- if thisArray or src argument is null.IllegalArgumentException
- if the source and destination element types do not match.
-
defaultCopy
Possible implementation ofUpdatableArray.copy(Array)
based onArray.getData(long, Object)
andUpdatableArray.setData(long, Object)
methods (for some temporary array). Usually called inUpdatableArray.copy(Array)
method in a case when src.getClass() != this.getClass().If allowNulls argument is true, then this method, in addition to standard behavior, always allows to copy src when it is result of Arrays.
nObjectCopies(..., null)
and when thisArray isUpdatableObjectArray
. (The element type of such source array is Object and usually cannot be assigned to element type of thisArray.)- Parameters:
thisArray
- this array.src
- the source array.allowNulls
- whether this method should always allow filling object array by null.- Throws:
NullPointerException
- if thisArray or src argument is null.IllegalArgumentException
- if the source and destination element types do not match.
-
defaultSwap
Possible implementation ofUpdatableArray.swap(UpdatableArray)
based onArray.getData(long, Object)
andUpdatableArray.setData(long, Object)
methods (for some temporary array). Usually called in swap method in a case when src.getClass() != this.getClass().- Parameters:
thisArray
- this array.another
- another array.- Throws:
NullPointerException
- if thisArray or another argument is null.IllegalArgumentException
- if another and this element types do not match.
-
defaultAppend
Simplest implementation ofMutableArray.append(Array)
, based onMutableArray.length(long)
,UpdatableArray.subArr(long, long)
andUpdatableArray.copy(Array)
methods.- Parameters:
thisArray
- this array.appendedArray
- appended array.- Returns:
- this array.
- Throws:
NullPointerException
- if thisArray or appendedArray argument is null.IllegalArgumentException
- if the source and this element types do not match.TooLargeArrayException
- if the resulting array length is too large for this type of arrays.
-