简体   繁体   中英

Creating a Real Map with HashMap in Java

I will like to create a real map where I can find gas stations in my area.

I have started by creating a HashMap:

key => Coordinates

value => Hotel

HashMap<Coordinates, Hotel> m = HashMap<Coordinates, Hotel>();

This is are the classes:

public class Coordinates {

    private double lng;
    private double lat;

    public Coordinates(double x, double y) {
        lat = x;
        lng = y;
    }

    public double getLng() {
        return lng;
    }

    public double getLat() {
        return lat;
    }

    public void setLat(double l) {
        lat = l;
    }

    public void setLng(double l) {
        lng = l;
    }

    public boolean equals(Coordinates other) {
        return ( (lng == other.getLng()) && (lat == other.getLat()) );
    }

    public int hashCode() {
        int lng2 = (int) (this.lng * 100000);
        int lat2 = (int) (this.lat * 100000);
        //Use a prime number for security
        return 31 * (lng2 + lat2);
    }

}

public class Hotels {

    public class Info {
        public String text;

        public Info(String t) {
            text = t;
        }
    }

    private Coordinates coords;
    private Info description;

    public Hotel(double lat, double lng, String text) {
        this.coords = new Coordinates(lat, lng);
        this.description = new Info(text);
    }

    public Coordinates getCoords() {
        return coords;
    }

    public Info getInfo() {
        return description;
    }

    public String getDescription() {
        return description.text;
    }
}

The challenge that I proposed myself (not homework) is to create a function that when called, it returns all the Hotels in the radius that you have declared:

public Iterable<Hotel> search(double lat, double lng, double radius) {
    //Code Here
}

Obviously if I want to use HashMap, I DO NOT want to iterate all the Hotels. I want to have the best complexity in the function.

EDIT: This is a map xD

http://i.stack.imgur.com/7vF5Q.jpg

A hashmap is the wrong data structure for this. Maps allow quick access of items by key; you want to gather a list of items based on a criteria, and you want that gathering to be efficient. I suggest you store a list of hotels in order by each coordinate; ie, one list has hotels in order by longitude, one by latitude. Then, when you want a set within a radius, you can start by getting all those within the square that encompasses the radius-defined circle.

The Map collections are specifically designed to allow you to get a value for a given key. They are not well designed to search the keys for values (which is what you want to do here).

If your aim here is to improve the efficiency of the search then you are really looking for a way to find a subset of hotels to filter for radius. I would suggest you approach it by implementing a separate class Region which is essentially all Coordinates within some range. You can then map from Region to a List of Hotels which would be searched by distance. Note that you'll also need to consider surrounding regions as your target may be at the edge of one of them.

Here's some sample code for your method to get you started. You will need to implement the Region class and a method in Coordinates called streamRegionsWithin which returns a Stream of all regions within some distance of the coordinates.

Map<Region, List<Hotel>> regionMap;

public List<Hotel> findAllHotelsWithinRadiusOfLocation(Coordinates coords, double distance) {
    return coords.streamRegionsWithin(distance)
        .flatMap(region -> regionMap.get(region).stream())
        .filter(hotel -> hotel.distanceTo(coords) <= distance)
        .collect(Collectors.toList());
}

The size of regions is a tradeoff: larger will mean a smaller map but more hotels to filter for distance.

Please ask questions if any of that doesn't make sense.

As others have noted, a hashmap isn't the right data structure for this.

Consider spatial data structures such as the kd tree or quadtrees . These are designed to handle radius queries of the sort you describe very efficiently. Essentially they partition the search space recursively and then use binary search to locate the query results.

References

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM