繁体   English   中英

TreeSet add()返回false

[英]TreeSet add() returning false

我正在用Java实现一个A *算法,我使用TreeSet作为保持打开列表排序的简单方法。 如果你不熟悉A *,它基本上是一个从A到B获得最短路径的函数,而开放列表是基于它们与B的接近程度排序的节点列表(在我的例子中是Tiles )。

我的对象实现了compareTo()函数的排序,如下所示:

@Override
public int compareTo( Tile b ) 
{
    return ( this.f< b.f) ? -1 : ( this.f> b.f) ? 1 : 0;
}

当我尝试将一些切片添加到打开列表时,我的问题出现了 - TreeSet似乎使用compareTo()来检查对象是否已经存在,而不是equals() 由于两个不同的Tiles可能具有相同的f值,因此TreeSet认为该对象已存在于列表中并且不会添加它。

根据文档(或至少,我如何阅读它),它应该使用equals

“如果指定的元素不存在,则将其添加到此集合。更正式地说,如果集合中不包含元素e2,则将指定的元素e添加到此集合中(e == null?e2 == null:e.equals( e2)) 。“ (强调我的)。

在调用add()contains()compareTo()进行排序时,如何让TreeSet使用equals() 对于info,我的Tile类不会覆盖equals()函数,所以它应该得到默认的return a == b

如果我不想用TreeSet做什么,那么我应该使用的正确集合是什么?

根据TreeSet文档,这是预期的行为:

请注意,如果要正确实现Set接口,则由set维护的排序(无论是否提供显式比较器)必须与equals一致。 (有关与equals一致的精确定义,请参阅Comparable或Comparator。)这是因为Set接口是根据equals操作定义的,但TreeSet实例使用compareTo(或compare)方法执行所有元素比较,因此从集合的角度来看,通过这种方法被认为相等的元素是相等的。 集合的行为即使其排序与equals不一致也是明确定义的; 它只是不遵守Set接口的一般合同。

调用addcontains时,无法让TreeSet使用equals 最好的办法是通过比较f属性以及其他属性equals什么来使compareTo方法与equals一致。

我希望以下示例可以帮助SO用户。 我有类似的情况,我处理的方式是除了价值之外还使用id。 就我而言,价值指的是一个频率。

请注意使用'paddedText' - 如果你进行字符串比较,这是重要的3> 11。

 public int compareTo(Object o) { String oText= o.getValue()+""; oText = String.format("%20s",oText).replace(' ', '0')+o.getName(); paddedText = this.value +""; paddedText=String.format("%20s",paddedText).replace(' ', '0') + this.name; return oText.compareTo(paddedText); } 

这里的答案已经让我创造了这个。 我会把它留在这里因为似乎只有解决方案的要点。

    @Override
    public int compare(TileState lhs, TileState rhs) {
        int compare = (lhs.getTaxicab + lhs.mMoves.size())
                - (rhs.getTaxicab + rhs.mMoves.size());
        if (compare == 0 && !lhs.equals(rhs)) return 1;
        return compare;
    }

只需在比较方法返回0时担心。

如果是这种情况并且equals将返回false,则返回0以外的任何值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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