在浏览 Javadoc 时,Java 开发人员常常会遇到 SortedSet 类型(它在 JDK 中唯一的实现是 TreeSet)。 因为
SortedSet 是 java.util 包中唯一提供某种排序行为的 Collection,所以开发人员通常直接使用它而不会仔细地研究它。
清单 4 展示了:
清单 4. SortedSet,我很高兴找到了它!
import java.util.*;
public class UsingSortedSet {
public static void main(String[] args) {
List<Person> persons = Arrays.asList(
new Person("Ted", "Neward", 39),
new Person("Ron", "Reynolds", 39),
new Person("Charlotte", "Neward", 38),
new Person("Matthew", "McCullough", 18)
);
SortedSet ss = new TreeSet(new Comparator<Person>() {
public int compare(Person lhs, Person rhs) {
return lhs.getLastName().compareTo(rhs.getLastName());
}
});
ss.addAll(perons);
System.out.println(ss);
}
}
使用上述代码一段时间后,可能会发现这个 Set 的核心特性之一:它不允许重复。 该特性在 Set Javadoc 中进行了介绍。 Set 是不包含重复元素的集合。 更准确地说,set 不包含成对的 e1 和 e2 元素,因此如果 e1.equals(e2)
,那么最多包含一个 null
元素。
但实际上似乎并非如此 — 尽管 清单 4 中没有相等的 Person 对象(根据 Person 的 equals()
实现), 但在输出时只有三个对象出现在 TreeSet 中。
与 set 的有状态本质相反,TreeSet 要求对象直接实现 Comparable 或者在构造时传入 Comparator,它不使用 equals()
比较对象; 它使用 Comparator/Comparable 的 compare 或 compareTo 方法。
因此存储在 Set 中的对象有两种方式确定相等性:大家常用的 equals()
方法和 Comparable/Comparator 方法,采用哪种方法取决于上下文。
更糟的是,简单的声明两者相等还不够,因为以排序为目的的比较不同于以相等性为目的的比较: 可以想象一下按姓排序时两个 Person 相等,但是其内容却并不相同。
一定要明白 equals()
和 Comparable.compareTo()
两者之间的不同 — 实现 Set 时会返回 0。 甚至在文档中也要明确两者的区别。
分享到:
相关推荐
所谓与equals一致是指对于类 C 的每一个 e1 和 e2 来说,当且仅当 (e1.compareTo((Object)e2) == 0) 与e1.equals((Object)e2) 具有相同的布尔值时,类 C 的自然排序才叫做与 equals 一致 。 2.实现什么方法 int ...
要注意的是List,Set,Queue继承了Collection接口,...这里想用一个简单的例子展示一下他们的使用,内容包括:List、Map、Set、Queue,Collections、Comparable与Comparator,排序、搜索,内部类,泛型、重写equals、hashCode
### Comparable与Comparator的区别详解 #### 一、引言 在Java编程中,为了对自定义对象进行排序,Java提供了两种接口:`Comparable`与`Comparator`。这两种接口各有优势,适用于不同的场景。本文将深入探讨这两种...
此外,Comparable接口的实现通常会影响类的 equals() 和 hashCode() 方法,因为它们之间的关系是:如果两个对象相等(根据 equals()),那么它们的 compareTo() 方法应该返回 0。而Comparator接口则不会影响对象的 ...
`compare`方法用于比较两个对象,规则由你自定义,而`equals`方法则是判断两个Comparator是否相等,通常与`compare`方法的实现有关。 ```java public class MyComparator implements Comparator<MyObject> { @...
实现Comparable接口的类应该遵循一个重要的原则:如果`compareTo()`方法返回值与`equals()`方法定义的一致性原则相违背,那么这可能会导致排序行为不符合预期,即所谓的“怪异”行为。通常,当两个对象相等时,`...
在某些情况下,我们需要重写hashcode()方法,使其生成对象的哈希码,并且使其与equals()方法保持一致。 例如,在Hashtable、HashMap、HashSet、LinkedHashMap等容器中,我们需要重写hashcode()方法,使其生成对象的...
Comparable接口定义在`java.lang`包中,它只有一个方法`compareTo(T o)`,用于比较当前对象与另一个对象的大小。当一个类实现了Comparable接口,意味着类的实例可以被自然排序,无需额外的比较器。例如,String类就...
与之相比,Comparator 是一个比较器接口。我们可以通过实现 Comparator 接口来控制某个类的次序,而该类本身不支持排序。Comparator 接口包含两个函数,compare 和 equals,它的定义如下: ```java package java....
泛型化的Comparable接口允许你指定对象可以与哪种类型进行比较,通常是与它自身类型比较。 在某些情况下,你可能需要对不支持自然排序的类或者需要自定义排序规则的情况进行排序,这时Comparator接口就派上了用场。...
Java 中保持 compareTo 和 equals 同步 在 Java 中,compareTo 和 equals 是两个不同...在实现 Comparable 接口时,我们需要覆写 compareTo 方法,并将其与 equals 方法之间的比较依据保持一致,避免出现意外的结果。
四、Comparable与equals() Comparable接口用于定义对象之间的自然排序。实现了Comparable接口的类,其compareTo()方法用于比较两个对象的大小。虽然compareTo()与equals()看似相似,但它们的目的不同:equals()关注...
Java 比较接口comparable与comparator区别解析 Java 语言中提供了两个比较接口: Comparable 和 Comparator,这两个接口都是用于比较对象的大小顺序的,但它们有着不同的使用场景和实现方式。在本文中,我们将详细...
- 传递性:如果x.equals(y)和y.equals(z)都为true,则x.equals(z)也应为true。 - 一致性:多次调用x.equals(y)在对象不变的情况下应返回相同结果。 - 非null性:对于非null的引用,x.equals(null)应返回false。 ...
在上面的代码中,我们定义了一个MyDate类,该类实现了Comparable接口,并自定义了equals()方法。我们首先检查被比较的对象是否是同一个引用,然后检查被比较的对象是否为空和类型是否相同。最后,我们对每个关键字段...
除了`equals()`方法,有时候我们还需要让对象遵循一定的排序规则,这时可以实现`Comparable`接口。`compareTo()`方法用于比较当前对象与另一个对象的大小关系。 **6. equals()和hashCode()的一致性** 在重写`equals...
在Java编程中,`Comparable`接口用于比较对象的顺序,`equals`方法用于判断两个对象是否相等,而`toString`方法则是为了将对象转换为字符串形式,便于打印或输出。在给定的编程题中,`TwoTuple, T2>`是一个泛型类,...
`compareTo()`是`Comparable`接口的一部分,用于排序,它返回一个整数,表示当前对象与另一个对象的大小关系。虽然两者都涉及对象的比较,但目的和使用场景不同。 在实际开发中,理解这些比较原则对于编写可维护和...
默认情况下,`equals()`方法的行为与`==`相同,但大多数类(尤其是`String`、`ArrayList`等)重写了这个方法,以便比较对象的属性或内容。例如,`String`类的`equals()`方法比较两个字符串的字符序列: ```java ...