`

当Set元素改变时的行为

 
阅读更多

先看这段程序:

import java.util.*;

class KeyMaster {
	public int i;

	public KeyMaster(int i) {
		this.i = i;
	}

	public boolean equals(Object o) {
		return i == ((KeyMaster) o).i;
	}

	public int hashCode() {
		return i;
	}
}

public class Test {
	public static void main(String[] args) {
		Set<KeyMaster> set = new HashSet<KeyMaster>();
		KeyMaster k1 = new KeyMaster(1);
		KeyMaster k2 = new KeyMaster(2);
		set.add(k1);
		set.add(k1);
		set.add(k2);
		set.add(k2);
		System.out.print(set.size() + ":");
		k2.i = 1;
		System.out.print(set.size() + ":");
		set.remove(k1);
		System.out.print(set.size() + ":");
		set.remove(k2);
		System.out.print(set.size());
	}
}

 

 

 

 

 

 

 

结果是什么呢?

2:2:1:1

也就是说添加的时候根据equals方法判断,只进去了两个不同i值的对象,但删除时为什么第二个删除不了呢?发现如果去掉override的hashCode方法时结果为2:2:1:0

文档中有这样一段:

Note: Great care must be exercised if mutable objects are used as set elements. The behavior of a set is not specified if the value of an object is changed in a manner that affects equals comparisons while the object is an element in the set. A special case of this prohibition is that it is not permissible for a set to contain itself as an element.

说有可变元素时行为未定,但remove方法文档中也没提到可能会被hashCode影响到?

 

2009.08.27回答:

remove之前可能是要先对比hashCode的,而k2的hashCode改变之后导致无法找到这个元素,导致remove失败

分享到:
评论

相关推荐

    vue $set 给数据赋值的实例

    而且,当状态属性值改变时,页面上显示的图片也会跟着变化,说明视图层已正确响应了数据模型的变化。 在实际开发中,经常会遇到需要在运行时动态添加属性到对象或数组的情况,如果不使用$set,Vue将无法追踪这些...

    awk set 使用手册

    `awk`的命令行选项可以改变其默认行为,如`-F`用于设置输入字段分隔符。`BEGIN`和`END`规则在处理输入之前和之后执行,分别用于初始化变量和进行最终处理。 七、awk与set实际应用 在实际工作中,`set`概念可以用于...

    java中循环遍历删除List和Set集合中元素的方法(推荐)

    当尝试在循环内部删除元素时,Java的迭代机制无法处理这种行为,因此抛出`ConcurrentModificationException`。 **正确的遍历删除方式** 为了避免上述异常,有以下两种正确的方法来遍历并删除List和Set集合中的元素...

    WPF 双向绑定到非公开 set 方法属性在 NET 45 和 NET Core 行为的不同.rar

    当UI元素的值改变时,数据模型会自动更新,反之亦然。这简化了UI和模型之间的交互。 2. **非公开 set 方法的属性**:在.NET中,属性通常通过get和set访问器来定义。如果set方法是非公开的,那么这个属性就不能从...

    java的传值与传值后的改变

    这里,`swap`函数可以改变`numbers`列表的第一个元素,因为`list`和`numbers`都引用了同一个列表。但是,如果`swap`函数试图将`list`赋值给另一个列表,`numbers`不会受到影响,因为这只是改变了函数内部的引用。 ...

    Set-Busy-Cursor.zip_labview set cursor

    在`鼠标的应用.vi`中,你可能会看到这样的逻辑:当开始一个长时间任务时,调用“设置光标”函数,将光标更改为忙碌状态(例如旋转的沙漏),并在任务完成后恢复到原始光标。这样,用户可以清楚地知道程序何时在执行...

    学习STL MAP, STL SET之数据结构基础

    在实际应用中,当数据元素数量从10000增加到20000时,`map`和`set`的插入和搜索速度通常仍能保持O(log n)的效率,因为红黑树的平衡特性保证了即使元素数量增长,树的高度也不会线性增长。然而,具体的性能表现还取决...

    gtk_属性改变事件

    当属性改变可能影响到控件的视觉呈现时,例如背景色或字体大小改变,通常需要重新绘制控件。通过调用`gtk_widget_queue_draw()`,GTK+会安排在下次事件循环中重新绘制该控件。 3. **gtk_widget_size_allocate()**...

    STL中map、set的数据结构及底层实现.docx

    当map和set的元素数量从10000增长到20000时,插入和搜索速度的变化取决于具体实现和操作的具体情况。由于红黑树的性质,插入和搜索的时间复杂度通常是O(log n),因此,即使元素数量增加,性能下降也不会像线性容器...

    通过获取网页的DOM操作网页元素的软件源码

    通过DOM,我们可以找到特定的元素,改变其属性,甚至添加或删除元素。例如,`getElementById`方法可以让我们定位到ID为特定值的元素,`getElementsByTagName`则可获取所有指定标签名的元素。 在VB中,我们可以使用...

    改变控件颜色的扩展控件

    3. **属性逻辑实现**:为这些属性提供Get和Set方法,处理颜色改变的逻辑,如设置或获取控件的颜色值。 4. **注册和提供扩展**:在控件的`BeginInit()`和`EndInit()`方法中,注册和注销可以接受扩展的控件。 5. **...

    使用Vue.set()方法实现响应式修改数组数据步骤

    由于Vue不能监听到直接修改数组元素的行为,如`this.state[num] = '新状态'`,因此必须使用`Vue.set()`来确保响应性。 此外,`Vue.set()`还可以用来向数组末尾添加新的元素。例如,如果要添加一个新的考勤状态,...

    vue中 this.$set的用法详解

    总之,`this.$set`是Vue中一个非常实用的方法,尤其在处理动态添加属性或修改深层嵌套对象属性时,能够确保视图与数据的同步,避免出现预期之外的行为。在开发过程中,尤其是在处理非预定义的属性或数组元素时,合理...

    Python打印输出数组中全部元素

    对于元素数量较多的数组,可以使用`set_printoptions`来改变打印行为。其中`threshold`参数特别有用,它定义了在打印数组时,超过多少元素就进行折叠。设置`threshold='nan'`表示无限制,即打印所有元素。例如: `...

    vue.js中$set与数组更新方法

    特别是,当你通过索引直接修改数组元素或者改变数组的长度时,Vue无法感知到这些变化,从而不会触发视图的更新。 1. **直接修改数组元素** 当你执行如下的操作: ```javascript vm.items[indexOfItem] = ...

    JAVA集合类[参考].pdf

    当我们向`Set`添加元素时,`equals()`方法被用来判断元素是否已经存在。如果两个对象的`equals()`方法返回`true`,那么它们被认为是相等的,`Set`不会接受重复的元素。此外,`hashCode()`方法也起着关键作用,因为它...

    ant 元素介绍XXOO

    例如,`&lt;fileset&gt;`元素可以用来选择一组Java源文件,而`&lt;mapper&gt;`元素可以用来改变这些文件的名称或路径,比如在创建类路径文件时。 在标签"源码"的提示下,我们可以推测这篇博文可能深入探讨了如何使用Ant处理和...

    4种input元素滑块UI样式.zip

    5. `oninput`事件:当滑块值改变时触发,可用于实时更新页面其他部分的状态。 此外,为了兼容不同浏览器,可能还需要使用polyfill或者条件语句来确保在不支持这些特性的浏览器中也能正常工作。例如,对于不支持CSS3...

    python 显示数组全部元素的方法

    `np.set_printoptions`是NumPy库中的一个函数,它允许用户设定打印数组时的参数,以改变打印输出的行为。具体来说,这里使用了`threshold`参数,并将其设置为了`'nan'`。 `threshold`参数控制着打印多维数组时,当...

    java集合框架

    然而,由于Set不允许重复元素,所以在尝试添加已存在的元素时,操作会立即返回,不会改变Set的大小。 Queue接口则表示一种先进先出(FIFO)的数据结构,常用于实现队列。队列接口提供了enqueue(入队)和dequeue...

Global site tag (gtag.js) - Google Analytics