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?

https://github.com/lessthanoptimal/ddogleg/tree/v0.23.3/examples/src/org/ddogleg/example/ExampleDogArray.java

 1public 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}