Java之Set集合的怪
工作中可能用Set比较少,但是如果用的时候,出的一些问题很让人摸不着头脑,然后我就看了一下Set的底层实现,大吃一惊。 ###看一个问题
Map map = new HashMap();map.put(1,"a");map.put(12,"ab");map.put(123,"abc");Set set1 = map.keySet();Set set2 = map.keySet();Set set3 = map.keySet();set1.remove(1);set1.forEach(p-> System.out.println(p.toString()));set2.forEach(p-> System.out.println(p.toString()));set3.forEach(p-> System.out.println(p.toString()));
复制代码
然后我的运行结果是
123
12
----------------
123
12
----------------
123
12
复制代码
为什么我在set1里面执行remove(1);其它的两个set对象为什么也删掉了第一个元素呢? 为什么会受到我前面操作的影响呢。 ###分析底层实现
1.最简单的实践
我们大概能猜出问题的所在,就是set1其实调用的还是map对象。那怎样才具有说服力呢。 学过反射的应该都清楚,我们可以看下set1它到底是什么类型的对象。
Class classes = set1.getClass();System.out.println(classes.getTypeName());
复制代码
控制台打印:
java.util.HashMap$KeySet
复制代码
是不是眼前一亮,wtf竟然是个Map类型。我不是明明给它实例化了个Set对象吗。好了,这个现象成功吸引了我的兴趣。于是
找底层实现
我们找到这个KeySet方法
public Set<K> keySet() {Set<K> ks = keySet;if (ks == null) {ks = new AbstractSet<K>() {public Iterator<K> iterator() {return new Iterator<K>() {private Iterator<Entry<K,V>> i = entrySet().iterator();public boolean hasNext() {return i.hasNext();}public K next() {return i.next().getKey();}public void remove() {i.remove();}};}public int size() {return AbstractMap.this.size();}public boolean isEmpty() {return AbstractMap.this.isEmpty();}public void clear() {AbstractMap.this.clear();}public boolean contains(Object k) {return AbstractMap.this.containsKey(k);}};keySet = ks;}return ks;}
复制代码
我们可以看到,有一个成员内部类AbstractSet(),里面有两部分,一部分是new 一个迭代器(内部类),一部分是调用AbstractMap对象(外部类)。外部类对象调用的内部类的构造函数,反编译的话,会看出传入了外部类对象的引用进去。所以它最终的类型应该是AbstractMap,(Map的派生类)。
所以,眼看是实例化了一个Set对象,其实底层还是调用的map对象。
Java之Set集合的怪相关推荐
- java去重复的集合_如何去除Java中List集合中的重复数据
1.循环list中的所有元素然后删除重复 public class duplicatRemoval { public static List removeDuplicate(List list){ f ...
- Java中Set集合是如何实现添加元素保证不重复的?
点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | 公众号「武培轩」 Java中Set集合是如何实 ...
- Thinking in java基础之集合框架
Thinking in java基础之集合框架 大家都知道我的习惯,先上图说话. 集合简介(容器) 把具有相同性质的一类东西,汇聚成一个整体,就可以称为集合,例如这里有20个苹果,我们把每一个苹果当成 ...
- Java的数组集合概括
Java的数组集合概括 Collection 1.List(存储有序,有索引,可以重复) 1.1.ArrayList 底层是数组实现的,线程不安全,查找和修改快,增删比较慢 1.2.LinkedLis ...
- Java对象容器——集合Set
集合就是数学中的集合的概念:所有的元素都具有唯一的值,元素在其中没有顺序. 数学中的集合具有唯一性(没有重复元素),Java中的集合也是. 比如放三个值1,1,1输出这个集合的话只会输出一个1. Ha ...
- Set精讲(Java)·算法常用集合处理方法
Set精讲(Java)·算法常用集合处理方法 Set概述 Set集合类似于一个罐子,程序可以依次把多个对象"丢进"Set集合,而Set集合通常不能记住元素的添加顺序.实际上Set就 ...
- 万字长文深入理解java中的集合-附PDF下载
文章目录 1. 前言 2. List 2.1 fail-safe fail-fast知多少 2.1.1 Fail-fast Iterator 2.1.2 Fail-fast 的原理 2.1.3 Fai ...
- java 什么是线程同步,java多线程同步集合是什么?并发集合是什么?
java中关于集合的内容也是十分丰富的,而且相关的知识点也是十分多的.多线程集合所涵盖的范围是十分广阔的.今天就来为大家介绍一下,java多线程同步集合是什么以及并发集合是什么?一起来看看吧. 首先我 ...
- (转)java中对集合对象list的几种循环访问总结
Java集合的Stack.Queue.Map的遍历 在集合操作中,常常离不开对集合的遍历,对集合遍历一般来说一个foreach就搞定了,但是,对于Stack.Queue.Map类型的遍历,还是有一些讲 ...
最新文章
- TensorFlow人工智能引擎入门教程之二 CNN卷积神经网络的基本定义理解。
- 微软Skype突破!视讯人数上限来到50人
- python学习(1)
- oracle 重建em失败,11gr2 EM重建出现问题,求高人指点
- 我国计算机体系结构相关产业,中国工程院院士吴汉明:发展我国半导体产业,力求颠覆传统计算机体系结构...
- wxpython 可视化开发pdf_MicroPython for the Internet of Things.pdf
- 基于消息中间件RabbitMQ实现简单的RPC服务
- leetcode 721. 账户合并(并查集)
- PowerBI,自定义编辑同一页面中不同图表之间的交互,使页面交互更灵活
- JxBrowser概述与简单应用
- LeetCode 91. 解码方法
- MangoTrainingCourse课程hands-on lab-1
- 服务器系统2022安装wsl2,手把手教你踩坑:老白的Docker for Windows安装初探WSL 2 backend...
- QPushButton/QLabel在鼠标悬浮(划过, hover)、选中(单击, pressed)状态下更换图标样式
- dc综合与pt静态时序分析(中文)_新能源汽车小三电系统(PDU/DC/OBC)技术研究详解...
- 爬取嘉兴市人才网即时招聘信息并写入文本TXT完整案例
- Redis 安装部署
- GROMOS拓扑(、坐标、轨迹、能量)相关文件解读手册第5章阅读笔记II
- 拳皇觉醒服务器维护,拳皇全明星拳魂觉醒手游9月26日更新公告_拳皇全明星拳魂觉醒9月26日更新了什么_玩游戏网...
- 外贸工具WhatsApp