Java HashSet的元素内容变化导致的问题
概述
HashSet元素引用的对象的内容发生变化,会导致“元素不属于集合”的问题。事实上这个元素还在集合里,但是调用contains方法进行判断,得到的结果却是false。
正文
关于变化
这里所讲的变化是指元素引用的对象的内容的变化,但是对象还是这个对象。比如我们定义如下的field
private Set<Set<Integer>> cache = new HashSet<Set<Integer>>();
我们计划cache里的每一个元素都是一个Set<Integer>的集合。如果我们取出cache的一个元素,然后往这个元素集合中添加一个Integer元素。对于cache来说,这个元素还是这个元素,但是它的内容已经变化了。
关于校验标准
/**
* 校验.<br>
* 从集合中取出的元素反而不属于该集合,则为无效.
* @return
*/
private boolean validate() {
boolean flag = true;
for ( Set<Integer> ele : cache ) {
if (!cache.contains(ele)) {
flag = false;
System.out.println("无效的元素:" + ele);
}
} return flag;
}
测试
我们分为三个测试用例:数据初始化测试、直接更新测试、移除新增测试。
一、数据初始化测试
1. 数据初始化
/**
* 初始化数据.
*/
private void init() {
Integer[][] data = {{1, 2}, {3, 4}, {5}};
for (Integer[] ele : data) {
List<Integer> eleList = Arrays.asList(ele);
Set<Integer> eleSet = new HashSet<Integer>(eleList.size());
eleSet.addAll(eleList); cache.add(eleSet);
} System.out.println(cache);
}
2. 测试
@Test
public void testInit() {
init();
boolean flag = validate();
System.out.println("对初始化的数据进行校验,结果:" + flag);
}
3. 输出结果
[[2, 1], [5], [4, 3]]
对初始化的数据进行校验,结果:true
二、直接更新测试
1. 更新的方法
/**
* 直接修改.
*/
private void update() {
for (Set<Integer> ele : cache) {
if (ele.contains(5)) {
ele.add(6);
break;
}
} System.out.println(cache);
}
2. 测试
@Test
public void testUpdate() {
init();
update(); boolean flag = validate();
System.out.println("对直接修改的数据进行校验,结果:" + flag);
}
3. 输出结果
[[2, 1], [5], [4, 3]]
[[2, 1], [6, 5], [4, 3]]
无效的元素:[6, 5]
对直接修改的数据进行校验,结果:false
三、移除新增测试
1. 移除新增
/**
* 移除添加.
*/
private void removeThenAdd() {
for (Set<Integer> ele : cache) {
if (ele.contains(5)) {
cache.remove(ele);
ele.add(6);
cache.add(ele);
break;
}
} System.out.println(cache);
}
2. 测试
@Test
public void testRA() {
init();
removeThenAdd(); boolean flag = validate();
System.out.println("对移除添加的数据进行校验,结果:" + flag);
}
3. 输出结果
[[2, 1], [5], [4, 3]]
[[2, 1], [4, 3], [6, 5]]
对移除添加的数据进行校验,结果:true
结论
我认为HashSet遍历元素和判断元素是否在集合中的机制是不同的,HashSet中的元素都有一个不同的hashcode,我们直接修改其中的元素,导致其内容和其hashcode对应不上,所以才会有上述的问题。
Java HashSet的元素内容变化导致的问题的更多相关文章
- jQuery 监听元素内容变化的方法
我们可以用onchange事件来完成元素值发生改变触发的监听.但是 onchange 比较适用于<input>.<textarea> 以及 <select> 元素. ...
- 监控父元素里面子元素内容变化 DOMSubtreeModified
1监控ul的li的变化情况,并实时输出li的长度 布局: <ul id="isSelected"></ul> <span id="modal ...
- js监听dom元素内容变化
$("#divid").bind('DOMNodeInserted', function(e) { alert('element now contains: ' + $(e.tar ...
- Java HashSet对txt文本内容去重(统计小说用过的字或字数)
Java HashSet对txt文本内容去重(统计小说用过的字或字数) 基本思路: 1.字节流读需要去重的txt文本.(展示demo为当前workspace下名为utf-8.txt的文本) 2.对读取 ...
- 《java入门第一季》之HashSet存储元素保证唯一性的代码及图解
上一篇介绍了HashSet存储自定义自定义对象时应该注意的问题http://blog.csdn.net/qq_32059827/article/details/51580642, 这一篇对其内部结构稍 ...
- 读书笔记:《HTML5开发手册》--现有元素的变化
读书笔记:<HTML5开发手册>-- 现存元素的变化 继续学习HTML5语义化的内容,今天主要介绍一下,HTML5之前的元素经HTML5规范后的语义及一些使用示例. 一.cite HTML ...
- input输入框内容变化实时监听
js实现的文本框内容发生改变立马触发事件简单介绍:本章节介绍一下如何在文本框的内容发生变化的时候,立马触发一个事件执行响应的操作,而不是像是keydown或者keyup事件一样,只能够检测通过键盘输入 ...
- 《手把手教你》系列技巧篇(十五)-java+ selenium自动化测试-元素定位大法之By xpath中卷(详细教程)
1.简介 按宏哥计划,本文继续介绍WebDriver关于元素定位大法,这篇介绍定位倒数二个方法:By xpath.xpath 的定位方法, 非常强大. 使用这种方法几乎可以定位到页面上的任意元素. ...
- 《手把手教你》系列技巧篇(十六)-java+ selenium自动化测试-元素定位大法之By xpath下卷(详细教程)
1.简介 按宏哥计划,本文继续介绍WebDriver关于元素定位大法,这篇介绍定位倒数二个方法:By xpath.xpath 的定位方法, 非常强大. 使用这种方法几乎可以定位到页面上的任意元素. ...
随机推荐
- UVA 1640 The Counting Problem
https://vjudge.net/problem/UVA-1640 题意:统计区间[l,r]中0——9的出现次数 数位DP 注意删除前导0 #include<cmath> #inclu ...
- sqlserver xml转表 及(cross apply与outer apply)
一. 需求是需要把','分割的字符串转为表,便于做关联查询,于是发现可以通过xml转为表,如下: declare @XXX xml set @XXX = ' <v> <aa>1 ...
- codeforces——contest 864 problemE
Polycarp is in really serious trouble — his house is on fire! It's time to save the most valuable it ...
- Windows Phone 8.1基础教程(1) 页面导航、弹出框
1. 跳转到其他页面 Frame.Navigate(typeof(页面),参数); 2. 后退回历史页面 Frame.GoBack(); 3. 回跳时判断 if(e.NavigationMode == ...
- MSSQL 错误:在将 varchar 值 '1,2,3,5,6' 转换成数据类型 int 时失败。
MSSQL 错误:在将 varchar 值 '1,2,3,5,6' 转换成数据类型 int 时失败.
- AndroidStudio 添加Selector文件,在res文件夹下添加文件夹
在res文件夹下添加文件夹: 添加Selector文件:
- js中字符串的操作
1.length 获取字符串长度 var str = "hello world"; alert(str); 2.索引 通过下标获取字符串指定位置的字符,但是不能改变该索引对应的值 ...
- DIV+CSS左右列高度自适应问题
其实解决DIV+CSS左右两列高度自适应的方法就是要注意两点:一是在最外层加上overflow:hidden,然后在左边列加上margin-bottom:-9999px;padding-bottom: ...
- js中的return
retrun true: 返回正确的处理结果. return false:分会错误的处理结果,终止处理. return:把控制权返回给页面(如果条件满足,后面的逻辑就不执行了). if(this.in ...
- printk %pF %pS含义【转】
作者:啐楼链接:https://www.zhihu.com/question/37769890/answer/73532192来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出 ...