net.algart.arrays.FloatJArrayHolder Maven / Gradle / Ivy
Show all versions of algart Show documentation
/*
* The MIT License (MIT)
*
* Copyright (c) 2007-2024 Daniel Alievsky, AlgART Laboratory (http://algart.net)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package net.algart.arrays;
import java.lang.ref.SoftReference;
import java.util.Objects;
/*Repeat.SectionStart all*/
/**
* A simple class allowing to reuse Java float[]
array many times.
* It can be useful, when the algorithm usually allocates float[]
array with the same size
* many times (changing the size is a rare event). In this case, you can replace "new"
operator
* (that spends time for zero-initialing new array) with {@link #quickNew(int)} method,
* that probably will work very quickly.
* The previously allocated array is stored inside the object in a SoftReference
.
*
* This class is thread-safe: you may use the same instance of this class in several threads.
*
* @author Daniel Alievsky
*/
public final class FloatJArrayHolder {
private SoftReference reference = new SoftReference(new float[0]);
private final Object lock = new Object();
/**
* Equivalent to {@link #quickNew(long) quickNew}(matrix.{@link Matrix#size() size()})
.
*
* @param matrix some AlgART matrix.
* @return newly created "new float[newArrayLength]"
* or previously allocated array, if it exists and has identical length.
* @throws NullPointerException if the argument is {@code null}.
* @throws TooLargeArrayException if matrix.size() > Integer.MAX_VALUE
.
*/
public float[] quickNew(Matrix> matrix) {
Objects.requireNonNull(matrix, "Null matrix argument");
return quickNew(matrix.size());
}
/**
* Equivalent of {@link #quickNew(int)} method, but in addition it checks that
* newArrayLength
is actually 32-bit value (newArrayLength==(int)newArrayLength
)
* and, if not, throws {@link TooLargeArrayException}.
*
* @param newArrayLength required array length.
* @return newly created "new float[newArrayLength]"
* or previously allocated array, if it exists and has identical length.
* @throws IllegalArgumentException if newArrayLength < 0
.
* @throws TooLargeArrayException if newArrayLength > Integer.MAX_VALUE
.
*/
public float[] quickNew(long newArrayLength) {
if (newArrayLength < 0) {
throw new IllegalArgumentException("Zero or negative array new array length");
}
if (newArrayLength != (int) newArrayLength) {
throw new TooLargeArrayException("Too large requested array: " + newArrayLength + " elements");
}
return quickNew((int) newArrayLength);
}
/**
* Quick analog of new float[newArrayLength]}
.
* If this method is called several times for allocating data with the same size,
* this method returns previously allocated array.
* (Previous array is stored in SoftReference
and, if there is not enough memory,
* can be utilized by garbage collector; in this case, this method will just use "new"
* operator.)
*
* Please remember: unlike standard new
operator, the returned array is usually not
* filled by zeros.
*
* @param newArrayLength required array length.
* @return newly created "new float[newArrayLength]"
* or previously allocated array, if it exists and has identical length.
* @throws IllegalArgumentException if newArrayLength < 0
*/
public float[] quickNew(int newArrayLength) {
if (newArrayLength < 0) {
throw new IllegalArgumentException("Zero or negative array new array length");
}
synchronized (lock) {
final float[] oldArray = reference.get();
if (oldArray != null && oldArray.length == newArrayLength) {
return oldArray;
}
final float[] result = new float[newArrayLength];
reference = new SoftReference(result);
return result;
}
}
/**
* Quick analog of array.clone()
.
* Equivalent to the following operators:
*
* float[] result = {@link #quickNew(int)} quickNew}(array.length);
* System.arraycopy(array, 0, result, 0, array.length);
* (return result)
*
*
* @param array some array to clone.
* @return exact copy of the source array.
* @throws NullPointerException if the passed array is {@code null}.
*/
public float[] quickClone(float[] array) {
float[] result = quickNew(array.length);
System.arraycopy(array, 0, result, 0, array.length);
return result;
}
}
/*Repeat.SectionEnd all*/