第 12 章 设置
本作品已使用人工智能进行翻译。欢迎您提供反馈和意见:translation-feedback@oreilly.com
集合是一个不能包含重复项的项目集合;添加一个已经存在于集合中的项目不会产生任何影响。接口Set<E> 的方法与Collection 的方法相同,但它是单独定义的,以便让add 的合约(以及addAll ,它是根据add 定义的)反映这一点。equals 方法被重写:Set 合约规定,一个Set 只能等于另一个Set ,而且只有当它们大小相同、包含的元素相等时才能相等。hashCode 方法也被重载,当equals 被重载时,情况也应该如此(参见"实现"中的 "散列表")。Set 的散列代码是其元素的散列代码之和。
备注
本章的代码示例可在以下网址找到:
https://github.com/MauriceNaftalin/JGC_2e_Book_Code/blob/main/src/main/java/org/jgcbook/chapter12
让我们来看一个集合操作的实际例子。回到"使用集合方法 "中介绍的待办事项管理器示例,假设周一您有空闲时间执行电话任务。您可以将所有电话任务添加到现有的周一任务中,从而创建周一的新任务集合。让mondayTasks 和phoneTasks 与例 10-1 中声明的一样。
使用一组,可以写出
Set<Task> phoneAndMondayTasks = new HashSet<>(mondayTasks); phoneAndMondayTasks.addAll(phoneTasks); assert phoneAndMondayTasks.equals(Set.of(logicCode, mikePhone, paulPhone));
这是因为重复元素的处理方式。任务 mikePhone虽然在mondayTasks 和phoneTasks 中都出现过,但在phoneAndMondayTasks中只出现过一次--这对于本应用程序来说是合适的,因为您肯定不希望重复做两次任务!
定义集合等价关系
这看似简单明了,但要准确理解不同的Set 实现是如何工作的,我们需要更仔细地研究是什么定义了重复,也就是该集合的等价关系。前面的示例使用了HashSet ,其中的等价关系是equals 方法:换句话说,对于HashSet ,两个对象是重复的,当且仅当以其中一个对象为参数调用equals 方法时,返回true 。这似乎是一个显而易见的选择,但并不是唯一的选择(尽管 JDK 21 中Set 及其实现的 Javadoc 经常暗示这是唯一的选择)。其他一些实现也使用equals ,如CopyOnWriteArraySet 和我们称之为 UnmodifiableSet(参见"UnmodifiableSet")。使用这种关系的集合将包含对添加到其中的每个唯一对象的引用。EnumSet 就是这样一个例子(参见"EnumSet")--不过,由于枚举是单子,equals 方法的结果在所有比较中都与身份关系的结果一致。另一个例子是IdentityHashMap 的键集视图,或使用Collections 方法newSetFromMap 从IdentityHashMap 创建的任何集合(参见"IdentityHashMap")。
等价关系的第三种选择由以下合同规定NavigableSet.NavigableSet (请参阅"NavigableSet") ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access