2015-01-07 2 views
0

Мне нравится создавать настоящую карту, где я могу найти автозаправочные станции в своем районе.Создание реальной карты с помощью HashMap в Java

Я начал с создания HashMap:

ключ => Координаты

значение => Hotel

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

Это являются классы:

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; 
    } 
} 

Задача что я предложил себе (не домашнее задание) создать функцию, которая при вызове нс все отели в радиусе, что вы заявили:

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

Очевидно, что если я хочу использовать HashMap, я НЕ хочу, чтобы перебирать все отели. Я хочу иметь лучшую сложность в функции.

EDIT: Это карта XD

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

+2

Что вы имеете в виду "реальной" карты? «HashMap» - реальный, это не иллюзия. – Maroun

+0

Я имею в виду карту, такую ​​как дорожная карта – Alex

+1

С помощью 'HashMap' у вас будут проблемы. Вы не можете устранить координаты, не глядя на них. «TreeMap >', хотя ...? – cHao

ответ

1

HashMap лучше неправильная структура данных для этого. Карты обеспечивают быстрый доступ к элементам по ключу; вы хотите собрать список предметов на основе критериев, и вы хотите, чтобы сбор был эффективным. Я предлагаю вам хранить список гостиниц по каждой координате; т.е. один список имеет гостиницы по порядку по долготе, по широте. Затем, когда вы хотите установить радиус в радиусе, вы можете начать с получения всех тех, что находятся внутри квадрата, который охватывает круг, определенный по радиусу.

+0

Сложность в том, что O (n) Мне нужен меньший – Alex

+0

Боже мой, нет - если они в порядке, вы можете использовать любой из нескольких алгоритмов для поиска, не глядя на каждого. Бинарный поиск для экземпляр – arcy

+0

Как только вы найдете подгруппу для каждого критерия, вам нужно будет найти пересечение двух. Это обычно означает просмотр всех элементов в одном и просмотр, если они находятся в другом. Это все равно должно быть значительно меньше работы, чем поиск всего набора данных, хотя до тех пор, пока радиус поиска очень маленький. – cHao

0

Коллекции карт специально разработаны, чтобы вы могли получить значение для заданного ключа. Они не хорошо разработаны для поиска ключей для значений (вот что вы хотите сделать здесь).

Если ваша цель заключается в повышении эффективности поиска, то вы действительно ищете способ найти подмножество отелей для фильтрации радиуса. Я предлагаю вам подходить к нему, внедряя отдельный класс Region, который по существу является всеми координатами в некотором диапазоне. Затем вы можете перейти от региона к списку отелей, который будет искать по расстоянию. Обратите внимание, что вам также нужно будет учитывать окружающие регионы, так как ваша цель может находиться на краю одного из них.

Вот пример кода для вашего метода, чтобы вы начали. Вам нужно будет реализовать класс Region и метод в координатах, называемых streamRegionsWithin, который возвращает поток всех регионов на некотором расстоянии от координат.

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()); 
} 

Размер областей является компромиссом: больше будет означать меньшую карту, но больше отелей фильтр для расстояния.

Пожалуйста, задавайте вопросы, если это не имеет смысла.

+0

Ницца. Но как мне сделать 'streamRegionsWithIn'? Я также думал о выполнении этой функции, но я не могу найти хороший ответ: S Я чувствую, что это должно быть что-то связанное с полигонами и областями ... – Alex

+0

Я добавлю пример кода для регионов. – sprinter

0

Как уже отмечалось, хешмап не является подходящей структурой данных для этого.

Рассмотрите пространственные структуры данных, такие как k-d tree или quadtrees. Они предназначены для обработки запросов по радиусу, которые вы описываете очень эффективно. По существу они рекурсивно разбивают пространство поиска, а затем используют двоичный поиск для поиска результатов запроса.

Ссылки

Смежные вопросы