HashMap
won't be of use for your needs, because it's not meant for range queries, i.e. give me the entry whose key is closest to 12.0
, or give me all entries between keys 10.0
and 20.0
.
There are special-purpose structures that deal with geo points efficiently, i.e. R-tree or R* tree.
These kind of trees require you to index your data based on a geo-point like structure, usually a latitude/longitude pair, though they also allow to index data based on geo-shapes.
Creating a lat/lon pair object to be used as the key (as suggested in other answers) is only useful if you use a specialized structure that stores and indexes spatial data. Otherwise, having such pair will be pointless, because you won't be able to search points that are near a given location, or points that lie within a given rectangle, etc.
Now, if you don't want to go the R-tree's way and you can live with quite limited spatial queries, you might want to consider using the following structure:
TreeMap<Double, TreeMap<Double, Double>> demo = new TreeMap<>();
This is a TreeMap
of TreeMap
s, and the idea is to have the latitude as the key of the outer map and the longitude as the key of the inner maps. So you will always have to search first by latitude, then by longitude.
If this is OK for you, you can take advantage of some very useful methods of TreeMap
, such as headMap
, tailMap
and subMap
, to name the most relevant ones.
For example, if you want to find all the points within the rectangle determined by its upper left corner [-10.0, -10.0]
and its lower right corner [10.0, 10.0]
, you could do it as follows:
// Get all points with latitude between -10.0 and 10.0
SortedMap<Double, TreeMap<Double, Double>> byLat = demo.subMap(-10.0, 10.0);
// Now print points from byLat submap with longitude between -10.0 and 10.0
byLat.entrySet().stream()
.map(e -> e.getValue().subMap(-10.0, 10.0))
.forEach(System.out::println);
Even for 1 million points, performance will be reasonable, though not the best one, because TreeMap
is a general purpose Map
implementation based on a Red/Black tree, which has O(log n)
time complexity.
On the other hand, if you are willing to install some software, I recommend you use Elasticsearch with Geolocation. It has geo-point and geo-shaped specialized datatypes that will make your life easier. This search engine has excellent performance and scales horizontally up to thousands of nodes, so memory, lookup times, etc won't be a problem.