Java 如何在树集中使用自定义类?

Java 如何在树集中使用自定义类?,java,treeset,Java,Treeset,如果我使用的是类似于以下内容的集合: Set<node> s=new TreeSet<node>(); class node { private int x; private int y; } Set s=new TreeSet(); 类节点{ 私人INTX; 私营企业; } 这是可以接受的吗?既然它是一个树集,它也会对它进行排序吗?如果不实现compariable,它将无法对它进行排序,并且在覆盖equals()和hashCode()之前,它实际上不适

如果我使用的是类似于以下内容的
集合

Set<node> s=new TreeSet<node>();

class node {

  private int x;
  private int y;

}
Set s=new TreeSet();
类节点{
私人INTX;
私营企业;
}

这是可以接受的吗?既然它是一个树集,它也会对它进行排序吗?

如果不实现
compariable
,它将无法对它进行排序,并且在覆盖
equals()
hashCode()
之前,它实际上不适合设置操作。(您不必覆盖
equals
hashCode
以使
TreeSet
工作,但这样做是有意义的。)

大概是这样的:

final class Node implements Comparable<Node> {

  private final int x;
  private final int y;

  Node(int x, int y) {
    this.x = x;
    this.y = y;
  }

  @Override public boolean equals(Object other) {
    if (!(other instanceof Node)) {
      return false;
    }
    Node otherNode = (Node) other;
    return x == otherNode.x && y == otherNode.y;
  }

  @Override public int hashCode() {
    return x * 31 + y * 17; // For example...
  }

  @Override public int compareTo(Node other) {
    // As of Java 7, this can be replaced with
    // return x != other.x ? Integer.compare(x, other.x) 
    //     : Integer.compare(y, other.y);

    if (x < other.x || (x == other.x && y < other.y)) {
      return -1;
    }
    return x == other.x && y == other.y ? 0 : 1;
  }
}
final类节点实现可比较{
私人最终int x;
私人终审法院;
节点(整数x,整数y){
这个.x=x;
这个。y=y;
}
@重写公共布尔等于(对象其他){
如果(!(节点的其他实例)){
返回false;
}
Node otherNode=(Node)other;
返回x==otherNode.x&&y==otherNode.y;
}
@重写公共int hashCode(){
返回x*31+y*17;//例如。。。
}
@覆盖公共整数比较到(节点其他){
//从Java7开始,可以用
//返回x!=其他.x?整数。比较(x,其他.x)
//:整数。比较(y,其他.y);
if(x

(注意,按照惯例,类名应该是
节点
,而不是
节点

节点需要实现一个可比较的,或者需要传递一个可以比较两个节点对象的自定义比较器。此外,任何基于哈希的集合都依赖于适当重写equals()和hashcode()方法的对象。

您必须指定equals、hashcode并实现可比较的接口。

就接受而言,代码没有问题。但对于排序
节点
类必须实现可比较的接口

这实际上并不正确。只要有可比性就足够了。您应该实现equals(),但是默认的Object.equals()和Object.hashcode()足以“工作”-没有“必须”的意思。仅供参考,TreeSet不是基于哈希的。@波希米亚人是的,您是对的,TreeSet或TreeMap特别不使用哈希。使其成为
最终类
的原因是什么?@medopal:当涉及继承时,平等和其他事情变得更难正确实现(甚至在有正确性概念的情况下)。同样,当我知道没有子类时,我知道它是不可变的。基本上,我订阅了“为继承而设计或禁止继承”。或者“根据使用情况”使用guava或apache commons来避免代码中的分支,并让库实现hashcode和equals方法。@Carlos:不,因此这句话是“你不必重写equals和hashCode来让TreeSet工作,但这样做是有意义的。”我发现,当可比较的实现也遵循自然相等时,对代码进行推理要容易得多。“请注意,null不是任何类的实例,e.compareTo(null)应该抛出NullPointerException,即使e.equals(null)返回false。“删除第一个if语句。