从ClusterManager中删除项目时出现问题

11

在我的Android应用程序中,我需要删除并重新添加一个聚合项(cluster item)到我的GoogleMap中,这个聚合项代表了我的当前位置。但是当我运行以下代码时:

clusterMng.remove(myitem);

我遇到了这个异常:

java.lang.UnsupportedOperationException: NonHierarchicalDistanceBasedAlgorithm.remove    
not implemented.

有人能解释一下这是什么意思吗?我是否需要重写外部库中ClusterManager.java的一些方法?还是我只需更改我的算法即可?

5个回答

15

默认情况下,ClusterManager 使用不支持删除元素的NonHierarchicalDistanceBasedAlgorithm算法。

尝试改用GridBasedAlgorithm(它支持元素删除):

clusterMng.setAlgorithm(new GridBasedAlgorithm<MyClusterItem>());

或者,为了获得更好的性能,请将其包装在PreCachingAlgorithmDecorator中,就像ClusterManager默认情况下所做的那样:

clusterMng.setAlgorithm(new PreCachingAlgorithmDecorator<MyClusterItem>(new GridBasedAlgorithm<MyClusterItem>()));

1
这是一个不错的解决方案,但用 PreCachingAlgorithmDecorator 包装算法是不必要的,因为它在 setAlgorithm() 方法中自动完成了这个过程。 - Jeff Lockhart

8

以下是我的做法:

@Override
public void removeItem(T item) {
    final QuadItem<T> quadItem = new QuadItem<T>(item);
    synchronized (mQuadTree) {
        mItems.remove(quadItem);
        mQuadTree.remove(quadItem);
    }
}

根据NonHierarchicalDistanceBasedAlgorithm源代码的TODO建议,我还在QuadItem中实现了equals()hashCode()

@Override
public boolean equals(Object o) {
    if (this == o) {
        return true;
    }
    if (!(o instanceof QuadItem)) {
        return false;
    }

    QuadItem quadItem = (QuadItem) o;

    return mClusterItem.equals(quadItem.mClusterItem);

}

@Override
public int hashCode() {
    return mClusterItem.hashCode();
}

最后,我在我的ClusterItem的子类中实现了equals()hashCode()


确认,这个解决方案可行!性能方面看起来不错。可以处理超过1k个标记。 - Gibberish
@Viachaslau Tysianchuk,你是如何修改NonHierarchicalDistanceBasedAlgorithm.QuadItem以实现这些方法的?你是否需要将库用作模块? - desgraci
1
@desgraci 我将android-maps-utils的完整源代码复制到了我的项目中,因为我需要进行其他几个更改。对于这种情况,仅复制NonHierarchicalDistanceBasedAlgorithm可能就足够了。 - Viachaslau Tysianchuk
这对我不起作用。我下载了NonHierarchical类并更改了removeItem方法,并实现了equals和hashcode方法。然后,在我的“CustomItem extends ClusterItem”类中,我只是重写了equals和hashcode。有什么建议吗?谢谢! - xsorifc28
@xsorifc28 如果没有查看你的代码,可能无法提供太多建议。 也许可以检查一下你的 hashCode() 实现是否遵循http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode%28%29中的规则。 错误的 hashCode() 实现可能会在使用哈希映射和哈希集时导致错误。 - Viachaslau Tysianchuk
我遇到了以下问题:java.lang.NullPointerException: 尝试在空对象引用上调用接口方法'boolean java.util.List.remove(java.lang.Object)' custom_classes.CustomNonHierarchicalDistanceBasedAlgorithm.removeItem(CustomNonHierarchicalDistanceBasedAlgorithm.java:74)但是mItems不可能为空???编辑:啊,那是因为我在removeItem之前调用了clearItems。但现在我又遇到了ConcurrentModificationException... - Denny Weinberg

8
正如@SergePopulov所说,NonHierarchicalDistanceBasedAlgorithm不实现删除元素的功能。对于那些不想使用GridBasedAlgoritm但仍然需要从NonHierarchicalDistanceBasedAlgorithm中删除单个元素的人,有另一种解决方案。
通过此链接(源代码),您可以在github中找到由开发人员提供的NonHierarchicalDistanceBasedAlgorithm的源代码。
我所做的就是保存旧的集群项,清除clusterManager,然后再次添加旧的项,但不添加通过该方法传递的项。
首先创建一个单独的类,并粘贴NonHierarchicalDstanceBasedAlgorithm类代码。
public class CustomNonHierarchicalDistanceBasedAlgorithm<MarkerItem extends ClusterItem> implements Algorithm<MarkerItem>
{
    //copy code here
}

接下来找到removeItem方法并将其替换为以下代码:

@Override
public void removeItem(MarkerItem item)
{
    final Collection<QuadItem<MarkerItem>> items = new ArrayList<QuadItem<MarkerItem>>();
    final PointQuadTree<QuadItem<MarkerItem>> quadTree = new PointQuadTree<QuadItem<MarkerItem>>(0, 1, 0, 1);

    for (QuadItem<MarkerItem> temp : mItems)
    {
        if (item.getPosition() != temp.getPosition())
        {
            synchronized (quadTree)
            {
                items.add(temp);
                quadTree.add(temp);
            }
        }
    }

    clearItems();

    for (QuadItem<MarkerItem> temp : items)
    {
        synchronized (mQuadTree)
        {
            mItems.add(temp);
            mQuadTree.add(temp);
        }
    }
}

在此之后,请前往创建ClusterManager的位置,并粘贴下列代码,其中包含您的类名:

clusterManager.setAlgorithm(new CustomNonHierarchicalDistanceBasedAlgorithm<MarkerItem>());

您的MarkerItem是实现了ClusterItem接口的类。现在应该可以正常工作。

删除项目后不要忘记重新聚类您的ClusterManager,方法如下:

clusterManager.cluster();

我收到了“MarkerItems无法解析为类型”的错误消息。 - user2424370

1

android-maps-utils更新至0.5版本后,clusterManager.remove(item)将不会抛出UnsupportedOperationException("NonHierarchicalDistanceBasedAlgorithm.remove not implemented")异常。

参考此线程


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接