【问题标题】:Fastest way to search a HashMap and mark places with the same name?搜索 HashMap 并用相同名称标记地点的最快方法?
【发布时间】:2017-07-18 14:08:29
【问题描述】:

我的程序有一个搜索功能,用户可以输入一个在地图上可见并标记的地点名称(如果该地点存在)。我正在尝试找到最快的方法来搜索 HashMap 以查找具有相同名称的地点,标记它们/使它们可见,最后将所有标记的地点添加到 ArrayList。目前,大约 2000 个位置很近的地方需要大约 30 秒才能出现在上面提到的地图上,而且我听说像这样的操作应该会更快。我猜我的 for 循环是减慢速度的原因。有没有比下面更快的方法来做到这一点?

private Map<String, List<Place>> perName = new HashMap<>();

List<Place> sameName = perName.get(name);
                for (Place p : sameName) {
                    p.setVisible(true);
                    p.setMarked(true);
                }
                markedPlace.addAll(sameName);

编辑:这里是 Place-class 的一部分,例如 setMarked()-方法(setVisible 只显示图形组件):

private boolean isMarked = false;
    private boolean isShown = false;
    private int[] xs = { 0, 20, 40 };
    private int[] ys = { 0, 40, 0 };

    protected Place(String name, Position position, String category) {
        setBounds(position.getX() - 20, position.getY() - 40, 40, 40);
        this.name = name;
        this.position = position;
        this.category = category;
    }

    protected int[] getXs() {
        return xs;
    }

    protected int[] getYs() {
        return ys;
    }    

protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (isShown) {
                show(g);
            }
            if (isMarked) {
                mark(g);
            }
        }

        protected void setShown(boolean b) {
            isShown = b;
            repaint();
        }

        protected boolean isMarked() {
            return isMarked;
        }

        protected void setMarked(boolean b) {
            isMarked = b;
            repaint();
        }

        protected void mark(Graphics g) {
            g.setColor(Color.MAGENTA);
            g.drawRect(0, 0, 39, 39);
        }

        protected void show(Graphics g) {
            if (category.equals("Bus")) {
                g.setColor(Color.RED);
            } else if (category.equals("Underground")) {
                g.setColor(Color.BLUE);
            } else if (category.equals("Train")) {
                g.setColor(Color.GREEN);
            } else if (category.equals("None")) {
                g.setColor(Color.BLACK);
            }
            g.fillPolygon(getXs(), getYs(), 3);
        }

【问题讨论】:

  • 您确定哈希图中的查找是大部分时间花费的地方吗?我认为在地图(谷歌地图?)上渲染这么多标记肯定需要一些时间。
  • 如果该列表仅包含 2000 个元素并且 setVisible()setMarked() 只是简单的设置器(即内部没有花哨的逻辑),则循环应该在几毫秒内运行(在最合理的硬件上,即使在不到 1 毫秒)。
  • 顺便说一句,处理Map&lt;String, List&lt;Place&gt;&gt; 可能会很痛苦......您可能会考虑查看具有多图之类的 Google Guava,因此您可以使用 ListMultimap&lt;String, Place&gt; 并摆脱手动处理列表。这不会更快,但可能更容易编码和阅读。
  • @TimBiegeleisen 是的,也许,我在 for 循环中添加了更多代码
  • 简单的测试:计算迭代地图需要多长时间,只需访问 2000 个奇怪的地方 不做任何图形工作。如果这需要很短的时间,那么您就会更好地了解罪魁祸首可能是什么。

标签: java performance for-loop search hashmap


【解决方案1】:

只是为了好玩,试试这个:

markedPlace.addAll(perName.get(name).stream().peek(Place::setVisible).peek(Place::setMarked).collect(Collectors.toList()));

欢迎评论。

编辑:我同意其他人的观点。在我看来,性能问题不是因为你的循环结构。更有可能是因为 repaint() 调用或您在 setVisible() 中调用的任何内容

【讨论】:

    猜你喜欢
    • 2012-05-23
    • 1970-01-01
    • 2016-03-08
    • 2018-02-13
    • 2023-03-28
    • 2016-08-25
    • 2018-12-12
    • 2012-08-28
    • 1970-01-01
    相关资源
    最近更新 更多