Java基础数据结构之Map和Set

Map和Set接口

1.Set集合:独特性与无序性

Set是Java集合框架中的一种,它代表着一组无序且独特的元素。这意味着Set中的元素不会重复,且没有特定的顺序。Set接口有多个实现类,如HashSet、LinkedHashSet和TreeSet。

2.Map集合:键值对的存储

Map是Java集合框架中的另一种,它存储了一组键值对(Key-Value Pair)。每个键映射到一个值,使得通过键可以高效地检索对应的值。Map接口有多个实现类,如HashMapLinkedHashMap和TreeMap。

搜索树

1.概念

二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:

若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
它的左右子树也分别为二叉搜索树

2.创建一个二叉搜索树

查找:

插入:

    public boolean insert2(int val){TreeNode node=new TreeNode(val);if(root==null){root=node;} else {TreeNode cur=root;while(cur!=null){if(cur.val<val){if(cur.right==null){cur.right=node;break;}else if(cur.right.val>val){node.right=cur.right;cur.right=node;break;}else{cur=cur.right;}}else if(cur.val>val){if(cur.left==null){cur.left=node;break;}else if(cur.left.val<val){node.left=cur.left;cur.left=node;break;}else{cur=cur.right;}}else{return false;}}}return true;}

这段代码有问题,对于一个已经有俩个叉的节点,我们不能去更新它的左右孩子,所以对于二叉搜索树的插入操作,必须是在空节点上进行插入,代码如下:

删除:

    public boolean remove(int val){TreeNode cur=root;TreeNode parent=null;while(cur!=null){if(cur.val==val){break;}else if(cur.val<val){parent=cur;cur=cur.right;}else{parent=cur;cur=cur.left;}}if(cur==null){return false;} else if (cur.left==null) {if(cur==root){root=cur.right;} else if (cur==parent.left) {parent.left=cur.right;}else {parent.right = cur.right;}}else if(cur.right==null){if(cur==root){root=cur.left;} else if (cur==parent.left) {parent.left=cur.left;}else {parent.right = cur.left;}}else{TreeNode targetparent=cur;TreeNode target=cur.right;while(target.left!=null){targetparent=target;target=target.left;}if(targetparent==cur){cur.val=target.val;targetparent.right=target.right;}cur.val=target.val;targetparent.left=target.right;}return true;}

第一个while是找到待删除的节点,

如果待删节点左边为空:如果待删节点是根节点,则让待删节点的右边变成根;如果不是根节点,而是上一个结点的右面……是上一个结点的左面……

如果待删节点右面为空……

如果待删节点左右都不为空,我们的做法是:从待删结点的左边找到最大值(即左边子树的最右面的节点)或者从待删结点的右面找到最小值(即右面子树的最左边节点)。找到之后还要分类,分类如代码所示

3.和Java类集的关系

TreeMap TreeSet java 中利用搜索树实现的 Map Set ;实际上用的是红黑树,而红黑树是一棵近似平衡的
二叉搜索树,即在二叉搜索树的基础之上 + 颜色以及红黑树性质验证,关于红黑树的内容后序再进行讲解。

搜索

1.概念

Map set 是一种专门用来进行搜索的容器或者数据结构,其搜索的效率与其具体的实例化子类有关

2.模型

一般把搜索的数据称为关键字( Key ),和关键字对应的称为值( Value ),将其称之为 Key-value 的键值对,所以
模型会有两种:
纯key模型:比如快速查找某个电话在不在通讯录里面。
key-value模型:比如每个梁山好汉有自己的名字同时也有自己的绰号,比如统计每个单词出现的次数
其中Set是纯key模型,Map是key-value模型

Map的使用

1.实例化子类

这是一个泛型的接口,要传入key和value的类型

假设要统计单词的次数,则对于key是String类型,value是Integer类型,所以如下:

如果实例化TreeMap子类,则其搜索的时间复杂度为O(logN),如果是HashMap,则是O(1)。所以其搜索的效率与其具体的实例化子类有关

注意,使用时要导入对应的包:

其次,key是唯一的,不可以重复

2.Map中的常用方法

put方法返回值是放入的该单词的次数

get方法,参数是要得到的单词,返回值是单词的次数

getOrDefault方法,如果包含该单词,则返回对应的value,反之返回我们自己传入的defaultValue

boolean containsKey(Object key);判断是否包含key
boolean containsValue(Object value);判断是否包含value
V remove(Object key);删除key,即删除某个单词,返回对应的value即次数
void putAll(Map<? extends K, ? extends V> m);将m中的key和value全部放到map1中,其中,m的key的类型是map1的key的类型的子类,m的value类型是map1的value的类型的子类,如下:

Set<K> keySet();返回所有key的不重复集合,如下:

Collection<V> values();这个方法是返回所有value的集合

返回值是Collection<V>,那我进行向下转型,用ArrayList接收可以吗?试一试:

