【问题标题】:Creating a Real Map with HashMap in Java在 Java 中使用 HashMap 创建真实地图
【发布时间】:2015-03-05 21:04:42
【问题描述】:

我想创建一个真实的地图,我可以在其中找到我所在地区的加油站。

我已经开始创建一个 HashMap:

key => 坐标

价值 => 酒店

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,我不想迭代所有酒店。 我想在函数中拥有最好的复杂度。

编辑: 这是一张地图xD

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

【问题讨论】:

  • 什么是“真实”地图? HashMap 是真的,不是幻觉。
  • 我的意思是像路线图这样的地图
  • 使用HashMap,您将遇到问题。如果不查看每个坐标,就无法消除坐标。 TreeMap&lt;Double, TreeMap&lt;Double, Hotel&gt;&gt;,虽然...?
  • 请用该数据结构提出答案:)
  • 有实际的 GIS(地理信息系统)数据结构可以解决这个问题。 HashMap,尽管有这个名字,但不是解决这个问题的正确结构。

标签: java dictionary data-structures hashmap


【解决方案1】:

hashmap 是错误的数据结构。地图允许通过按键快速访问项目;您希望根据标准收集项目列表,并且希望该收集有效。我建议您按每个坐标按顺序存储酒店列表;即,一个列表按经度排列酒店,一个按纬度排列。然后,当您想要一个半径范围内的集合时,您可以首先获取包含半径定义的圆的正方形内的所有集合。

【讨论】:

  • 复杂度是 O(n) 我需要一个更小的
  • 天哪,不——如果它们是有序的,您可以使用几种算法中的任何一种进行搜索,而无需查看每个算法。例如,二分搜索。
  • 找到每个标准的子组后,您必须找到两者的交集。这通常意味着查看一个中的所有项目并查看它们是否在另一个中。不过,只要搜索半径相对较小,这仍然比搜索整个数据集要少得多。
  • 或者取第一个子集并按照第二个标准对其进行排序,只为您提供由半径定义的正方形中的项目,并且避免必须匹配两组中的项目。
  • 排序会带你到 O(n log n)。不过,现在我想到了,使用二进制搜索来交叉检查集合成员资格也是如此。通过仅搜索一个坐标然后过滤该组,您似乎没有任何收获。
【解决方案2】:

Map 集合专门设计用于获取给定键的值。它们没有很好地设计用于搜索键的值(这是您想要在此处执行的操作)。

如果您的目标是提高搜索效率,那么您实际上是在寻找一种方法来查找酒店子集以过滤半径。我建议您通过实现一个单独的类 Region 来处理它,该类基本上是某个范围内的所有坐标。然后,您可以从区域映射到将按距离搜索的酒店列表。请注意,您还需要考虑周边区域,因为您的目标可能位于其中一个区域的边缘。

以下是一些示例代码,可帮助您入门。您将需要在坐标中实现 Region 类和一个名为 streamRegionsWithin 的方法,该方法返回坐标一定距离内所有区域的 Stream。

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

区域的大小是一种权衡:越大意味着地图越小,但需要过滤距离的酒店越多。

如果其中任何一个没有意义,请提出问题。

【讨论】:

  • 不错。但是我该怎么办streamRegionsWithIn?我也想过做这个功能,但我想不出一个好的答案:S我觉得它需要与多边形和区域相关的东西......
【解决方案3】:

正如其他人所指出的,hashmap 不是正确的数据结构。

考虑空间数据结构,例如k-d treequadtrees。这些旨在非常有效地处理您描述的那种半径查询。本质上,它们递归地划分搜索空间,然后使用二分搜索来定位查询结果。

参考文献

【讨论】:

    猜你喜欢
    • 2017-12-15
    • 1970-01-01
    • 2013-01-22
    • 1970-01-01
    • 2011-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多