工作中可能用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集合的怪相关推荐

  1. java去重复的集合_如何去除Java中List集合中的重复数据

    1.循环list中的所有元素然后删除重复 public class duplicatRemoval { public static List removeDuplicate(List list){ f ...

  2. Java中Set集合是如何实现添加元素保证不重复的?

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | 公众号「武培轩」 Java中Set集合是如何实 ...

  3. Thinking in java基础之集合框架

    Thinking in java基础之集合框架 大家都知道我的习惯,先上图说话. 集合简介(容器) 把具有相同性质的一类东西,汇聚成一个整体,就可以称为集合,例如这里有20个苹果,我们把每一个苹果当成 ...

  4. Java的数组集合概括

    Java的数组集合概括 Collection 1.List(存储有序,有索引,可以重复) 1.1.ArrayList 底层是数组实现的,线程不安全,查找和修改快,增删比较慢 1.2.LinkedLis ...

  5. Java对象容器——集合Set

    集合就是数学中的集合的概念:所有的元素都具有唯一的值,元素在其中没有顺序. 数学中的集合具有唯一性(没有重复元素),Java中的集合也是. 比如放三个值1,1,1输出这个集合的话只会输出一个1. Ha ...

  6. Set精讲(Java)·算法常用集合处理方法

    Set精讲(Java)·算法常用集合处理方法 Set概述 Set集合类似于一个罐子,程序可以依次把多个对象"丢进"Set集合,而Set集合通常不能记住元素的添加顺序.实际上Set就 ...

  7. 万字长文深入理解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 ...

  8. java 什么是线程同步,java多线程同步集合是什么?并发集合是什么?

    java中关于集合的内容也是十分丰富的,而且相关的知识点也是十分多的.多线程集合所涵盖的范围是十分广阔的.今天就来为大家介绍一下,java多线程同步集合是什么以及并发集合是什么?一起来看看吧. 首先我 ...

  9. (转)java中对集合对象list的几种循环访问总结

    Java集合的Stack.Queue.Map的遍历 在集合操作中,常常离不开对集合的遍历,对集合遍历一般来说一个foreach就搞定了,但是,对于Stack.Queue.Map类型的遍历,还是有一些讲 ...

最新文章

  1. TensorFlow人工智能引擎入门教程之二 CNN卷积神经网络的基本定义理解。
  2. 微软Skype突破!视讯人数上限来到50人
  3. python学习(1)
  4. oracle 重建em失败,11gr2 EM重建出现问题,求高人指点
  5. 我国计算机体系结构相关产业,中国工程院院士吴汉明:发展我国半导体产业,力求颠覆传统计算机体系结构...
  6. wxpython 可视化开发pdf_MicroPython for the Internet of Things.pdf
  7. 基于消息中间件RabbitMQ实现简单的RPC服务
  8. leetcode 721. 账户合并(并查集)
  9. PowerBI,自定义编辑同一页面中不同图表之间的交互,使页面交互更灵活
  10. JxBrowser概述与简单应用
  11. LeetCode 91. 解码方法
  12. MangoTrainingCourse课程hands-on lab-1
  13. 服务器系统2022安装wsl2,手把手教你踩坑:老白的Docker for Windows安装初探WSL 2 backend...
  14. QPushButton/QLabel在鼠标悬浮(划过, hover)、选中(单击, pressed)状态下更换图标样式
  15. dc综合与pt静态时序分析(中文)_新能源汽车小三电系统(PDU/DC/OBC)技术研究详解...
  16. 爬取嘉兴市人才网即时招聘信息并写入文本TXT完整案例
  17. Redis 安装部署
  18. GROMOS拓扑(、坐标、轨迹、能量)相关文件解读手册第5章阅读笔记II
  19. 拳皇觉醒服务器维护,拳皇全明星拳魂觉醒手游9月26日更新公告_拳皇全明星拳魂觉醒9月26日更新了什么_玩游戏网...
  20. 外贸工具WhatsApp

热门文章

  1. ulp通信_Java Math类ulp()方法及示例
  2. python安全攻防---scapy基础---计算机网络各层协议
  3. php的range函数
  4. hdu5446——Unknown Treasure
  5. C++ 常用查找算法
  6. 【c语言】棋盘游戏--三子棋
  7. fstat、stat和lstat 区别
  8. 【算法】学习笔记(5):快速排序
  9. 【操作系统】进程调度(2b):STCF(最短完成时间优先) 算法 原理与实践
  10. 700. 二叉搜索树中的搜索