这是我的代码:
import java.util.*;
public class AnotherBackedCollectionsTest{
public static void main(String... args){
Shape square = new Shape("square");
Shape circle = new Shape("circle");
Shape triangle = new Shape("triangle");
NavigableSet<Shape> shapes = new TreeSet<Shape>();
shapes.add(square);
shapes.add(circle);
shapes.add(triangle);
System.out.println("New shape added? " +shapes.add(new Shape("square")));
for(Shape s : shapes){
System.out.println(s.getName());
}
Set<Shape> shapes2 = new HashSet<Shape>();
shapes2.add(square);
shapes2.add(triangle);
shapes2.add(circle);
System.out.println("New shape added? " +shapes2.add(new Shape("square")));
for(Shape s : shapes2){
System.out.println(s.getName());
}
}
}
class Shape implements Comparable<Shape>{
private String name;
public Shape(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public int compareTo(Shape shape){
return this.name.compareTo(shape.getName());
}
}
我得到这个输出:
New shape added? false
circle
square
triangle
New shape added? true
triangle
square
square
circle
如您所见,我没有重写
equals()
对象上的 Shape
方法。我发现奇怪的是,当我尝试在 Shape
中添加另一个名为“square”的 NavigableSet
对象时,它以某种方式拒绝了它。是因为 Shape implements Comparable<T>
所以它使用了重写的 compareTo()
方法来确定方法相等性?
基本上,我想问的是 NavigableSet 如何确定我正在尝试添加重复的对象,而事实上,我没有重写 equals() 方法。
TreeSet
不使用 equals()
来比较元素。它使用 Comparable
界面。
来自文档:
a
实例使用其TreeSet
(或compareTo
)方法执行所有元素比较,因此从集合的角度来看,此方法认为相等的两个元素是相等的。compare
正如文档还指出的那样,如果您希望您的集合遵守通用
Set
合同,则必须以与 equals()
一致的方式定义 compareTo()
:
集合的行为是明确定义的,即使它的顺序与 equals 不一致;它只是不遵守
接口的一般契约。Set
另一方面,
HashSet
确实使用了equals()
和hashCode()
,并且不关注compareTo()
。
这解释了行为上的差异。
简而言之,为了使您的元素尽可能广泛兼容,请确保覆盖
equals()
和 hashCode()
,并实现 Comparable
接口。