1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2001, Eric D. Friedman All Rights Reserved.
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 ///////////////////////////////////////////////////////////////////////////////
21 import java.io.Externalizable;
22 import java.io.IOException;
23 import java.io.ObjectInput;
24 import java.io.ObjectOutput;
25 import java.util.Arrays;
26 import java.util.Random;
29 //////////////////////////////////////////////////
30 // THIS IS A GENERATED CLASS. DO NOT HAND EDIT! //
31 //////////////////////////////////////////////////
35 * A resizable, array-backed list of float primitives.
37 * Created: Sat Dec 29 14:21:12 2001
39 * @author Eric D. Friedman
43 public class TFloatArrayList implements Externalizable, Cloneable {
44 static final long serialVersionUID = 1L;
46 /** the data of the list */
47 protected float[] _data;
49 /** the index after the last entry in the list */
52 /** the default capacity for new lists */
53 protected static final int DEFAULT_CAPACITY = 10;
56 * Creates a new <code>TFloatArrayList</code> instance with the
59 public TFloatArrayList() {
60 this(DEFAULT_CAPACITY);
64 * Creates a new <code>TFloatArrayList</code> instance with the
67 * @param capacity an <code>int</code> value
69 public TFloatArrayList(int capacity) {
70 _data = new float[capacity];
75 * Creates a new <code>TFloatArrayList</code> instance whose
76 * capacity is the greater of the length of <tt>values</tt> and
77 * DEFAULT_CAPACITY and whose initial contents are the specified
80 * @param values an <code>float[]</code> value
82 public TFloatArrayList(float[] values) {
83 this(Math.max(values.length, DEFAULT_CAPACITY));
90 * Grow the internal array as needed to accommodate the specified
91 * number of elements. The size of the array floats on each
92 * resize unless <tt>capacity</tt> requires more than twice the
95 * @param capacity an <code>int</code> value
97 public void ensureCapacity(int capacity) {
98 if (capacity > _data.length) {
99 int newCap = Math.max(_data.length << 1, capacity);
100 float[] tmp = new float[newCap];
101 System.arraycopy(_data, 0, tmp, 0, _data.length);
107 * Returns the number of values in the list.
109 * @return the number of values in the list.
116 * Tests whether this list contains any values.
118 * @return true if the list is empty.
120 public boolean isEmpty() {
125 * Sheds any excess capacity above and beyond the current size of
128 public void trimToSize() {
129 if (_data.length > size()) {
130 float[] tmp = new float[size()];
131 toNativeArray(tmp, 0, tmp.length);
139 * Adds <tt>val</tt> to the end of the list, growing as needed.
141 * @param val an <code>float</code> value
143 public void add(float val) {
144 ensureCapacity(_pos + 1);
149 * Adds the values in the array <tt>vals</tt> to the end of the
152 * @param vals an <code>float[]</code> value
154 public void add(float[] vals) {
155 add(vals, 0, vals.length);
159 * Adds a subset of the values in the array <tt>vals</tt> to the
160 * end of the list, in order.
162 * @param vals an <code>float[]</code> value
163 * @param offset the offset at which to start copying
164 * @param length the number of values to copy.
166 public void add(float[] vals, int offset, int length) {
167 ensureCapacity(_pos + length);
168 System.arraycopy(vals, offset, _data, _pos, length);
173 * Inserts <tt>value</tt> into the list at <tt>offset</tt>. All
174 * values including and to the right of <tt>offset</tt> are shifted
177 * @param offset an <code>int</code> value
178 * @param value an <code>float</code> value
180 public void insert(int offset, float value) {
181 if (offset == _pos) {
185 ensureCapacity(_pos + 1);
187 System.arraycopy(_data, offset, _data, offset + 1, _pos - offset);
189 _data[offset] = value;
194 * Inserts the array of <tt>values</tt> into the list at
195 * <tt>offset</tt>. All values including and to the right of
196 * <tt>offset</tt> are shifted to the right.
198 * @param offset an <code>int</code> value
199 * @param values an <code>float[]</code> value
201 public void insert(int offset, float[] values) {
202 insert(offset, values, 0, values.length);
206 * Inserts a slice of the array of <tt>values</tt> into the list
207 * at <tt>offset</tt>. All values including and to the right of
208 * <tt>offset</tt> are shifted to the right.
210 * @param offset an <code>int</code> value
211 * @param values an <code>float[]</code> value
212 * @param valOffset the offset in the values array at which to
214 * @param len the number of values to copy from the values array
216 public void insert(int offset, float[] values, int valOffset, int len) {
217 if (offset == _pos) {
218 add(values, valOffset, len);
222 ensureCapacity(_pos + len);
224 System.arraycopy(_data, offset, _data, offset + len, _pos - offset);
226 System.arraycopy(values, valOffset, _data, offset, len);
231 * Returns the value at the specified offset.
233 * @param offset an <code>int</code> value
234 * @return an <code>float</code> value
236 public float get(int offset) {
237 if (offset >= _pos) {
238 throw new ArrayIndexOutOfBoundsException(offset);
240 return _data[offset];
244 * Returns the value at the specified offset without doing any
247 * @param offset an <code>int</code> value
248 * @return an <code>float</code> value
250 public float getQuick(int offset) {
251 return _data[offset];
255 * Sets the value at the specified offset.
257 * @param offset an <code>int</code> value
258 * @param val an <code>float</code> value
260 public void set(int offset, float val) {
261 if (offset >= _pos) {
262 throw new ArrayIndexOutOfBoundsException(offset);
268 * Sets the value at the specified offset and returns the
269 * previously stored value.
271 * @param offset an <code>int</code> value
272 * @param val an <code>float</code> value
273 * @return the value previously stored at offset.
275 public float getSet(int offset, float val) {
276 if (offset >= _pos) {
277 throw new ArrayIndexOutOfBoundsException(offset);
279 float old = _data[offset];
285 * Replace the values in the list starting at <tt>offset</tt> with
286 * the contents of the <tt>values</tt> array.
288 * @param offset the first offset to replace
289 * @param values the source of the new values
291 public void set(int offset, float[] values) {
292 set(offset, values, 0, values.length);
296 * Replace the values in the list starting at <tt>offset</tt> with
297 * <tt>length</tt> values from the <tt>values</tt> array, starting
300 * @param offset the first offset to replace
301 * @param values the source of the new values
302 * @param valOffset the first value to copy from the values array
303 * @param length the number of values to copy
305 public void set(int offset, float[] values, int valOffset, int length) {
306 if (offset < 0 || offset + length > _pos) {
307 throw new ArrayIndexOutOfBoundsException(offset);
309 System.arraycopy(values, valOffset, _data, offset, length);
313 * Sets the value at the specified offset without doing any bounds
316 * @param offset an <code>int</code> value
317 * @param val an <code>float</code> value
319 public void setQuick(int offset, float val) {
324 * Flushes the internal state of the list, resetting the capacity
327 public void clear() {
328 clear(DEFAULT_CAPACITY);
332 * Flushes the internal state of the list, setting the capacity of
333 * the empty list to <tt>capacity</tt>.
335 * @param capacity an <code>int</code> value
337 public void clear(int capacity) {
338 _data = new float[capacity];
343 * Sets the size of the list to 0, but does not change its
344 * capacity. This method can be used as an alternative to the
345 * {@link #clear clear} method if you want to recyle a list without
346 * allocating new backing arrays.
350 public void reset() {
356 * Sets the size of the list to 0, but does not change its
357 * capacity. This method can be used as an alternative to the
358 * {@link #clear clear} method if you want to recyle a list
359 * without allocating new backing arrays. This method differs
360 * from {@link #reset reset} in that it does not clear the old
361 * values in the backing array. Thus, it is possible for {@link
362 * #getQuick getQuick} to return stale data if this method is used
363 * and the caller is careless about bounds checking.
369 public void resetQuick() {
374 * Removes the value at <tt>offset</tt> from the list.
376 * @param offset an <code>int</code> value
377 * @return the value previously stored at offset.
379 public float remove(int offset) {
380 float old = get(offset);
386 * Removes <tt>length</tt> values from the list, starting at
389 * @param offset an <code>int</code> value
390 * @param length an <code>int</code> value
392 public void remove(int offset, int length) {
393 if (offset < 0 || offset >= _pos) {
394 throw new ArrayIndexOutOfBoundsException(offset);
399 System.arraycopy(_data, length, _data, 0, _pos - length);
400 } else if (_pos - length == offset) {
401 // no copy to make, decrementing pos "deletes" values at
404 // data in the middle
405 System.arraycopy(_data, offset + length,
406 _data, offset, _pos - (offset + length));
409 // no need to clear old values beyond _pos, because this is a
410 // primitive collection and 0 takes as much room as any other
415 * Transform each value in the list using the specified function.
417 * @param function a <code>TFloatFunction</code> value
419 public void transformValues(TFloatFunction function) {
420 for (int i = _pos; i-- > 0;) {
421 _data[i] = function.execute(_data[i]);
426 * Reverse the order of the elements in the list.
428 public void reverse() {
433 * Reverse the order of the elements in the range of the list.
435 * @param from the inclusive index at which to start reversing
436 * @param to the exclusive index at which to stop reversing
438 public void reverse(int from, int to) {
440 return; // nothing to do
443 throw new IllegalArgumentException("from cannot be greater than to");
445 for (int i = from, j = to - 1; i < j; i++, j--) {
451 * Shuffle the elements of the list using the specified random
454 * @param rand a <code>Random</code> value
456 public void shuffle(Random rand) {
457 for (int i = _pos; i-- > 1;) {
458 swap(i, rand.nextInt(i));
463 * Swap the values at offsets <tt>i</tt> and <tt>j</tt>.
465 * @param i an offset into the data array
466 * @param j an offset into the data array
468 private final void swap(int i, int j) {
469 float tmp = _data[i];
477 * Returns a clone of this list. Since this is a primitive
478 * collection, this will be a deep clone.
480 * @return a deep clone of the list.
482 public Object clone() {
483 TFloatArrayList list = null;
485 list = (TFloatArrayList) super.clone();
486 list._data = toNativeArray();
487 } catch (CloneNotSupportedException e) {
489 } // end of try-catch
495 * Returns a sublist of this list.
497 * @param begin low endpoint (inclusive) of the subList.
498 * @param end high endpoint (exclusive) of the subList.
499 * @return sublist of this list from begin, inclusive to end, exclusive.
500 * @throws IndexOutOfBoundsException - endpoint out of range
501 * @throws IllegalArgumentException - endpoints out of order (end > begin)
503 public TFloatArrayList subList(int begin, int end) {
504 if (end < begin) throw new IllegalArgumentException("end index " + end + " greater than begin index " + begin);
505 if (begin < 0) throw new IndexOutOfBoundsException("begin index can not be < 0");
506 if (end > _data.length) throw new IndexOutOfBoundsException("end index < " + _data.length);
507 TFloatArrayList list = new TFloatArrayList(end - begin);
508 for (int i = begin; i < end; i++) {
516 * Copies the contents of the list into a native array.
518 * @return an <code>float[]</code> value
520 public float[] toNativeArray() {
521 return toNativeArray(0, _pos);
525 * Copies a slice of the list into a native array.
527 * @param offset the offset at which to start copying
528 * @param len the number of values to copy.
529 * @return an <code>float[]</code> value
531 public float[] toNativeArray(int offset, int len) {
532 float[] rv = new float[len];
533 toNativeArray(rv, offset, len);
538 * Copies a slice of the list into a native array.
540 * @param dest the array to copy into.
541 * @param offset the offset of the first value to copy
542 * @param len the number of values to copy.
544 public void toNativeArray(float[] dest, int offset, int len) {
546 return; // nothing to copy
548 if (offset < 0 || offset >= _pos) {
549 throw new ArrayIndexOutOfBoundsException(offset);
551 System.arraycopy(_data, offset, dest, 0, len);
557 * Compares this list to another list, value by value.
559 * @param other the object to compare against
560 * @return true if other is a TFloatArrayList and has exactly the
563 public boolean equals(Object other) {
566 } else if (other instanceof TFloatArrayList) {
567 TFloatArrayList that = (TFloatArrayList)other;
568 if (that.size() != this.size()) {
571 for (int i = _pos; i-- > 0;) {
572 if (this._data[i] != that._data[i]) {
583 public int hashCode() {
585 for (int i = _pos; i-- > 0;) {
586 h = 37 * h + HashFunctions.hash(_data[i]);
594 * Applies the procedure to each value in the list in ascending
595 * (front to back) order.
597 * @param procedure a <code>TFloatProcedure</code> value
598 * @return true if the procedure did not terminate prematurely.
600 public boolean forEach(TFloatProcedure procedure) {
601 for (int i = 0; i < _pos; i++) {
602 if (! procedure.execute(_data[i])) {
610 * Applies the procedure to each value in the list in descending
611 * (back to front) order.
613 * @param procedure a <code>TFloatProcedure</code> value
614 * @return true if the procedure did not terminate prematurely.
616 public boolean forEachDescending(TFloatProcedure procedure) {
617 for (int i = _pos; i-- > 0;) {
618 if (! procedure.execute(_data[i])) {
628 * Sort the values in the list (ascending) using the Sun quicksort
631 * @see java.util.Arrays#sort
634 Arrays.sort(_data, 0, _pos);
638 * Sort a slice of the list (ascending) using the Sun quicksort
641 * @param fromIndex the index at which to start sorting (inclusive)
642 * @param toIndex the index at which to stop sorting (exclusive)
643 * @see java.util.Arrays#sort
645 public void sort(int fromIndex, int toIndex) {
646 Arrays.sort(_data, fromIndex, toIndex);
652 * Fills every slot in the list with the specified value.
654 * @param val the value to use when filling
656 public void fill(float val) {
657 Arrays.fill(_data, 0, _pos, val);
661 * Fills a range in the list with the specified value.
663 * @param fromIndex the offset at which to start filling (inclusive)
664 * @param toIndex the offset at which to stop filling (exclusive)
665 * @param val the value to use when filling
667 public void fill(int fromIndex, int toIndex, float val) {
668 if (toIndex > _pos) {
669 ensureCapacity(toIndex);
672 Arrays.fill(_data, fromIndex, toIndex, val);
678 * Performs a binary search for <tt>value</tt> in the entire list.
679 * Note that you <b>must</b> @{link #sort sort} the list before
682 * @param value the value to search for
683 * @return the absolute offset in the list of the value, or its
684 * negative insertion point into the sorted list.
686 public int binarySearch(float value) {
687 return binarySearch(value, 0, _pos);
691 * Performs a binary search for <tt>value</tt> in the specified
692 * range. Note that you <b>must</b> @{link #sort sort} the list
693 * or the range before doing a search.
695 * @param value the value to search for
696 * @param fromIndex the lower boundary of the range (inclusive)
697 * @param toIndex the upper boundary of the range (exclusive)
698 * @return the absolute offset in the list of the value, or its
699 * negative insertion point into the sorted list.
701 public int binarySearch(float value, int fromIndex, int toIndex) {
703 throw new ArrayIndexOutOfBoundsException(fromIndex);
705 if (toIndex > _pos) {
706 throw new ArrayIndexOutOfBoundsException(toIndex);
710 int high = toIndex - 1;
712 while (low <= high) {
713 int mid = (low + high) >>> 1;
714 float midVal = _data[mid];
716 if (midVal < value) {
718 } else if (midVal > value) {
721 return mid; // value found
724 return -(low + 1); // value not found.
728 * Searches the list front to back for the index of
731 * @param value an <code>float</code> value
732 * @return the first offset of the value, or -1 if it is not in
734 * @see #binarySearch for faster searches on sorted lists
736 public int indexOf(float value) {
737 return indexOf(0, value);
741 * Searches the list front to back for the index of
742 * <tt>value</tt>, starting at <tt>offset</tt>.
744 * @param offset the offset at which to start the linear search
746 * @param value an <code>float</code> value
747 * @return the first offset of the value, or -1 if it is not in
749 * @see #binarySearch for faster searches on sorted lists
751 public int indexOf(int offset, float value) {
752 for (int i = offset; i < _pos; i++) {
753 if (_data[i] == value) {
761 * Searches the list back to front for the last index of
764 * @param value an <code>float</code> value
765 * @return the last offset of the value, or -1 if it is not in
767 * @see #binarySearch for faster searches on sorted lists
769 public int lastIndexOf(float value) {
770 return lastIndexOf(_pos, value);
774 * Searches the list back to front for the last index of
775 * <tt>value</tt>, starting at <tt>offset</tt>.
777 * @param offset the offset at which to start the linear search
779 * @param value an <code>float</code> value
780 * @return the last offset of the value, or -1 if it is not in
782 * @see #binarySearch for faster searches on sorted lists
784 public int lastIndexOf(int offset, float value) {
785 for (int i = offset; i-- > 0;) {
786 if (_data[i] == value) {
794 * Searches the list for <tt>value</tt>
796 * @param value an <code>float</code> value
797 * @return true if value is in the list.
799 public boolean contains(float value) {
800 return lastIndexOf(value) >= 0;
804 * Searches the list for values satisfying <tt>condition</tt> in
805 * the manner of the *nix <tt>grep</tt> utility.
807 * @param condition a condition to apply to each element in the list
808 * @return a list of values which match the condition.
810 public TFloatArrayList grep(TFloatProcedure condition) {
811 TFloatArrayList list = new TFloatArrayList();
812 for (int i = 0; i < _pos; i++) {
813 if (condition.execute(_data[i])) {
821 * Searches the list for values which do <b>not</b> satisfy
822 * <tt>condition</tt>. This is akin to *nix <code>grep -v</code>.
824 * @param condition a condition to apply to each element in the list
825 * @return a list of values which do not match the condition.
827 public TFloatArrayList inverseGrep(TFloatProcedure condition) {
828 TFloatArrayList list = new TFloatArrayList();
829 for (int i = 0; i < _pos; i++) {
830 if (! condition.execute(_data[i])) {
838 * Finds the maximum value in the list.
840 * @return the largest value in the list.
841 * @exception IllegalStateException if the list is empty
845 throw new IllegalStateException("cannot find maximum of an empty list");
847 float max = Float.NEGATIVE_INFINITY;
848 for (int i = 0; i < _pos; i++ ) {
849 if ( _data[i] > max ) {
857 * Finds the minimum value in the list.
859 * @return the smallest value in the list.
860 * @exception IllegalStateException if the list is empty
864 throw new IllegalStateException("cannot find minimum of an empty list");
866 float min = Float.POSITIVE_INFINITY;
867 for (int i = 0; i < _pos; i++ ) {
868 if ( _data[i] < min ) {
878 * Returns a String representation of the list, front to back.
880 * @return a <code>String</code> value
882 public String toString() {
883 final StringBuilder buf = new StringBuilder("{");
884 for (int i = 0, end = _pos - 1; i < end; i++) {
885 buf.append(_data[i]);
889 buf.append(_data[_pos - 1]);
892 return buf.toString();
896 public void writeExternal( ObjectOutput out ) throws IOException {
901 out.writeInt( _pos );
905 out.writeInt( _pos ); // Written twice for backwards compatability with
907 for( int i = 0; i < len; i++ ) {
908 out.writeFloat( _data[ i ] );
912 public void readExternal( ObjectInput in )
913 throws IOException, ClassNotFoundException {
922 int len = in.readInt();
923 _data = new float[ len ];
924 for( int i = 0; i < len; i++ ) {
925 _data[ i ] = in.readFloat();