gpt4 book ai didi

java - 为什么在 Collections 中使用比较器而不是 equals()?

转载 作者:行者123 更新时间:2023-11-30 05:50:40 25 4
gpt4 key购买 nike

有一个 java bean Car 可能包含两个值:model 和 price。

现在假设我重写 equals() 和 hashcode() 以这种方式只检查模型:

public boolean equals(Object o) {            
return this.model.equals(o.model);
}


public int hashCode() {
return model.hashCode();
}

这允许我以这种方式检查数组列表是否已经包含相同型号的项目 Car(并且与价格无关):

List<Car> car = new ArrayList<Car>();


car.add(new Car("carA",100f));
car.add(new Car("carB",101f));
car.add(new Car("carC",110f));

System.out.println(a.contains(new Car("carB",111f)));

它返回真。没关系,因为汽车已经存在了!

但现在我认为 ArrayList 不好,因为我想维护有序的项目,所以我用这种方式用 TreeSet 代替它:

Set<Car> car = new TreeSet<Car>(new Comparator<Car>() {
@Override
public int compare(Car car1, Car car2) {

int compPrice = - Float.compare(car1.getPrice(), car2.getPrice());

if (compPrice > 0 || compPrice < 0)
return compPrice;
else
return car1.getModel().compareTo(car2.getModel());

}});

car.add(new Car("carA",100f));
car.add(new Car("carB",101f));
car.add(new Car("carC",110f));

System.out.println(a.contains(new Car("carB",111f)));

但是现在有问题,它返回FALSE...为什么?

似乎当我使用 arrayList 调用 contains() 时,调用了 equals() 方法。但似乎当我使用带有比较器的 TreeSet 调用 contains() 时,使用的是比较器。

为什么会这样?

最佳答案

TreeSet形成一个二叉树,根据自然(或非)顺序保存元素,因此为了快速搜索一个特定元素是集合,TreeSet使用 ComparableComparator而不是 equals() .

作为TreeSet JavaDoc 精确:

Note that the ordering maintained by a set (whether or not an explicit comparator is provided) must be consistent with equals if it is to correctly implement the Set interface. (See Comparable or Comparator for a precise definition of consistent with equals.) This is so because the Set interface is defined in terms of the equals operation, but a TreeSet instance performs all element comparisons using its compareTo (or compare) method, so two elements that are deemed equal by this method are, from the standpoint of the set, equal. The behavior of a set is well-defined even if its ordering is inconsistent with equals; it just fails to obey the general contract of the Set interface.

我们可以找到与 HashCode/Equals 合约的相似之处:

如果 equals()返回 true , hashcode() 必须也返回 true 以便在搜索过程中被发现。

TreeSet 同样:

如果 contains() (使用 ComparatorComparable )返回 true , equals() 必须返回true也是为了与equals()一致 .

因此: TreeSet.equals() 中使用的字段方法必须与您的 Comparator 中的方法完全相同(不多不少)实现。

关于java - 为什么在 Collections 中使用比较器而不是 equals()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13755094/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com