I have a need for a data structure that will be able to give preceding and following neighbors for a given int that is part of the structure.
Some criteria I've set for myself:
- write once, read many times
- contain 100 to 1000 int
- be efficient: order of magnitude O(1)
- be memory efficient (size of the ints + some housekeeping bits ideally)
- implemented in pure Java (no libraries for this, as I want to learn)
- items are unique
- no concurrency requirements
- ints are ordered externally, that order will most likely not be a natural ordering, and that order must be preserved (ie. there is no contract whatsoever regarding the difference in value between two neighboring ints - any int may be greater or smaller than the int it preceeds in the order).
This is in Java, and is mostly theoretical, as I've started using the solution described below.
Things I've considered:
- LinkedHashSet: very quick to find an item, order of O(1), and very quick to retrieve next neighbor. No apparent way to get previous neighbor without reverse sorting the set. Boxed Integer objects only.
- int[]: very easy on memory because no boxing required, very quick to get previous and next neighbor, retrieval of an item is O(n) though because index is not known and array traversal is required, and that is not acceptable.
What I'm using now is a combination of int[] and HashMap:
- HashMap for retrieving index of a specific int in the int[]
- int[] for retrieving the neighbors of that int
What I like:
- neighbor lookup is ideally O(2)
- int[] does not do boxing
- performance is theoretically very good
What I dislike:
- HashMap does boxing twice (key and value)
- the ints are stored twice (in both the map and the array)
- theoretical memory use could be improved quite a bit
I'd be curious to hear of better solutions.