博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java HashSet的元素内容变化导致的问题
阅读量:4519 次
发布时间:2019-06-08

本文共 2380 字,大约阅读时间需要 7 分钟。

概述

HashSet元素引用的对象的内容发生变化,会导致“元素不属于集合”的问题。事实上这个元素还在集合里,但是调用contains方法进行判断,得到的结果却是false。

正文

关于变化

这里所讲的变化是指元素引用的对象的内容的变化,但是对象还是这个对象。比如我们定义如下的field

private Set
> cache = new HashSet
>();

我们计划cache里的每一个元素都是一个Set<Integer>的集合。如果我们取出cache的一个元素,然后往这个元素集合中添加一个Integer元素。对于cache来说,这个元素还是这个元素,但是它的内容已经变化了。

关于校验标准

/** * 校验.
* 从集合中取出的元素反而不属于该集合,则为无效. * @return */private boolean validate() { boolean flag = true; for ( Set
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
eleList = Arrays.asList(ele); Set
eleSet = new HashSet
(eleList.size()); eleSet.addAll(eleList); cache.add(eleSet); } System.out.println(cache);}

2. 测试

@Testpublic void testInit() {    init();    boolean flag = validate();    System.out.println("对初始化的数据进行校验,结果:" + flag);}

3. 输出结果

[[2, 1], [5], [4, 3]]对初始化的数据进行校验,结果:true

二、直接更新测试

1. 更新的方法

/** * 直接修改. */private void update() {    for (Set
ele : cache) { if (ele.contains(5)) { ele.add(6); break; } } System.out.println(cache);}

2. 测试

@Testpublic 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
ele : cache) { if (ele.contains(5)) { cache.remove(ele); ele.add(6); cache.add(ele); break; } } System.out.println(cache);}

2. 测试

@Testpublic 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对应不上,所以才会有上述的问题。

转载于:https://www.cnblogs.com/ywjy/p/5073082.html

你可能感兴趣的文章
vim配置成c++IDE
查看>>
利用node搭建本地服务器
查看>>
python pickle命令执行与marshal 任意代码执行
查看>>
Elasticsearch 2.3 java api
查看>>
golang写入csv
查看>>
基础2
查看>>
java基础篇---网络编程(UDP程序设计)
查看>>
Kafka Producer相关代码分析【转】
查看>>
LeetCode 121. Best Time to Buy and Sell Stock
查看>>
麻省理工学院公开课-第四讲:快速排序 及 随机化 算法
查看>>
pycharm 的包路径设置export PYTHONPATH=$PYTHONPATH
查看>>
SQL语句创建函数
查看>>
解决mysql无法显示中文/MySQL中文乱码问号等问题
查看>>
CentOS 7.2 配置mysql5.7
查看>>
python输出转义字符
查看>>
java基础43 IO流技术(输入字节流/缓冲输入字节流)
查看>>
计算一个整数二进制中1的个数
查看>>
netdom join 错误:指定的域不存在,或无法联系。
查看>>
Android中Dialog的使用
查看>>
Android Activity接收Service发送的广播
查看>>