分类集和比较器

时间:2011-01-08 01:15:10

标签: java set treeset

我正在使用TreeSet来存储执行A *算法时使用的路径查找位置。

基本上,除非有“开放”元素(仍然要详尽地访问),否则每个开放元素的邻居都会被考虑并添加到SortedSet中,以便按成本和启发式成本对它们进行排序。这意味着我有一个类:

public class PathTileInfo implements Comparable<PathTileInfo>
{
  int cost;
  int hCost;
  final int x, y;

  @Override
  public int compareTo(PathTileInfo t2) {
    int c = cost + hCost;
    int c2 = t2.cost + t2.hCost;
    int costComp = c < c2 ? -1 : (c > c2 ? 1: 0);

    return costComp != 0 ? costComp : (x < t2.x || y < t2.y ? -1 : (x > t2.x || y > t2.y ? 1 : 0));
  }

  @Override
  public boolean equals(Object o2) {
    if (o2 instanceof PathTileInfo) {
      PathTileInfo i = (PathTileInfo)o2;
      return i.cost + i.hCost == cost + hCost && x == i.x && y == i.y;
    }

    return false;
  }
}

通过这种方式,首先考虑总成本,因为需要总排序(与equals的一致性),需要考虑根据x,y坐标的排序。

如果我在算法执行过程中迭代TreeSet,那么这应该可以工作,但它根本不会,

for (PathTileInfo t : openSet)
  System.out.print("("+t.x+","+t.y+","+(t.cost+t.hCost)+") ");

我得到的结果是没有保留正确的顺序,例如:

  

(7,7,6)(7,6,7)(6,8,6)(6,6,7)(5,8,7)(5,7,7)(6,7, 6)(6,6,7)(6,5,7)(5,7,7)(5,5,8)(4,7,7)(4,6,8)(4,5,8) )

我有什么微妙的遗失吗? 谢谢!

2 个答案:

答案 0 :(得分:1)

请确保在向TreeSet添加后,不要更改元素'可比较'值。如果您在添加到TreeSet后更改了值,则TreeSet无法维护新订单。

我认为您的PathTileInfo是正确的,但在这种情况下不需要equals()覆盖。

答案 1 :(得分:0)

TreeSet默认使用自然顺序对您添加的元素进行排序,这就是您的情况。你在创建它时是否告诉TreeSet使用自定义比较器?