DogArray

DogArrays are re-sizable arrays with implementations available for primitive types and generic objects. Internally it uses an array that can be directly accessed. The name DogArray comes from the library name and was selected since just about every permutation on growable array conflicted with an existing library. Plus who doesn’t like dogs?

ExampleDogArray.java

 1 public static void main( String[] args ) {
 2     // This will create an array of Point2D. New instances are created using the default constructor
 3     // and when recycled they will be assigned values of zero.
 4     // The second argument (reset lambda) is optional. If not provided then the state is not changed
 5     // when recycled
 6     var arrayObject = new DogArray<>(Point2D::new, ( p ) -> p.setTo(0, 0));
 7 
 8     // Resize the array so that it has 5 elements
 9     arrayObject.resize(2);
10     // Let's resize it to make it larger, but provide a lambda to initialize these values instead of the default
11     // (idx = the index, p = an element in the array)
12     arrayObject.resize(6, ( idx, p ) -> p.setTo(idx, 1));
13     // Print so we can see what it looks like. Instead of the traditional for loop, let's use the functional API
14     arrayObject.forEach(p -> System.out.println(p.x + " " + p.y));
15 
16     // When the order doesn't matter, you can "remove" elements with remove swap. This has a O(1) complexity
17     // but will swap the first for the last objects
18     arrayObject.removeSwap(1);
19     System.out.println("After removeSwap");
20     arrayObject.forIdx(( idx, p ) -> System.out.println("p[" + idx + "] = " + p.x + " " + p.y));
21 
22     // While remove will shift every element, maintaining their order but in O(N) time
23     arrayObject.remove(0);
24     System.out.println("After remove");
25     arrayObject.forIdx(( idx, p ) -> System.out.println("p[" + idx + "] = " + p.x + " " + p.y));
26 
27     // It's also possible to treat it like a list. Note that toList() does not declare any memory and recycles
28     // the returned object. This is very important in threaded applications.
29     for (Point2D p : arrayObject.toList()) {
30         p.y += 10;
31     }
32 
33     // Make it easy to see which output belongs to the code below
34     System.out.println("------------ Primitive Array\n");
35 
36     // There are primitive versions that should (in theory) support the same API when it makes sense
37     var arrayPrimitive = new DogArray_F32();
38 
39     // This will fill the first 5 elements with (0.5, 1.5, 2.5, ... )
40     arrayPrimitive.resize(5, ( idx ) -> idx + 0.5f);
41     // This will fill the new elements (5 to 7) with -1
42     arrayPrimitive.resize(8, -1);
43     // If you shrink the array size then no values are changed
44     arrayPrimitive.resize(7);
45 
46     // Let's print it out
47     System.out.print("[ ");
48     arrayPrimitive.forEach(v -> System.out.print(v + ", "));
49     System.out.println(" ]");
50 
51     // If you want to access elements in the reverse order, then getTail() can do that
52     System.out.println("tail[0]=" + arrayPrimitive.getTail(0) + " tail[2]=" + arrayPrimitive.getTail(2));
53 
54     // There are also a few different variants of indexOf() for when you need to search and get the index
55     System.out.println("2.5 is at " + arrayPrimitive.indexOf(2.5f));
56 
57     // Not previously discussed, but reserve will ensure that there is enough memory preallocate to support
58     // an array of the specified size before it needs to declare a new array internally
59     arrayPrimitive.reserve(20);
60     System.out.println("Reserve: array.size=" + arrayPrimitive.size + " data.length=" + arrayPrimitive.data.length);
61 
62     // If you are dealing with errors then its easy to get percentile errors by sorting then using get fraction
63     arrayPrimitive.sort();
64     System.out.println("35% = " + arrayPrimitive.getFraction(0.35));
65 }