C++之闭散列哈希表
目录
unordered_set和unordered_map
哈希概念
哈希表基本结构
哈希冲突
线性探测编辑
二次探测
前几期我们学习了红黑树和红黑树的模拟实现,最终使用红黑树封装了map和set。本期开始我们将学习下一个重要的知识点---哈希表,最终使用哈希表封装unordered_map和unordered_set。
unordered_set和unordered_map
在学习哈希之前,我们先了解一下unordered_set和unordered_map,这两个容器也都是关联式容器,我们之前已经学习了map和set。unordered_set和unordered_map与set和map大体上是一样的,但是也有几点不同。
1.map和set的底层是用红黑树进行封装实现的,也正因为如此,红黑树是一个搜索二叉树,搜索二叉树的元素我们是按照中序遍历的方法进行遍历的。所以map和set的元素的遍历是有序的,而unordered_set和undered_map的元素的遍历是无序的。
2.map和set是双向迭代器,而unordered_set和unordered_map是单项迭代器,通过C++官方文档就可以看出来。
3.map和set查找一个元素时,因为底层是红黑树,所以最多查找高度次,所以查找一个元素的时间复杂度为O(logN),而unordered_set和unordered_map底层是哈希,所以查找一个元素的时间复杂度为O(1),为什么是O(1),下面会为大家阐述。
哈希概念
有N个数的集合,这N个数的范围为[1,26],N个数中有重复的数,现在要统计这N个数中,每个数出现的次数,我们该如何进行统计呢?
有一种方法,就是开辟一个大小为27的一维数组,让这N个数的每个数都%27,然后将取模之后得到的数作为数组的下标,对应数组元素的值为这一数字出现的次数,通过这一方法就可以统计得到N个数每个元素出现的次数。这其实就是哈希的一种体现。
哈希表:通过哈希函数,使得关键码和元素位置建立一一映射的表,我们称之为哈希表。
哈希表基本结构
namespace CloseHash
{enum Status{EMPTY,DELETE,EXIST};template<class K, class V>struct HashData{private:pair<K, V> _kv;Status _st = EMPTY;};template<class K,class V>class HashTable{private:vector<HashData<K, V>> _v;int _n; //哈希表中有效元素的个数};}
哈希冲突
何为哈希冲突呢?前提为我们要用一个一维数组存储数据。
有1组数为1,7,2,8,映射在大小为7的数组中,1映射到下标为1的位置,7也映射到1的位置,但是数组的一个元素中只能存储一个数据,那么1先存入之后,7要存入时这就产生了冲突,我们就称这为哈希冲突。
简单来说,哈希冲突就是不想同的元素,通过哈希映射,映射到了哈希表的同一位置。
如何解决哈希冲突呢?我们使用了闭散列的方法,即为线性探测和二次探测法。什么是线性探测?什么又是二次探测法呢?
线性探测

线性探测就是,当第二个元素与第一个元素产生哈希冲突时,从产生冲突的位置开始,依次往后继续寻找空的位置,寻找到空的位置之后,将产生冲突的元素放在空的位置。代码实现如下。
代码如下。
//哈希表中元素的插入bool insert( const pair<K,V>& kv){//先去判断哈希表中是否存在当前要插入的元素,因为哈希表的原理是不排序加去重HashData<K, V>* ret = find(kv.first);if (ret != nullptr){return false;}if (_v.size() == 0 || _n*10 / _v.size() > 7){int NewSize = _v.size() == 0 ? 10 : _v.size() * 2;HashTable<K, V> ht;ht._v.resize(NewSize);for (int i = 0; i< _v.size(); i++){if (_v[i]._st == EXIST){ht.insert(_v[i]._kv);}}_v.swap(ht._v);}HashFunc<K> hf;int start = hf(kv.first) % _v.size();int i = 0;size_t index = start;while (_v[start]._st == EXIST){++i;start = index + i;start% _v.size();}_v[start]._kv = kv;_v[start]._st = EXIST;++_n;return true;}
大家来想一个问题?当哈希表中的元素越来越多时,产生哈希冲突的概率必然也是越来越大的,怎么样去避免这类现象出现呢?
唯一的办法就是不断的去扩容,所以我们引入了平衡因子的概念,就是哈希表中的有效元素个数除以哈希表的容量,注意,这里的容量是size(),即vector中申请并初始化之后的元素的数目。
二次探测
何为二次探测,并不是探测两次,而是2次方。图示如下。
二次探测和线性探测类似。线性探测有一个缺点,就是当相同位置的元素过多时,就会侵占当前位置附近的其他位置,这就导致,本来处在附近位置的元素又去侵占其它元素的位置,这样会降低整个哈希表的查找效率,所以我们引入了二次探测,即插入的元素引起哈希冲突时,并不会在后续的第一个空位置插入冲突的元素,而是会去寻找当前位置+i*i的位置,如果当前位置为空,则插入元素。
代码如下。
bool insert( const pair<K,V>& kv){//先去判断哈希表中是否存在当前要插入的元素,因为哈希表的原理是不排序加去重HashData<K, V>* ret = find(kv.first);if (ret != nullptr){return false;}if (_v.size() == 0 || _n*10 / _v.size() > 7){int NewSize = _v.size() == 0 ? 10 : _v.size() * 2;HashTable<K, V> ht;ht._v.resize(NewSize);for (int i = 0; i< _v.size(); i++){if (_v[i]._st == EXIST){ht.insert(_v[i]._kv);}}_v.swap(ht._v);}HashFunc<K> hf;int start = hf(kv.first) % _v.size();int i = 0;size_t index = start;while (_v[start]._st == EXIST){++i;//start = index + i;start = index + i * i;start% _v.size();}_v[start]._kv = kv;_v[start]._st = EXIST;++_n;return true;}
闭散列哈希表整体代码如下。
#pragma once
#include<iostream>
#include<vector>
#include <string>
using namespace std;namespace CloseHash
{enum Status{EMPTY,DELETE,EXIST};template<class K>struct HashFunc{size_t operator()(const K& key){return key;}};template<>struct HashFunc <string>{size_t operator()(const string& string){size_t value = 0;for (auto e : string){value *= 31;value += e;}return value;}};template<class K, class V>struct HashData{pair<K, V> _kv;Status _st = EMPTY;};template<class K,class V,class hashFunc=HashFunc<K>>class HashTable{public:bool erase(const K& key){HashData<K, V>* ret = find(key);if (ret == nullptr){return false;}else{ret->_st = DELETE;_n--;return true;}}HashData<K,V>* find(const K& key){if (_v.size() == 0){return nullptr;}HashFunc<K> hf;size_t start = hf(key) % _v.size();int i = 0;size_t index = start;while (_v[start]._st != EMPTY){if (_v[start]._kv.first == key && _v[start]._st == EXIST){return &_v[start];}++i;start = index + i;}return nullptr;}//哈希表中元素的插入bool insert( const pair<K,V>& kv){//先去判断哈希表中是否存在当前要插入的元素,因为哈希表的原理是不排序加去重HashData<K, V>* ret = find(kv.first);if (ret != nullptr){return false;}if (_v.size() == 0 || _n*10 / _v.size() > 7){int NewSize = _v.size() == 0 ? 10 : _v.size() * 2;HashTable<K, V> ht;ht._v.resize(NewSize);for (int i = 0; i< _v.size(); i++){if (_v[i]._st == EXIST){ht.insert(_v[i]._kv);}}_v.swap(ht._v);}HashFunc<K> hf;int start = hf(kv.first) % _v.size();int i = 0;size_t index = start;while (_v[start]._st == EXIST){++i;//start = index + i;start = index + i * i;start% _v.size();}_v[start]._kv = kv;_v[start]._st = EXIST;++_n;return true;}private:vector<HashData<K,V>> _v;int _n; //哈希表中有效元素的个数};void HashTest(){HashTable<int, int> ht;ht.insert(make_pair(1, 1));ht.insert(make_pair(2, 1));ht.insert(make_pair(3, 1));ht.insert(make_pair(4, 1));cout << ht.find(1) << endl;cout << ht.find(5) << endl;}}
调试代码,发现运行结果符合预期。
以上便是哈希表中闭散列哈希表的所有内容,下期将为大家带来开散列哈希表的内容。
本期内容到此结束^_^
相关文章:
C++之闭散列哈希表
目录 unordered_set和unordered_map 哈希概念 哈希表基本结构 哈希冲突 线性探测编辑 二次探测 前几期我们学习了红黑树和红黑树的模拟实现,最终使用红黑树封装了map和set。本期开始我们将学习下一个重要的知识点---哈希表,最终使用哈希表封装u…...
微信小程序map组件所有markers展示在视野范围内
注意:使用include-points属性不生效,要通过createMapContext实现 <template><view class"map-box"><map id"map" class"map" :markers"markers" :enable-traffic"true" :enable-poi&…...
Ubuntu平台虚拟机软件学习笔记
Ubuntu平台上常见虚拟机软件 VirtualBox [Download]KVM/QEMU 1. VirtualBox 1.1 查看安装版本 VBoxManage -V2. KVM/QEMU KVM: Kernel-based Virtual Machine QEMU: Quick EMUlator 通义千问: virt-manager 既不是QEMU也不是KVM,而是用于管理和创建…...
EasyExcel数据的导入导出
1.easyExcel简介 EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。 他能让你在不用考虑性能、内存的等因素的情况下,快速完成Excel的读、写等功能。 EasyExcel 的主要特点如下: 1、高性能:EasyExcel 采用了异…...
CSS Grid 布局全攻略:从基础到进阶
文章目录 一.Grid 是什么二.示例代码1. 基础使用 - 固定宽高2.百分百宽高3.重复设置-repeat4.单位-fr5.自适应6.间距定义其他 一.Grid 是什么 CSS 中 Grid 是一种强大的布局方式,它可以同时处理行和列 Grid 和Flex有一些类似,都是由父元素包裹子元素使用…...
C语言的语法
C语言的语法与应用探讨 C语言作为一种高效的程序设计语言,自1970年代问世以来,一直在科学计算、系统编程、嵌入式系统等领域中扮演着重要角色。本文将深入探讨C语言的基本语法、数据结构、控制结构以及其在实际应用中的重要性。 一、C语言基础 1.1 数…...
Go中的context 包使用详解
context 包在 Go 中非常重要,特别是在处理并发和超时的场景下,它能让你在多个 goroutine 之间传递取消信号、超时控制或其他控制信息。context 是 Go 并发模型中的一个重要工具,尤其适用于 HTTP 请求、数据库操作、分布式系统等场景。 1. 基…...
通俗易懂之线性回归时序预测PyTorch实践
线性回归(Linear Regression)是机器学习中最基本且广泛应用的算法之一。它不仅作为入门学习的经典案例,也是许多复杂模型的基础。本文将全面介绍线性回归的原理、应用,并通过一段PyTorch代码进行实践演示,帮助读者深入…...
机器学习模型评估指标
模型的评估指标是衡量一个模型应用于对应任务的契合程度,常见的指标有: 准确率(Accuracy): 正确预测的样本数占总样本数的比例。适用于类别分布均衡的数据集。 精确率(Precision): 在所有被预测为正类的样…...
嵌入式软件C语言面试常见问题及答案解析(三)
嵌入式软件C语言面试常见问题及答案解析(三) 上一篇已经足够长了,再长也就有点不礼貌了,所以在这儿继续来总结分享那个面试中遇到的题目,文中的问题和提供的答案或者代码均代表个人的理解,如有不合理或者错误的地方,欢迎大家批评指正。 本文中题目列表 1. 编码实现子串定…...
LeetCode:165. 比较版本号(双指针 Java)
目录 165. 比较版本号 题目描述: 实现代码与解析: 双指针 原理思路: 165. 比较版本号 题目描述: 给你两个 版本号字符串 version1 和 version2 ,请你比较它们。版本号由被点 . 分开的修订号组成。修订号的值 是它…...
Golang中遇到“note module requires Go xxx”后的解决方案,不升级Go版本!
前几天,需要对一个两年前写的项目添加点儿新功能,需要用到一个 Http 客户端包,于是就用了 https://github.com/go-resty/resty 这个插件包。 我先是直接在项目根目录下执行了以下包的安装命令: go get -v github.com/go-resty/res…...
ubuntu编译ijkplayer,支持rmvb以及mkv
1. 准备环境 sudo apt-get update apt install gcc yasm cmake python p7zip-full vim pkg-config autoconf automake build-essential dos2unix mercurial cmake-curse-gui -y apt-get -y --force-yes install libass-dev libtheora-dev libtool libva-dev libvdpau-dev libv…...
mysql之sql的优化方案(重点)
1、全字段匹配是最棒的 假如一个Staffs 这个表,将 name,age ,pos 组合成了一个联合索引,在where条件下,能够使用到的索引越多越好。 EXPLAIN SELECT * FROM staffs WHERE NAME July; EXPLAIN SELECT * FROM staffs WHERE NAME July AND age…...
使用Qt实现json数据的格式检测并序列化输出 Qt5.4.0环境
问题: 使用 Qt 实现 JSON 数据的格式检测,并输出各个键值 代码: widget.h #include <QWidget> #include <QJsonDocument> /*序列化 反序列化(F1查看帮助文档)*/ #include <QJsonObject> /*利用对象代表了一段json数据*/ …...
Internet协议原理
文章目录 考试说明Chapter 0: 本书介绍Chapter 1: Introduction And Overview 【第1章:引言与概述】Chapter 2: Overview Of Underlying Network Technologies 【第2章:底层网络技术的回顾】Chapter 3: Internetworking Concept And Architectural Model…...
国标GB28181-2022视频平台EasyGBS小知识:局域网ip地址不够用怎么解决?
在局域网中,IP地址不足的问题通常不会在小型网络中出现,但在拥有超过255台设备的大型局域网中,就需要考虑如何解决IP地址不够用的问题了。 在企业局域网中,经常会出现私有IP地址如192.168.1.x到192.168.1.255不够用的情况。由于0…...
CentOS 使用 yum 方式安装 Nginx
CentOS 使用 yum 方式安装 Nginx 文章目录 CentOS 使用 yum 方式安装 Nginx1、Nginx 安装前提条件步骤 1:更新系统软件包步骤 2:查看 Nginx 相关的软件包步骤 3:安装 Nginx步骤 4:启动并启用 Nginx步骤 5:验证 Nginx 是…...
Spring Boot教程之五十一:Spring Boot – CrudRepository 示例
Spring Boot – CrudRepository 示例 Spring Boot 建立在 Spring 之上,包含 Spring 的所有功能。由于其快速的生产就绪环境,使开发人员能够直接专注于逻辑,而不必费力配置和设置,因此如今它正成为开发人员的最爱。Spring Boot 是…...
消息队列:原理、问题与设计全解析
1.如何保证消息的顺序性 保证消息顺序性通常是在分布式系统或网络通信中遇到的一个挑战。以下是几种常见的方法来确保消息的顺序性: 单生产者单消费者模型: 如果系统设计为只有一个生产者和一个消费者,那么保持消息顺序相对简单,…...
成功!QT 5.15.2编译mysql驱动
首选要说明,5.15与6.7编译驱动是完全不同的。搞错了永远编译不出来。 参考 主要是参考安装QT,安装mysql等。 编译成功!QT/6.7.2/Creator编译Windows64 MySQL驱动(MSVC版)_mingw编译qt6.7-CSDN博客 复制mysql的include和lib到一个方便的目…...
【玩转全栈】----Django连接MySQL
阅前先赞,养好习惯! 目录 1、ORM框架介绍 选择建议 2、安装mysqlclient 3、创建数据库 4、修改settings,连接数据库 5、对数据库进行操作 创建表 删除表 添加数据 删除数据 修改(更新)数据: 获取数据 1、OR…...
【Spring Boot】Spring AOP 快速上手指南:开启面向切面编程新旅程
前言 🌟🌟本期讲解关于spring aop的入门介绍~~~ 🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客 🔥 你的点赞就是小编不断更新的最大动力 🎆那么废话不…...
力扣--54.螺旋矩阵
题目 给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。 提示: m matrix.length n matrix[i].length 1 < m, n < 10 -100 < matrix[i][j] < 100代码 class Solution { public List spiralOr…...
【Uniapp-Vue3】image媒体组件属性
如果我们想要在页面上展示图片就需要使用到image标签。 这部分最重要的是图片的裁剪,图片的裁剪和缩放属性: mode 图片裁剪、缩放的模式 默认值是scaleToFill 我将用两张图片对属性进行演示,一张是pic1.jpg(宽更长…...
Ubuntu上安装Apache Spark
在Ubuntu上安装Apache Spark的步骤如下: 1. 安装Java Spark是用Scala编写的,并且依赖Java。因此,首先需要安装Java。 安装OpenJDK 8(或更高版本) 执行以下命令安装OpenJDK: sudo apt update sudo apt …...
Nginx入门笔记
Nginx入门笔记 一、Nginx基本概念二、代理1、正向代理2、反向代理 三、准备工作1、CentOS 7安装nginx(1). 安装必要的依赖(2)下载nginx(3)编译安装(4)编译并安装 Nginx(5)启动nginx …...
HTML5 滑动效果(Slide In/Out)详解
HTML5 滑动效果(Slide In/Out)详解 滑动效果(Slide In/Out)是一种常见的动画效果,使元素从一侧滑入或滑出,增强页面的动态感和用户体验。以下是滑动效果的详细介绍及实现示例。 1. 滑动效果的特点 动态视…...
unity学习8:unity的基础操作 和对应shortcut
目录 1 unity的基础操作的工具,就在scene边上 1.1 对应shortcut快捷键 2 物体的重置/ 坐标归到0附近 3 F:快速找到当前gameobject 4 Q:小手和眼睛,在场景中移动 5 W:十字箭头,移动gameobject 6 …...
计算机网络 (32)用户数据报协议UDP
前言 用户数据报协议(UDP,User Datagram Protocol)是计算机网络中的一种重要传输层协议,它提供了无连接的、不可靠的、面向报文的通信服务。 一、基本概念 UDP协议位于传输层,介于应用层和网络层之间。它不像TCP那样提…...
java内存区域 - 栈
目录 java内存区域 - 栈1. Java虚拟机栈的组成2. 栈帧中的详细内容2.1 局部变量表2.2 操作数栈2.3 动态链接2.4 方法返回地址2.5 附加信息 3. JVM栈的生命周期4. 示例解析 - 运行时的栈帧分布5. 栈中的异常6.栈配置7.本地方法栈 java内存区域 - 栈 在JDK11中,JVM栈…...
AI大模型-提示工程学习笔记5
卷首语:我所知的是我自己非常无知,所以我要不断学习。 写给AI入行比较晚的小白们(比如我自己)看的,大神可以直接路过无视了。 零提示是什么 “零提示”(Zero-shot)是指在没有提供任何特定示例…...
跨站脚本攻击(XSS)详解
跨站脚本攻击(XSS)详解 跨站脚本攻击(XSS,Cross-Site Scripting)是一种通过在网页中注入恶意脚本,攻击用户浏览器的漏洞。攻击者可以利用XSS窃取用户敏感信息、劫持会话、或在受害者浏览器中执行恶意操作。…...
【图像加密解密】Logistic混沌映射的彩色图像加密算法复现(含相关性检验)【Matlab完整源码 1期】
1、说明 本文给出详细完整代码、完整的实验报告和PPT。 环境:MATLAB2019a 复现文献:[1]黄硕.基于改进的Logistic混沌映射彩色图像加密算法[J].河南工程学院学报(自然科学版),2015,27(02):63-67. 主要目的是为了快速了解何为混沌序列、混沌序列产生、…...
VUE学习
import { ref } from vue; 引入了 Vue 的 ref 函数,用于创建响应式数据。const message ref(Hello Vue3); 创建了一个响应式变量 message 并初始化为字符串 Hello Vue3。<h1>{{ message }}</h1> 使用了 Vue 的插值表达式 {{ message }} 来显示 message…...
buildroot 编译 x264 及 ffmpeg
buildroot 编译 x264 及 ffmpeg 依赖安装x264编译安装解压源码并修改配置文件配置及编译编译错误: aarch64-linux-ar: two different operation options specified编译结果ffmpeg安装源码编译错误 : ERROR: x264 not found using pkg-config为在rk3568平台上开发音视频采集及…...
HarmonyOS开发:ArkTS初识
ArkTS基本语法 ArkTS语言简介 ArkTS是鸿蒙生态的应用开发语言。基本语法风格与TypeScript(简称TS)相似,在TS的生态基础上进一步扩展,继承了TS的所有特性,是TS的超集。 基本语法概述 扩展能力 基础语法:…...
C++ STL map和set的使用
序列式容器和关联式容器 想必大家已经接触过一些容器如:list,vector,deque,array,forward_list,string等,这些容器统称为系列容器。因为逻辑结构为线性的,两个位置的存储的值一般是…...
VisionPro软件Image Stitch拼接算法
2D图像拼接的3种情景 1.一只相机取像位置固定,或者多只相机固定位置拍图,硬拷贝拼图,采用CopyRegion工具实现 2.一只或多只相机在多个位置拍照,相机视野互相重叠,基于Patmax特征定位后,无缝 拼图ÿ…...
缓存-Redis-缓存更新策略-主动更新策略-Cache Aside Pattern(全面 易理解)
**Cache-Aside Pattern(旁路缓存模式)**是一种广泛应用于缓存管理的设计模式,尤其在使用 Redis 作为缓存层时尤为常见。该模式通过在应用程序与缓存之间引入一个旁路,确保数据的一致性和高效性。本文将在之前讨论的 Redis 主动更新…...
Linux(Centos 7.6)命令详解:cd
1.命令作用 改变当前工作目录(change directory) 2.命令语法 Usage: cd [-L|[-P [-e]]] [dir] 3.参数详解 -L,当目标路径是符号链接时,强制使用符号链接,这是一个默认选项。-P,使用物理路径代替符号链接。-e࿰…...
oracle位运算、左移右移、标签算法等
文章目录 位运算基础与或非同或同或应用场景 异或异或应用场景 什么是真值表 oracle基础函数创建bitor(按位或)函数bitnot(按位非)函数bitxor(按位异或)函数左移函数BITSHIFT()函数(实测不可用,废弃掉该方案)右移函数(略,有此场景吗?) 实际应用资质字典…...
预训练语言模型——BERT
1.预训练思想 有了预训练就相当于模型在培养大学生做任务,不然模型初始化再做任务就像培养小学生 当前数据层面的瓶颈是能用于预训练的语料快被用完了 现在有一个重要方向是让机器自己来生成数据并做微调 1.1 预训练(Pre - training)vs. 传…...
基于Thinkphp6+uniapp的陪玩陪聊软件开发方案分析
使用uni-app框架进行前端开发。uni-app是一个使用Vue.js开发所有前端应用的框架,支持一次编写,多端发布,包括APP、小程序、H5等。 使用Thinkphp6框架进行后端开发。Thinkphp6是一个轻量级、高性能、面向对象的PHP开发框架,具有易…...
C++异常处理
C异常处理 C中的异常处理机制是通过try、throw和catch三个关键字来实现的,主要用于捕获和处理程序执行过程中可能出现的错误或异常情况,从而提高程序的健壮性和可维护性。 基本概念 try块:用于定义一个可能抛出异常的代码块。在这个代码块…...
UVM: TLM机制
topic overview 不建议的方法:假如没有TLM TLM TLM 1.0 整个TLM机制下,底层逻辑离不开动作发起者和被动接受者这个底层的模型基础,但实际上,在验证环境中,任何一个组件,都有可能成为动作的发起者࿰…...
基于机器学习的故障诊断(入门向)
一、原始信号的特征提取 1.EMD经验模态分解的作用 信号分析:EMD可以将信号分解为多个IMFs,每个IMF代表信号中的一个特定频率和幅度调制的成分。这使得EMD能够提供对信号的时频特征进行分析的能力(特征提取用到的)。信号去噪&…...
Linux 磁盘管理命令:使用xfs 管理命令
文章目录 Linux磁盘管理命令使用xfs 管理命令1.命令说明2.建立 XFS 文件系统4.调整 XFS 文件系统各项参数5.在线调整 XFS 文件系统的大小6.暂停和恢复 XFS 文件系统7.尝试修复受损的 XFS 文件系统8.备份和恢…...
《Spring Framework实战》8:4.1.3.Bean 概述
欢迎观看《Spring Framework实战》视频教程 Spring IoC 容器管理一个或多个 bean。这些 bean 是使用 您提供给容器的配置元数据(例如,以 XML <bean/>定义的形式)。 在容器本身中,这些 bean 定义表示为BeanDefinition对象&a…...
Spring Boot教程之五十二:CrudRepository 和 JpaRepository 之间的区别
Spring Boot – CrudRepository 和 JpaRepository 之间的区别 Spring Boot建立在 Spring 之上,包含 Spring 的所有功能。由于其快速的生产就绪环境,使开发人员能够直接专注于逻辑,而不必费力配置和设置,因此如今它正成为开发人员…...