-
Notifications
You must be signed in to change notification settings - Fork 4
Array Tutorial
Javimmutable provides a sparse array implementation. A sparse array is an immutable collection similar to a map except that:
- it implements
IArray
instead ofIMap
- its keys are ints (not Integers) so no boxing/unboxing is needed for them
- its iterators iterate in sorted order by key using natural integer ordering (negative indexes before positive indexes)
Any valid 32-bit integer can be used as an index to a sparse array. Like a map the array efficiently manages memory so an array with widely dispersed keys will use approximately the same amount of memory as one with contiguous keys.
You should create sparse array instances using the static factory methods in the IArrays
class. Using these methods instead of instantiating objects directly is preferred since it isolates the client from future changes in the underlying implementation.
IArray
s are immutable. The assign()
and delete()
methods leave the original array intact and return a new modified array containing the requested change. The old and new arrays share almost all of their structure in common so very little copying is performed.
IArray<String> array = IArrays.of();
array = array.assign(25000, "charlie");
array = array.assign(0, "baker");
array = array.assign(-50000, "able");
assertEquals("baker", array.get(0));
The example creates an empty array and then assigns three values. Notice that the indexes are not contiguous and that negative indexes are perfectly acceptable. Arrays iterate over their values in order of their keys so for the sample array values()
would return the values in the order "able" then "baker" then "charlie". The keys()
method would return -50000 then 0 then 25000. Iterator
s and Stream
s skip "missing" indexes. The standard iterator()
method returns IMapEntry
objects that contain both the index and the value for each entry in the array.
Since arrays are not contiguous there is no concept of "insertion", only assignment. If you need a collection that manages indexes for you use a IList
. However if your algorithm provides a natural way to manage its own indexes an IArray
might be a better option.
IArray
offers methods to create java.util.Stream
objects.
- The array itself has a
stream()
method to stream overIMapEntry
objects. - The
keys()
method returns a view that can create a stream over the array indices. - The
values()
method returns a view that can create a stream over the array values.
IArray<String> array = IArrays.<String>of()
.assign(25000, "charlie")
.assign(-50000, "able")
.assign(0, "baker");
assertEquals(-25000, array.keys().stream().mapToInt(i -> i).sum());
assertEquals("ab,ba,ch", array.values().stream().map(x -> x.substring(0, 2)).collect(Collectors.joining(",")));