运行之后发现报错了?为什么呢?这不就是向下转型吗?实际上,这是非法的向下转型!!!看下面的例子,Student是Person的子类

这样的代码在运行时没有报错

这个代码报错了。其实是没真正理解向下转型以及父类和子类的关系

在Java中,父类引用可以指向子类实例,反之则不可以

第一段代码中p是父类引用,它是指向了子类实例,然后将一个子类实例p给到了子类的引用自然是可以的;而第二段代码中p是父类引用并且指向父类实例,然后将哟个父类实例p给到一个子类引用就是不可以的

这也就是为什么不可以用ArrayList来接收Collection类的返回值!!!!!

那么如何存储到ArrayList中?用Arraylist的一个构造方法:

代码如下:

或者将它存放到HashSet中:

Set<Map.Entry<K, V>> entrySet();要想了解这个方法,首先要看一下Map.Entry:

Entry是Map中的一个内部接口,包含了key和value,所以Set<Map.Entry<K, V>> entrySet();这个方法可以将key和value看成一个,都放到set中,如下:

或者如下打印:

3.注意

1.Map中存放的键值对的key是唯一的,value是可以重复的(就比如单词出现的次数的统计)

2.在TreeMap中插入键值对时,key不能为空,value可以为空;而HashMap中的key和value都可以为空

3.Map中的key可全部分离出来存到Set中进行访问

Set的使用

Set使用和Map类似,请详细看源码

只强调几个:

Iterator<E> iterator();用法如下:

boolean addAll(Collection<? extends E> c);
boolean containsAll(Collection<?> c);

注意这俩个方法的参数是实现了Collection接口的类,所以单纯的整型数组不可以作为参数传递,要用到Arrays中的aslist方法

boolean retainAll(Collection<?> c);这个方法只保留这个集合中包含在指定集合中的元素(可选操作)。换句话说,从这个集合中删除所有不包含在指定集合中的元素

注意:

1.Set时继承自Collection的接口类

2.TreeSet的底层是一个TreeMap

不管实例化一个什么样的TreeSet,value都是一个Object对象

3.Set中的key是唯一的

4.TreeSet的key不能是null,但HashSet可以

5.添加的对象必须是可以进行比较的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/665404.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis核心技术与实战【学习笔记】 - 19.Pika:基于SSD实现大容量“Redis”

前言 随着业务数据的增加&#xff08;比如电商业务中&#xff0c;随着用户规模和商品数量的增加&#xff09;&#xff0c;就需要 Redis 能保存更多的数据。你可能会想到使用 Redis 切片集群&#xff0c;把数据分散保存到不同的实例上。但是这样做的话&#xff0c;如果要保存的…

利用牛顿方法求解非线性方程(MatLab)

一、算法原理 1. 牛顿方法的算法原理 牛顿方法&#xff08;Newton’s Method&#xff09;&#xff0c;也称为牛顿-拉弗森方法&#xff0c;是一种用于数值求解非线性方程的迭代方法。其基本思想是通过不断迭代来逼近方程的根&#xff0c;具体原理如下&#xff1a; 输入&#…

PCB笔记(二十三):allegro 标注长宽(一般用于测量板宽)时如何显示双单位

步骤&#xff1a;首先选择标注工具&#xff0c;然后右键→Parameters&#xff0c;在弹出来的窗口中√上如下图二所示选项 最终要达到显示单位的效果的话&#xff0c;需要在Text项键入%v%u。 今天就记录到这里啦O

Leetcode206:反转链表

一、题目 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表 示例&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]输入&#xff1a;head [1,2] 输出&#xff1a;[2,1]输入&#xff1a;head [] 输出&#xff1…

[ESP32 IDF]web server

目录 通过web server控制LED 核心原理解析 分区表 web server的使用 错误Header fields are too long的解决 通过web server控制LED 通过网页控制LED灯的亮灭&#xff0c;一般的ESP32开发板都可以实现&#xff0c;下面这篇文章是国外开发者提供的一个通过web server控制…

13.2K Star,12306 抢票助手帮你回家

Hi&#xff0c;骚年&#xff0c;我是大 G&#xff0c;公众号「GitHub指北」会推荐 GitHub 上有趣有用的项目&#xff0c;一分钟 get 一个优秀的开源项目&#xff0c;挖掘开源的价值&#xff0c;欢迎关注。 马上过年了&#xff0c;今年你在哪里过年&#xff1f;回老家吗&#x…

前端入门第一天

目录 HTML超文本标记语言——Hyper Text Markup Language 标签语法&#xff1a; 双标签&#xff1a; 单标签——只有开始标签&#xff0c;没有结束标签 基本骨架&#xff1a; 标签的关系: 注释&#xff1a; 标题标签&#xff1a;&#xff08;新闻标题、文章标题、网页区域…

