@@ -50,13 +50,15 @@ public FloatList() {
5050 data = new float [10 ];
5151 }
5252
53+
5354 /**
5455 * @nowebref
5556 */
5657 public FloatList (int length ) {
5758 data = new float [length ];
5859 }
5960
61+
6062 /**
6163 * @nowebref
6264 */
@@ -66,13 +68,49 @@ public FloatList(float[] list) {
6668 System .arraycopy (list , 0 , data , 0 , count );
6769 }
6870
71+
6972 /**
73+ * Construct an FloatList from an iterable pile of objects.
74+ * For instance, a float array, an array of strings, who knows).
75+ * Un-parseable or null values will be set to NaN.
7076 * @nowebref
7177 */
72- public FloatList (Iterable <Float > iter ) {
78+ public FloatList (Iterable <Object > iter ) {
7379 this (10 );
74- for (float v : iter ) {
75- append (v );
80+ for (Object o : iter ) {
81+ if (o == null ) {
82+ append (Float .NaN );
83+ } else if (o instanceof Number ) {
84+ append (((Number ) o ).floatValue ());
85+ } else {
86+ append (PApplet .parseFloat (o .toString ().trim ()));
87+ }
88+ }
89+ crop ();
90+ }
91+
92+
93+ /**
94+ * Construct an FloatList from a random pile of objects.
95+ * Un-parseable or null values will be set to NaN.
96+ */
97+ public FloatList (Object ... items ) {
98+ // nuts, no good way to pass missingValue to this fn (varargs must be last)
99+ final float missingValue = Float .NaN ;
100+
101+ count = items .length ;
102+ data = new float [count ];
103+ int index = 0 ;
104+ for (Object o : items ) {
105+ float value = missingValue ;
106+ if (o != null ) {
107+ if (o instanceof Number ) {
108+ value = ((Number ) o ).floatValue ();
109+ } else {
110+ value = PApplet .parseFloat (o .toString ().trim (), missingValue );
111+ }
112+ }
113+ data [index ++] = value ;
76114 }
77115 }
78116
@@ -132,6 +170,9 @@ public void clear() {
132170 * @brief Get an entry at a particular index
133171 */
134172 public float get (int index ) {
173+ if (index >= count ) {
174+ throw new ArrayIndexOutOfBoundsException (index );
175+ }
135176 return data [index ];
136177 }
137178
@@ -156,6 +197,22 @@ public void set(int index, float what) {
156197 }
157198
158199
200+ /** Just an alias for append(), but matches pop() */
201+ public void push (float value ) {
202+ append (value );
203+ }
204+
205+
206+ public float pop () {
207+ if (count == 0 ) {
208+ throw new RuntimeException ("Can't call pop() on an empty list" );
209+ }
210+ float value = get (count -1 );
211+ count --;
212+ return value ;
213+ }
214+
215+
159216 /**
160217 * Remove an element from the specified index.
161218 *
@@ -288,6 +345,14 @@ public void append(FloatList list) {
288345 }
289346
290347
348+ /** Add this value, but only if it's not already in the list. */
349+ public void appendUnique (float value ) {
350+ if (!hasValue (value )) {
351+ append (value );
352+ }
353+ }
354+
355+
291356// public void insert(int index, int value) {
292357// if (index+1 > count) {
293358// if (index+1 < data.length) {
@@ -318,8 +383,13 @@ public void append(FloatList list) {
318383// }
319384
320385
386+ public void insert (int index , float value ) {
387+ insert (index , new float [] { value });
388+ }
389+
390+
321391 // same as splice
322- public void insert (int index , int [] values ) {
392+ public void insert (int index , float [] values ) {
323393 if (index < 0 ) {
324394 throw new IllegalArgumentException ("insert() index cannot be negative: it was " + index );
325395 }
@@ -347,7 +417,7 @@ public void insert(int index, int[] values) {
347417 }
348418
349419
350- public void insert (int index , IntList list ) {
420+ public void insert (int index , FloatList list ) {
351421 insert (index , list .values ());
352422 }
353423
@@ -437,12 +507,23 @@ public boolean hasValue(float value) {
437507 }
438508
439509
510+ private void boundsProblem (int index , String method ) {
511+ final String msg = String .format ("The list size is %d. " +
512+ "You cannot %s() to element %d." , count , method , index );
513+ throw new ArrayIndexOutOfBoundsException (msg );
514+ }
515+
516+
440517 /**
441518 * @webref floatlist:method
442519 * @brief Add to a value
443520 */
444521 public void add (int index , float amount ) {
445- data [index ] += amount ;
522+ if (index < count ) {
523+ data [index ] += amount ;
524+ } else {
525+ boundsProblem (index , "add" );
526+ }
446527 }
447528
448529
@@ -451,7 +532,11 @@ public void add(int index, float amount) {
451532 * @brief Subtract from a value
452533 */
453534 public void sub (int index , float amount ) {
454- data [index ] -= amount ;
535+ if (index < count ) {
536+ data [index ] -= amount ;
537+ } else {
538+ boundsProblem (index , "sub" );
539+ }
455540 }
456541
457542
@@ -460,7 +545,11 @@ public void sub(int index, float amount) {
460545 * @brief Multiply a value
461546 */
462547 public void mult (int index , float amount ) {
463- data [index ] *= amount ;
548+ if (index < count ) {
549+ data [index ] *= amount ;
550+ } else {
551+ boundsProblem (index , "mult" );
552+ }
464553 }
465554
466555
@@ -469,7 +558,11 @@ public void mult(int index, float amount) {
469558 * @brief Divide a value
470559 */
471560 public void div (int index , float amount ) {
472- data [index ] /= amount ;
561+ if (index < count ) {
562+ data [index ] /= amount ;
563+ } else {
564+ boundsProblem (index , "div" );
565+ }
473566 }
474567
475568
@@ -585,7 +678,27 @@ public void sortReverse() {
585678 new Sort () {
586679 @ Override
587680 public int size () {
588- return count ;
681+ // if empty, don't even mess with the NaN check, it'll AIOOBE
682+ if (count == 0 ) {
683+ return 0 ;
684+ }
685+ // move NaN values to the end of the list and don't sort them
686+ int right = count - 1 ;
687+ while (data [right ] != data [right ]) {
688+ right --;
689+ if (right == -1 ) { // all values are NaN
690+ return 0 ;
691+ }
692+ }
693+ for (int i = right ; i >= 0 ; --i ) {
694+ float v = data [i ];
695+ if (v != v ) {
696+ data [i ] = data [right ];
697+ data [right ] = v ;
698+ --right ;
699+ }
700+ }
701+ return right + 1 ;
589702 }
590703
591704 @ Override
@@ -623,7 +736,7 @@ public void swap(int a, int b) {
623736
624737 /**
625738 * @webref floatlist:method
626- * @brief Reverse sort, orders values by first digit
739+ * @brief Reverse the order of the list elements
627740 */
628741 public void reverse () {
629742 int ii = count - 1 ;
@@ -691,6 +804,7 @@ public float[] values() {
691804
692805
693806 /** Implemented this way so that we can use a FloatList in a for loop. */
807+ @ Override
694808 public Iterator <Float > iterator () {
695809// }
696810//
@@ -701,6 +815,7 @@ public Iterator<Float> iterator() {
701815
702816 public void remove () {
703817 FloatList .this .remove (index );
818+ index --;
704819 }
705820
706821 public Float next () {
@@ -726,7 +841,8 @@ public float[] array() {
726841
727842
728843 /**
729- * Copy as many values as possible into the specified array.
844+ * Copy values into the specified array. If the specified array is null or
845+ * not the same size, a new array will be allocated.
730846 * @param array
731847 */
732848 public float [] array (float [] array ) {
@@ -784,17 +900,23 @@ public String join(String separator) {
784900 }
785901
786902
903+ public void print () {
904+ for (int i = 0 ; i < count ; i ++) {
905+ System .out .format ("[%d] %f%n" , i , data [i ]);
906+ }
907+ }
908+
909+
910+ /**
911+ * Return this dictionary as a String in JSON format.
912+ */
913+ public String toJSON () {
914+ return "[ " + join (", " ) + " ]" ;
915+ }
916+
917+
787918 @ Override
788919 public String toString () {
789- StringBuilder sb = new StringBuilder ();
790- sb .append (getClass ().getSimpleName () + " size=" + size () + " [ " );
791- for (int i = 0 ; i < size (); i ++) {
792- if (i != 0 ) {
793- sb .append (", " );
794- }
795- sb .append (i + ": " + data [i ]);
796- }
797- sb .append (" ]" );
798- return sb .toString ();
920+ return getClass ().getSimpleName () + " size=" + size () + " " + toJSON ();
799921 }
800922}
0 commit comments