1dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond/* 2dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Licensed to the Apache Software Foundation (ASF) under one or more 3dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * contributor license agreements. See the NOTICE file distributed with 4dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * this work for additional information regarding copyright ownership. 5dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The ASF licenses this file to You under the Apache License, Version 2.0 6dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * (the "License"); you may not use this file except in compliance with 7dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the License. You may obtain a copy of the License at 8dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 9dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * http://www.apache.org/licenses/LICENSE-2.0 10dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 11dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Unless required by applicable law or agreed to in writing, software 12dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * distributed under the License is distributed on an "AS IS" BASIS, 13dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * See the License for the specific language governing permissions and 15dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * limitations under the License. 16dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 17dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpackage org.apache.commons.math.util; 18dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 19dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport java.io.Serializable; 20dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport java.util.Arrays; 21dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 22dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.MathRuntimeException; 23dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.exception.util.LocalizedFormats; 24dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 25dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond/** 26dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 27dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * A variable length {@link DoubleArray} implementation that automatically 28dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * handles expanding and contracting its internal storage array as elements 29dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * are added and removed. 30dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </p> 31dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 32dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The internal storage array starts with capacity determined by the 33dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <code>initialCapacity</code> property, which can be set by the constructor. 34dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The default initial capacity is 16. Adding elements using 35dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * {@link #addElement(double)} appends elements to the end of the array. When 36dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * there are no open entries at the end of the internal storage array, the 37dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * array is expanded. The size of the expanded array depends on the 38dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <code>expansionMode</code> and <code>expansionFactor</code> properties. 39dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The <code>expansionMode</code> determines whether the size of the array is 40dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * multiplied by the <code>expansionFactor</code> (MULTIPLICATIVE_MODE) or if 41dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the expansion is additive (ADDITIVE_MODE -- <code>expansionFactor</code> 42dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * storage locations added). The default <code>expansionMode</code> is 43dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * MULTIPLICATIVE_MODE and the default <code>expansionFactor</code> 44dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * is 2.0. 45dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </p> 46dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 47dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The {@link #addElementRolling(double)} method adds a new element to the end 48dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * of the internal storage array and adjusts the "usable window" of the 49dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * internal array forward by one position (effectively making what was the 50dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * second element the first, and so on). Repeated activations of this method 51dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * (or activation of {@link #discardFrontElements(int)}) will effectively orphan 52dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the storage locations at the beginning of the internal storage array. To 53dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * reclaim this storage, each time one of these methods is activated, the size 54dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * of the internal storage array is compared to the number of addressable 55dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * elements (the <code>numElements</code> property) and if the difference 56dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * is too large, the internal array is contracted to size 57dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <code>numElements + 1.</code> The determination of when the internal 58dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * storage array is "too large" depends on the <code>expansionMode</code> and 59dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <code>contractionFactor</code> properties. If the <code>expansionMode</code> 60dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * is <code>MULTIPLICATIVE_MODE</code>, contraction is triggered when the 61dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * ratio between storage array length and <code>numElements</code> exceeds 62dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <code>contractionFactor.</code> If the <code>expansionMode</code> 63dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * is <code>ADDITIVE_MODE,</code> the number of excess storage locations 64dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * is compared to <code>contractionFactor.</code> 65dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </p> 66dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 67dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * To avoid cycles of expansions and contractions, the 68dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <code>expansionFactor</code> must not exceed the 69dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <code>contractionFactor.</code> Constructors and mutators for both of these 70dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * properties enforce this requirement, throwing IllegalArgumentException if it 71dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * is violated. 72dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </p> 73dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @version $Revision: 1073474 $ $Date: 2011-02-22 20:52:17 +0100 (mar. 22 févr. 2011) $ 74dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 75dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpublic class ResizableDoubleArray implements DoubleArray, Serializable { 76dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 77dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** additive expansion mode */ 78dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static final int ADDITIVE_MODE = 1; 79dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 80dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** multiplicative expansion mode */ 81dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static final int MULTIPLICATIVE_MODE = 0; 82dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 83dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Serializable version identifier */ 84dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final long serialVersionUID = -3485529955529426875L; 85dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 86dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 87dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The contraction criteria determines when the internal array will be 88dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * contracted to fit the number of elements contained in the element 89dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * array + 1. 90dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 91dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected float contractionCriteria = 2.5f; 92dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 93dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 94dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The expansion factor of the array. When the array needs to be expanded, 95dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the new array size will be 96dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <code>internalArray.length * expansionFactor</code> 97dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * if <code>expansionMode</code> is set to MULTIPLICATIVE_MODE, or 98dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <code>internalArray.length + expansionFactor</code> if 99dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <code>expansionMode</code> is set to ADDITIVE_MODE. 100dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 101dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected float expansionFactor = 2.0f; 102dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 103dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 104dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Determines whether array expansion by <code>expansionFactor</code> 105dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * is additive or multiplicative. 106dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 107dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected int expansionMode = MULTIPLICATIVE_MODE; 108dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 109dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 110dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The initial capacity of the array. Initial capacity is not exposed as a 111dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * property as it is only meaningful when passed to a constructor. 112dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 113dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected int initialCapacity = 16; 114dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 115dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 116dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The internal storage array. 117dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 118dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected double[] internalArray; 119dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 120dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 121dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The number of addressable elements in the array. Note that this 122dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * has nothing to do with the length of the internal storage array. 123dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 124dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected int numElements = 0; 125dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 126dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 127dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The position of the first addressable element in the internal storage 128dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * array. The addressable elements in the array are <code> 129dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * internalArray[startIndex],...,internalArray[startIndex + numElements -1] 130dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </code> 131dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 132dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected int startIndex = 0; 133dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 134dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 135dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Create a ResizableArray with default properties. 136dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <ul> 137dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li><code>initialCapacity = 16</code></li> 138dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li><code>expansionMode = MULTIPLICATIVE_MODE</code></li> 139dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li><code>expansionFactor = 2.5</code></li> 140dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li><code>contractionFactor = 2.0</code></li> 141dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </ul> 142dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 143dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public ResizableDoubleArray() { 144dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond internalArray = new double[initialCapacity]; 145dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 146dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 147dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 148dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Create a ResizableArray with the specified initial capacity. Other 149dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * properties take default values: 150dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <ul> 151dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li><code>expansionMode = MULTIPLICATIVE_MODE</code></li> 152dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li><code>expansionFactor = 2.5</code></li> 153dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li><code>contractionFactor = 2.0</code></li> 154dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </ul> 155dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param initialCapacity The initial size of the internal storage array 156dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws IllegalArgumentException if initialCapacity is not > 0 157dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 158dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public ResizableDoubleArray(int initialCapacity) { 159dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond setInitialCapacity(initialCapacity); 160dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond internalArray = new double[this.initialCapacity]; 161dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 162dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 163dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 164dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Create a ResizableArray from an existing double[] with the 165dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * initial capacity and numElements corresponding to the size of 166dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the supplied double[] array. If the supplied array is null, a 167dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * new empty array with the default initial capacity will be created. 168dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The input array is copied, not referenced. 169dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Other properties take default values: 170dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <ul> 171dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li><code>initialCapacity = 16</code></li> 172dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li><code>expansionMode = MULTIPLICATIVE_MODE</code></li> 173dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li><code>expansionFactor = 2.5</code></li> 174dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li><code>contractionFactor = 2.0</code></li> 175dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </ul> 176dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 177dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param initialArray initial array 178dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.2 179dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 180dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public ResizableDoubleArray(double[] initialArray) { 181dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (initialArray == null) { 182dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond this.internalArray = new double[initialCapacity]; 183dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 184dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond this.internalArray = new double[initialArray.length]; 185dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond System.arraycopy(initialArray, 0, this.internalArray, 0, initialArray.length); 186dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond initialCapacity = initialArray.length; 187dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond numElements = initialArray.length; 188dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 189dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 190dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 191dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 192dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 193dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Create a ResizableArray with the specified initial capacity 194dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * and expansion factor. The remaining properties take default 195dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * values: 196dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <ul> 197dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li><code>expansionMode = MULTIPLICATIVE_MODE</code></li> 198dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li><code>contractionFactor = 0.5 + expansionFactor</code></li> 199dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </ul></p> 200dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 201dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Throws IllegalArgumentException if the following conditions are 202dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * not met: 203dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <ul> 204dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li><code>initialCapacity > 0</code></li> 205dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li><code>expansionFactor > 1</code></li> 206dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </ul></p> 207dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 208dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param initialCapacity The initial size of the internal storage array 209dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param expansionFactor the array will be expanded based on this 210dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * parameter 211dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws IllegalArgumentException if parameters are not valid 212dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 213dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public ResizableDoubleArray(int initialCapacity, float expansionFactor) { 214dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond this.expansionFactor = expansionFactor; 215dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond setInitialCapacity(initialCapacity); 216dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond internalArray = new double[initialCapacity]; 217dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond setContractionCriteria(expansionFactor +0.5f); 218dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 219dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 220dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 221dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 222dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Create a ResizableArray with the specified initialCapacity, 223dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * expansionFactor, and contractionCriteria. The <code>expansionMode</code> 224dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * will default to <code>MULTIPLICATIVE_MODE.</code></p> 225dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 226dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Throws IllegalArgumentException if the following conditions are 227dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * not met: 228dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <ul> 229dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li><code>initialCapacity > 0</code></li> 230dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li><code>expansionFactor > 1</code></li> 231dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li><code>contractionFactor >= expansionFactor</code></li> 232dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </ul></p> 233dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param initialCapacity The initial size of the internal storage array 234dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param expansionFactor the array will be expanded based on this 235dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * parameter 236dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param contractionCriteria The contraction Criteria. 237dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws IllegalArgumentException if parameters are not valid 238dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 239dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public ResizableDoubleArray(int initialCapacity, float expansionFactor, 240dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond float contractionCriteria) { 241dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond this.expansionFactor = expansionFactor; 242dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond setContractionCriteria(contractionCriteria); 243dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond setInitialCapacity(initialCapacity); 244dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond internalArray = new double[initialCapacity]; 245dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 246dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 247dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 248dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 249dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Create a ResizableArray with the specified properties.</p> 250dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 251dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Throws IllegalArgumentException if the following conditions are 252dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * not met: 253dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <ul> 254dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li><code>initialCapacity > 0</code></li> 255dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li><code>expansionFactor > 1</code></li> 256dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li><code>contractionFactor >= expansionFactor</code></li> 257dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li><code>expansionMode in {MULTIPLICATIVE_MODE, ADDITIVE_MODE}</code> 258dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </li> 259dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </ul></p> 260dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 261dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param initialCapacity the initial size of the internal storage array 262dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param expansionFactor the array will be expanded based on this 263dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * parameter 264dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param contractionCriteria the contraction Criteria 265dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param expansionMode the expansion mode 266dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws IllegalArgumentException if parameters are not valid 267dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 268dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public ResizableDoubleArray(int initialCapacity, float expansionFactor, 269dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond float contractionCriteria, int expansionMode) { 270dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond this.expansionFactor = expansionFactor; 271dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond setContractionCriteria(contractionCriteria); 272dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond setInitialCapacity(initialCapacity); 273dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond setExpansionMode(expansionMode); 274dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond internalArray = new double[initialCapacity]; 275dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 276dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 277dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 278dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Copy constructor. Creates a new ResizableDoubleArray that is a deep, 279dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * fresh copy of the original. Needs to acquire synchronization lock 280dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * on original. Original may not be null; otherwise a NullPointerException 281dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * is thrown. 282dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 283dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param original array to copy 284dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.0 285dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 286dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public ResizableDoubleArray(ResizableDoubleArray original) { 287dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond copy(original, this); 288dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 289dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 290dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 291dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Adds an element to the end of this expandable array. 292dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 293dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param value to be added to end of array 294dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 295dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public synchronized void addElement(double value) { 296dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond numElements++; 297dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if ((startIndex + numElements) > internalArray.length) { 298dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond expand(); 299dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 300dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond internalArray[startIndex + (numElements - 1)] = value; 301dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (shouldContract()) { 302dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond contract(); 303dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 304dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 305dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 306dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 307dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Adds several element to the end of this expandable array. 308dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 309dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param values to be added to end of array 310dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.2 311dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 312dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public synchronized void addElements(double[] values) { 313dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double[] tempArray = new double[numElements + values.length + 1]; 314dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond System.arraycopy(internalArray, startIndex, tempArray, 0, numElements); 315dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond System.arraycopy(values, 0, tempArray, numElements, values.length); 316dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond internalArray = tempArray; 317dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond startIndex = 0; 318dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond numElements += values.length; 319dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 320dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 321dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 322dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 323dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Adds an element to the end of the array and removes the first 324dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * element in the array. Returns the discarded first element. 325dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The effect is similar to a push operation in a FIFO queue. 326dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </p> 327dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 328dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Example: If the array contains the elements 1, 2, 3, 4 (in that order) 329dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * and addElementRolling(5) is invoked, the result is an array containing 330dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the entries 2, 3, 4, 5 and the value returned is 1. 331dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </p> 332dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 333dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param value the value to be added to the array 334dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the value which has been discarded or "pushed" out of the array 335dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * by this rolling insert 336dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 337dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public synchronized double addElementRolling(double value) { 338dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double discarded = internalArray[startIndex]; 339dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 340dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if ((startIndex + (numElements + 1)) > internalArray.length) { 341dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond expand(); 342dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 343dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Increment the start index 344dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond startIndex += 1; 345dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 346dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Add the new value 347dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond internalArray[startIndex + (numElements - 1)] = value; 348dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 349dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Check the contraction criteria 350dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (shouldContract()) { 351dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond contract(); 352dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 353dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return discarded; 354dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 355dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 356dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 357dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Substitutes <code>value</code> for the most recently added value. 358dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Returns the value that has been replaced. If the array is empty (i.e. 359dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * if {@link #numElements} is zero), a MathRuntimeException is thrown. 360dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 361dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param value new value to substitute for the most recently added value 362dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return value that has been replaced in the array 363dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.0 364dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 365dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public synchronized double substituteMostRecentElement(double value) { 366dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (numElements < 1) { 367dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw MathRuntimeException.createArrayIndexOutOfBoundsException( 368dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LocalizedFormats.CANNOT_SUBSTITUTE_ELEMENT_FROM_EMPTY_ARRAY); 369dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 370dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 371dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double discarded = internalArray[startIndex + (numElements - 1)]; 372dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 373dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond internalArray[startIndex + (numElements - 1)] = value; 374dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 375dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return discarded; 376dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 377dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 378dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 379dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 380dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Checks the expansion factor and the contraction criteria and throws an 381dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * IllegalArgumentException if the contractionCriteria is less than the 382dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * expansionCriteria 383dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 384dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param expansion factor to be checked 385dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param contraction criteria to be checked 386dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws IllegalArgumentException if the contractionCriteria is less than 387dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the expansionCriteria. 388dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 389dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected void checkContractExpand(float contraction, float expansion) { 390dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 391dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (contraction < expansion) { 392dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw MathRuntimeException.createIllegalArgumentException( 393dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LocalizedFormats.CONTRACTION_CRITERIA_SMALLER_THAN_EXPANSION_FACTOR, 394dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond contraction, expansion); 395dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 396dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 397dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (contraction <= 1.0) { 398dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw MathRuntimeException.createIllegalArgumentException( 399dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LocalizedFormats.CONTRACTION_CRITERIA_SMALLER_THAN_ONE, 400dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond contraction); 401dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 402dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 403dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (expansion <= 1.0) { 404dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw MathRuntimeException.createIllegalArgumentException( 405dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LocalizedFormats.EXPANSION_FACTOR_SMALLER_THAN_ONE, 406dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond expansion); 407dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 408dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 409dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 410dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 411dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Clear the array, reset the size to the initialCapacity and the number 412dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * of elements to zero. 413dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 414dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public synchronized void clear() { 415dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond numElements = 0; 416dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond startIndex = 0; 417dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond internalArray = new double[initialCapacity]; 418dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 419dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 420dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 421dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Contracts the storage array to the (size of the element set) + 1 - to 422dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * avoid a zero length array. This function also resets the startIndex to 423dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * zero. 424dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 425dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public synchronized void contract() { 426dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double[] tempArray = new double[numElements + 1]; 427dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 428dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Copy and swap - copy only the element array from the src array. 429dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond System.arraycopy(internalArray, startIndex, tempArray, 0, numElements); 430dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond internalArray = tempArray; 431dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 432dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Reset the start index to zero 433dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond startIndex = 0; 434dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 435dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 436dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 437dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Discards the <code>i<code> initial elements of the array. For example, 438dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * if the array contains the elements 1,2,3,4, invoking 439dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <code>discardFrontElements(2)</code> will cause the first two elements 440dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * to be discarded, leaving 3,4 in the array. Throws illegalArgumentException 441dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * if i exceeds numElements. 442dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 443dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param i the number of elements to discard from the front of the array 444dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws IllegalArgumentException if i is greater than numElements. 445dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.0 446dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 447dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public synchronized void discardFrontElements(int i) { 448dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 449dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond discardExtremeElements(i,true); 450dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 451dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 452dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 453dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 454dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Discards the <code>i<code> last elements of the array. For example, 455dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * if the array contains the elements 1,2,3,4, invoking 456dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <code>discardMostRecentElements(2)</code> will cause the last two elements 457dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * to be discarded, leaving 1,2 in the array. Throws illegalArgumentException 458dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * if i exceeds numElements. 459dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 460dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param i the number of elements to discard from the end of the array 461dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws IllegalArgumentException if i is greater than numElements. 462dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.0 463dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 464dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public synchronized void discardMostRecentElements(int i) { 465dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 466dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond discardExtremeElements(i,false); 467dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 468dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 469dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 470dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 471dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Discards the <code>i<code> first or last elements of the array, 472dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * depending on the value of <code>front</code>. 473dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * For example, if the array contains the elements 1,2,3,4, invoking 474dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <code>discardExtremeElements(2,false)</code> will cause the last two elements 475dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * to be discarded, leaving 1,2 in the array. 476dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * For example, if the array contains the elements 1,2,3,4, invoking 477dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <code>discardExtremeElements(2,true)</code> will cause the first two elements 478dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * to be discarded, leaving 3,4 in the array. 479dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Throws illegalArgumentException 480dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * if i exceeds numElements. 481dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 482dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param i the number of elements to discard from the front/end of the array 483dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param front true if elements are to be discarded from the front 484dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * of the array, false if elements are to be discarded from the end 485dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * of the array 486dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws IllegalArgumentException if i is greater than numElements. 487dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.0 488dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 489dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private synchronized void discardExtremeElements(int i,boolean front) { 490dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (i > numElements) { 491dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw MathRuntimeException.createIllegalArgumentException( 492dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LocalizedFormats.TOO_MANY_ELEMENTS_TO_DISCARD_FROM_ARRAY, 493dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond i, numElements); 494dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else if (i < 0) { 495dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw MathRuntimeException.createIllegalArgumentException( 496dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LocalizedFormats.CANNOT_DISCARD_NEGATIVE_NUMBER_OF_ELEMENTS, 497dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond i); 498dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 499dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // "Subtract" this number of discarded from numElements 500dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond numElements -= i; 501dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (front) startIndex += i; 502dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 503dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (shouldContract()) { 504dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond contract(); 505dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 506dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 507dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 508dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 509dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Expands the internal storage array using the expansion factor. 510dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 511dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * if <code>expansionMode</code> is set to MULTIPLICATIVE_MODE, 512dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the new array size will be <code>internalArray.length * expansionFactor.</code> 513dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * If <code>expansionMode</code> is set to ADDITIVE_MODE, the length 514dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * after expansion will be <code>internalArray.length + expansionFactor</code> 515dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </p> 516dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 517dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected synchronized void expand() { 518dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 519dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // notice the use of FastMath.ceil(), this guarantees that we will always 520dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // have an array of at least currentSize + 1. Assume that the 521dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // current initial capacity is 1 and the expansion factor 522dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // is 1.000000000000000001. The newly calculated size will be 523dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // rounded up to 2 after the multiplication is performed. 524dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int newSize = 0; 525dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (expansionMode == MULTIPLICATIVE_MODE) { 526dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond newSize = (int) FastMath.ceil(internalArray.length * expansionFactor); 527dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 528dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond newSize = internalArray.length + FastMath.round(expansionFactor); 529dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 530dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double[] tempArray = new double[newSize]; 531dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 532dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Copy and swap 533dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond System.arraycopy(internalArray, 0, tempArray, 0, internalArray.length); 534dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond internalArray = tempArray; 535dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 536dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 537dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 538dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Expands the internal storage array to the specified size. 539dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 540dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param size Size of the new internal storage array 541dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 542dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private synchronized void expandTo(int size) { 543dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double[] tempArray = new double[size]; 544dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Copy and swap 545dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond System.arraycopy(internalArray, 0, tempArray, 0, internalArray.length); 546dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond internalArray = tempArray; 547dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 548dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 549dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 550dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The contraction criteria defines when the internal array will contract 551dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * to store only the number of elements in the element array. 552dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * If the <code>expansionMode</code> is <code>MULTIPLICATIVE_MODE</code>, 553dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * contraction is triggered when the ratio between storage array length 554dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * and <code>numElements</code> exceeds <code>contractionFactor</code>. 555dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * If the <code>expansionMode</code> is <code>ADDITIVE_MODE</code>, the 556dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * number of excess storage locations is compared to 557dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <code>contractionFactor.</code> 558dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 559dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the contraction criteria used to reclaim memory. 560dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 561dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public float getContractionCriteria() { 562dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return contractionCriteria; 563dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 564dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 565dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 566dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Returns the element at the specified index 567dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 568dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param index index to fetch a value from 569dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return value stored at the specified index 570dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws ArrayIndexOutOfBoundsException if <code>index</code> is less than 571dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * zero or is greater than <code>getNumElements() - 1</code>. 572dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 573dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public synchronized double getElement(int index) { 574dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (index >= numElements) { 575dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw MathRuntimeException.createArrayIndexOutOfBoundsException( 576dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LocalizedFormats.INDEX_LARGER_THAN_MAX, 577dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond index, numElements - 1); 578dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else if (index >= 0) { 579dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return internalArray[startIndex + index]; 580dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 581dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw MathRuntimeException.createArrayIndexOutOfBoundsException( 582dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LocalizedFormats.CANNOT_RETRIEVE_AT_NEGATIVE_INDEX, 583dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond index); 584dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 585dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 586dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 587dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 588dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Returns a double array containing the elements of this 589dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <code>ResizableArray</code>. This method returns a copy, not a 590dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * reference to the underlying array, so that changes made to the returned 591dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * array have no effect on this <code>ResizableArray.</code> 592dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the double array. 593dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 594dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public synchronized double[] getElements() { 595dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double[] elementArray = new double[numElements]; 596dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond System.arraycopy( internalArray, startIndex, elementArray, 0, 597dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond numElements); 598dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return elementArray; 599dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 600dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 601dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 602dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The expansion factor controls the size of a new array when an array 603dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * needs to be expanded. The <code>expansionMode</code> 604dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * determines whether the size of the array is multiplied by the 605dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <code>expansionFactor</code> (MULTIPLICATIVE_MODE) or if 606dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the expansion is additive (ADDITIVE_MODE -- <code>expansionFactor</code> 607dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * storage locations added). The default <code>expansionMode</code> is 608dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * MULTIPLICATIVE_MODE and the default <code>expansionFactor</code> 609dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * is 2.0. 610dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 611dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the expansion factor of this expandable double array 612dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 613dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public float getExpansionFactor() { 614dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return expansionFactor; 615dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 616dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 617dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 618dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The <code>expansionMode</code> determines whether the internal storage 619dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * array grows additively (ADDITIVE_MODE) or multiplicatively 620dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * (MULTIPLICATIVE_MODE) when it is expanded. 621dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 622dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return Returns the expansionMode. 623dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 624dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public int getExpansionMode() { 625dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return expansionMode; 626dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 627dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 628dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 629dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Notice the package scope on this method. This method is simply here 630dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * for the JUnit test, it allows us check if the expansion is working 631dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * properly after a number of expansions. This is not meant to be a part 632dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * of the public interface of this class. 633dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 634dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the length of the internal storage array. 635dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 636dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond synchronized int getInternalLength() { 637dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return internalArray.length; 638dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 639dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 640dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 641dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Returns the number of elements currently in the array. Please note 642dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * that this is different from the length of the internal storage array. 643dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 644dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return number of elements 645dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 646dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public synchronized int getNumElements() { 647dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return numElements; 648dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 649dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 650dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 651dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Returns the internal storage array. Note that this method returns 652dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * a reference to the internal storage array, not a copy, and to correctly 653dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * address elements of the array, the <code>startIndex</code> is 654dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * required (available via the {@link #start} method). This method should 655dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * only be used in cases where copying the internal array is not practical. 656dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The {@link #getElements} method should be used in all other cases. 657dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 658dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 659dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the internal storage array used by this object 660dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @deprecated replaced by {@link #getInternalValues()} as of 2.0 661dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 662dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond @Deprecated 663dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public synchronized double[] getValues() { 664dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return internalArray; 665dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 666dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 667dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 668dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Returns the internal storage array. Note that this method returns 669dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * a reference to the internal storage array, not a copy, and to correctly 670dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * address elements of the array, the <code>startIndex</code> is 671dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * required (available via the {@link #start} method). This method should 672dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * only be used in cases where copying the internal array is not practical. 673dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The {@link #getElements} method should be used in all other cases. 674dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 675dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 676dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the internal storage array used by this object 677dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.0 678dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 679dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public synchronized double[] getInternalValues() { 680dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return internalArray; 681dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 682dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 683dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 684dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Sets the contraction criteria for this ExpandContractDoubleArray. 685dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 686dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param contractionCriteria contraction criteria 687dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 688dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public void setContractionCriteria(float contractionCriteria) { 689dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond checkContractExpand(contractionCriteria, getExpansionFactor()); 690dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond synchronized(this) { 691dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond this.contractionCriteria = contractionCriteria; 692dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 693dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 694dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 695dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 696dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 697dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Sets the element at the specified index. If the specified index is greater than 698dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <code>getNumElements() - 1</code>, the <code>numElements</code> property 699dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * is increased to <code>index +1</code> and additional storage is allocated 700dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * (if necessary) for the new element and all (uninitialized) elements 701dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * between the new element and the previous end of the array). 702dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 703dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param index index to store a value in 704dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param value value to store at the specified index 705dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws ArrayIndexOutOfBoundsException if <code>index</code> is less than 706dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * zero. 707dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 708dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public synchronized void setElement(int index, double value) { 709dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (index < 0) { 710dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw MathRuntimeException.createArrayIndexOutOfBoundsException( 711dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LocalizedFormats.CANNOT_SET_AT_NEGATIVE_INDEX, 712dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond index); 713dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 714dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (index + 1 > numElements) { 715dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond numElements = index + 1; 716dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 717dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if ((startIndex + index) >= internalArray.length) { 718dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond expandTo(startIndex + (index + 1)); 719dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 720dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond internalArray[startIndex + index] = value; 721dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 722dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 723dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 724dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Sets the expansionFactor. Throws IllegalArgumentException if the 725dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the following conditions are not met: 726dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <ul> 727dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li><code>expansionFactor > 1</code></li> 728dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li><code>contractionFactor >= expansionFactor</code></li> 729dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </ul> 730dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param expansionFactor the new expansion factor value. 731dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws IllegalArgumentException if expansionFactor is <= 1 or greater 732dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * than contractionFactor 733dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 734dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public void setExpansionFactor(float expansionFactor) { 735dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond checkContractExpand(getContractionCriteria(), expansionFactor); 736dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // The check above verifies that the expansion factor is > 1.0; 737dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond synchronized(this) { 738dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond this.expansionFactor = expansionFactor; 739dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 740dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 741dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 742dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 743dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Sets the <code>expansionMode</code>. The specified value must be one of 744dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * ADDITIVE_MODE, MULTIPLICATIVE_MODE. 745dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 746dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param expansionMode The expansionMode to set. 747dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws IllegalArgumentException if the specified mode value is not valid 748dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 749dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public void setExpansionMode(int expansionMode) { 750dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (expansionMode != MULTIPLICATIVE_MODE && 751dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond expansionMode != ADDITIVE_MODE) { 752dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw MathRuntimeException.createIllegalArgumentException( 753dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LocalizedFormats.UNSUPPORTED_EXPANSION_MODE, 754dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond expansionMode, MULTIPLICATIVE_MODE, "MULTIPLICATIVE_MODE", 755dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ADDITIVE_MODE, "ADDITIVE_MODE"); 756dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 757dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond synchronized(this) { 758dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond this.expansionMode = expansionMode; 759dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 760dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 761dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 762dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 763dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Sets the initial capacity. Should only be invoked by constructors. 764dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 765dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param initialCapacity of the array 766dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws IllegalArgumentException if <code>initialCapacity</code> is not 767dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * positive. 768dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 769dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected void setInitialCapacity(int initialCapacity) { 770dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (initialCapacity > 0) { 771dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond synchronized(this) { 772dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond this.initialCapacity = initialCapacity; 773dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 774dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 775dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw MathRuntimeException.createIllegalArgumentException( 776dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LocalizedFormats.INITIAL_CAPACITY_NOT_POSITIVE, 777dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond initialCapacity); 778dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 779dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 780dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 781dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 782dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * This function allows you to control the number of elements contained 783dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * in this array, and can be used to "throw out" the last n values in an 784dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * array. This function will also expand the internal array as needed. 785dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 786dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param i a new number of elements 787dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws IllegalArgumentException if <code>i</code> is negative. 788dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 789dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public synchronized void setNumElements(int i) { 790dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 791dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // If index is negative thrown an error 792dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (i < 0) { 793dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw MathRuntimeException.createIllegalArgumentException( 794dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LocalizedFormats.INDEX_NOT_POSITIVE, 795dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond i); 796dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 797dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 798dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Test the new num elements, check to see if the array needs to be 799dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // expanded to accommodate this new number of elements 800dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if ((startIndex + i) > internalArray.length) { 801dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond expandTo(startIndex + i); 802dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 803dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 804dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // Set the new number of elements to new value 805dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond numElements = i; 806dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 807dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 808dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 809dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Returns true if the internal storage array has too many unused 810dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * storage positions. 811dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 812dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return true if array satisfies the contraction criteria 813dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 814dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private synchronized boolean shouldContract() { 815dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (expansionMode == MULTIPLICATIVE_MODE) { 816dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (internalArray.length / ((float) numElements)) > contractionCriteria; 817dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 818dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (internalArray.length - numElements) > contractionCriteria; 819dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 820dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 821dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 822dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 823dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Returns the starting index of the internal array. The starting index is 824dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the position of the first addressable element in the internal storage 825dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * array. The addressable elements in the array are <code> 826dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * internalArray[startIndex],...,internalArray[startIndex + numElements -1] 827dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </code> 828dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 829dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return starting index 830dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 831dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public synchronized int start() { 832dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return startIndex; 833dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 834dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 835dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 836dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p>Copies source to dest, copying the underlying data, so dest is 837dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * a new, independent copy of source. Does not contract before 838dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the copy.</p> 839dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 840dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p>Obtains synchronization locks on both source and dest 841dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * (in that order) before performing the copy.</p> 842dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 843dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p>Neither source nor dest may be null; otherwise a NullPointerException 844dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * is thrown</p> 845dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 846dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param source ResizableDoubleArray to copy 847dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param dest ResizableArray to replace with a copy of the source array 848dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.0 849dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 850dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 851dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static void copy(ResizableDoubleArray source, ResizableDoubleArray dest) { 852dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond synchronized(source) { 853dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond synchronized(dest) { 854dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond dest.initialCapacity = source.initialCapacity; 855dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond dest.contractionCriteria = source.contractionCriteria; 856dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond dest.expansionFactor = source.expansionFactor; 857dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond dest.expansionMode = source.expansionMode; 858dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond dest.internalArray = new double[source.internalArray.length]; 859dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond System.arraycopy(source.internalArray, 0, dest.internalArray, 860dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 0, dest.internalArray.length); 861dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond dest.numElements = source.numElements; 862dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond dest.startIndex = source.startIndex; 863dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 864dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 865dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 866dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 867dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 868dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Returns a copy of the ResizableDoubleArray. Does not contract before 869dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the copy, so the returned object is an exact copy of this. 870dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 871dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return a new ResizableDoubleArray with the same data and configuration 872dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * properties as this 873dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.0 874dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 875dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public synchronized ResizableDoubleArray copy() { 876dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ResizableDoubleArray result = new ResizableDoubleArray(); 877dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond copy(this, result); 878dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return result; 879dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 880dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 881dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 882dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Returns true iff object is a ResizableDoubleArray with the same properties 883dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * as this and an identical internal storage array. 884dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 885dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param object object to be compared for equality with this 886dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return true iff object is a ResizableDoubleArray with the same data and 887dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * properties as this 888dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.0 889dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 890dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond @Override 891dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public boolean equals(Object object) { 892dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (object == this ) { 893dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return true; 894dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 895dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (object instanceof ResizableDoubleArray == false) { 896dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return false; 897dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 898dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond synchronized(this) { 899dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond synchronized(object) { 900dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond boolean result = true; 901dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ResizableDoubleArray other = (ResizableDoubleArray) object; 902dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result = result && (other.initialCapacity == initialCapacity); 903dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result = result && (other.contractionCriteria == contractionCriteria); 904dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result = result && (other.expansionFactor == expansionFactor); 905dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result = result && (other.expansionMode == expansionMode); 906dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result = result && (other.numElements == numElements); 907dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result = result && (other.startIndex == startIndex); 908dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (!result) { 909dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return false; 910dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 911dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Arrays.equals(internalArray, other.internalArray); 912dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 913dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 914dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 915dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 916dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 917dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 918dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Returns a hash code consistent with equals. 919dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 920dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return hash code representing this ResizableDoubleArray 921dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.0 922dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 923dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond @Override 924dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public synchronized int hashCode() { 925dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int[] hashData = new int[7]; 926dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond hashData[0] = new Float(expansionFactor).hashCode(); 927dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond hashData[1] = new Float(contractionCriteria).hashCode(); 928dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond hashData[2] = expansionMode; 929dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond hashData[3] = Arrays.hashCode(internalArray); 930dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond hashData[4] = initialCapacity; 931dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond hashData[5] = numElements; 932dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond hashData[6] = startIndex; 933dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return Arrays.hashCode(hashData); 934dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 935dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 936dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond} 937