探索设计模式的魅力:为什么你应该了解装饰器模式-代码优化与重构的秘诀

设计模式专栏&#xff1a;http://t.csdnimg.cn/nolNS 开篇 在一个常常需要在不破坏封装的前提下扩展对象功能的编程世界&#xff0c;有一个模式悄无声息地成为了高级编程技术的隐形冠军。我们日复一日地享受着它带来的便利&#xff0c;却往往对其背后的复杂性视而不见。它是怎样…

项目安全-----加密算法实现

目录 对称加密算法 AES &#xff08;ECB模式&#xff09; AES(CBC 模式)。 非对称加密 对称加密算法 对称加密算法&#xff0c;是使用相同的密钥进行加密和解密。使用对称加密算法来加密双方的通信的话&#xff0c;双方需要先约定一个密钥&#xff0c;加密方才能加密&#…

C++ 动态规划 线性DP 最长共同子序列

给定两个长度分别为 N 和 M 的字符串 A 和 B &#xff0c;求既是 A 的子序列又是 B 的子序列的字符串长度最长是多少。 输入格式 第一行包含两个整数 N 和 M 。 第二行包含一个长度为 N 的字符串&#xff0c;表示字符串 A 。 第三行包含一个长度为 M 的字符串&#xff0c;表…

Servlet+Ajax实现对数据的列表展示(极简入门)

目录 1.准备工作 1.数据库源&#xff08;这里以Mysql为例&#xff09; 2.映射实体类 3.模拟三层架构&#xff08;Dao、Service、Controller&#xff09; Dao接口 Dao实现 Service实现&#xff08;这里省略Service接口&#xff09; Controller层&#xff08;或叫Servlet层…

【blender插件】(1)快速开始

特性 blender的python API有如下特性: 编辑用户界面可以编辑的任意数据(场景,网格,粒子等)。修改用户首选项、键映射和主题。运行自己的配置运行工具。创建用户界面元素,如菜单、标题和面板。创建新的工具。场景交互式工具。创建与Blender集成的新渲染引擎。修改模型的数据…

LeetCode.1686. 石子游戏 VI

题目 题目链接 分析 本题采取贪心的策略 我们先假设只有两个石头a,b&#xff0c; 对于 Alice 价值分别为 a1,a2&#xff0c; 对于 Bob 价值而言价值分别是 b1,b2 第一种方案是 Alice取第一个&#xff0c;Bob 取第二个&#xff0c;Alice与Bob的价值差是 c1 a1 - b1&#xf…

【Crypto | CTF】BUUCTF rsarsa1

天命&#xff1a;第二题RSA解密啦&#xff0c;这题比较正宗 先来看看RSA算法 这道题给出了 p&#xff0c;q&#xff0c;E&#xff0c;就是给了两个质数和公钥 有这三个东西&#xff0c;那就可以得出私钥了 最后把私钥和质数放进去解密即可得到解密后的明文 from gmpy2 impor…

会计的记账凭证

目录 一. 记账凭证的填制与审核1.1 收付款凭证1.2 转账凭证1.3 单式记账凭证 二. 记账凭证的编号 \quad 一. 记账凭证的填制与审核 \quad \quad 1.1 收付款凭证 \quad 注意︰ 凡是涉及货币资金之间收付款的业务如将库存现金存入银行或从银行提取现金等类经济业务。在实际工作中…

程序员的悲哀:知名Python库requests作者失业了

在当今这个快速发展的科技时代&#xff0c;程序员作为创新的驱动力&#xff0c;一直被视为时代的宠儿。然而&#xff0c;即使在这样一个充满机会的领域&#xff0c;也有着不为人知的辛酸。近日&#xff0c;一个令人震惊的消息传遍了编程社区&#xff1a;知名Python库requests的…

css1基础选择器

大纲 一.标签选择器 比较简单&#xff0c;前面直接写目标标签 二.类选择器 应用 例子 三.多类名选择器&#xff08;调用时中间用空格隔开&#xff09; 四.id选择器 应用 五.通配符选择器 应用 六.总结

gRPC使用详解

起源特点主要优缺点应用场景组成部分使用方法SpringBoot集成gRPCVert.x集成gRPCNacos集成gRPC监控gRPC调用过程Java使用示例 起源 gRPC的起源可以追溯到2015年&#xff0c;当时谷歌发布了一款开源RPC框架&#xff0c;名为gRPC。gRPC的设计初衷是为了提供一种标准化、可通用和跨…

【成品论文30页】2024美赛C题完整1-4问完整解答+答疑服务+完整数据集代码

2024美赛C题 也包括心理和环境因素。理解这些因素对于运动员、教练和观众来说都至关重要&#xff0c;因为它们直接影响着比赛的结果和整体体验。 技术水平和体能因紊 网球比赛中得分的波动首先受到运动员的技术水平和体能因素的影响。技术水平高的运动员往往能够以更加精准和有…