数据结构(Java):Map集合Set集合哈希表
目录
1、介绍
1.1 Map和Set
1.2 模型
2、Map集合
2.1 Map集合说明
2.2 Map.Entry<K,V>
2.3 Map常用方法
2.4 Map注意事项及实现类
3、Set集合
3.1 Set集合说明
3.2 Set常用方法
3.3 Set注意事项及其实现类
4、TreeMap&TreeSet
4.1 集合类TreeMap(Key-Value模型)
4.1.1 底层结构
4.2 集合类TreeSet(纯Key模型)
4.2.1 底层结构
4.3 TreeMap与TreeSet之间的关系
4.3.1 再谈TreeSet之构造方法
4.3.2 再谈TreeSet之add方法
4.4 TreeMap&TreeSet总结
5、哈希表
5.1 概念
5.2 冲突-概念
5.2 冲突-避免
5.2.1 设计合理的哈希函数
5.2.2 调节负载因子
5.3 冲突-解决
5.3.1 闭散列
5.3.2 🌟开散列/哈希桶/开链法
5.4 HashMap&HashSet
5.4.1 hashCode与equals方法
5.5 性能分析
5.6 总结
1、介绍
1.1 Map和Set
Map和Set是一种专门用来进行搜索的容器或者数据结构,其搜索的效率与其具体的实例化子类有关。
Map和Set能够在查找时进行一些插入和删除的操作,即动态查找。
1.2 模型
一般把搜索的数据称为关键字(Key),和关键字对应的称为值(Value),将其称之为Key-value的键值对,所以模型会有两种:
- 纯Key模型:数据仅包含关键字。
- Key-Value模型:数据除关键字外,还有关键字所对应的值。例如:统计文件中每个单词出现的次数,统计结果是每个单词都有与其对应的次数:<单词,单词出现的次数>。
Map集合是Key-Value模型;而Set集合是纯Key模型。
2、Map集合
2.1 Map集合说明
Map是一个接口类,该接口没有继承自Collection,是一个单独的接口,为Key-Value模型,存储的是<K,V>结构的键值对,并且K一定是唯一的,不能重复。 (K不可重复,V可重复)
2.2 Map.Entry<K,V>
Entry是Map接口的一个内部接口,是用来存放<Key,Value>键值对映射关系的内部接口。
内部接口Map.Entry<K,V>主要提供了<Key,Value>的获取,Value的设置以及Key的比较方式。
注意:Map.Entry<K,V>并没有提供设置Key的方法 !!!Key无法修改!!!
同样,实现Map接口的类也需要实现Entry接口:
这里以TreeMap的内部类Entry为例,Entry实现了的Map.Entry接口,而Entry就相当于我们之前所学二叉树的一个节点TreeNode。
TreeMap的底层是一个红黑树(下文详解),TreeMap的内部类Entry就相当于红黑树的一个节点,有key、value等属性。
2.3 Map常用方法
演示如下:
若我们使用get方法来获取一个不存在的key的value值时,返回的value为null,
所以当value为Integer类型时,最好使用包装类Integer接收,若使用int基本类型接收会自动拆箱,可能抛出空指针异常:
需要注意的是keySet、values、entrySet方法:
- keySet,可以将key值放在Set集合中,返回Set集合;
- values,可以将value值放在Collection集合中,返回Collection集合;
- entrySet,可以将key-value映射关系放在Set集合中,返回Set集合。
注意:Map系列集合是不能用迭代器实现遍历的,若想使用迭代器遍历,需要使用keySet、values、entrySet方法转换为Set集合,再使用迭代器遍历!!!
2.4 Map注意事项及实现类
- Map是一个接口,不能直接实例化对象,如果要实例化对象只能实例化其实现类TreeMap或者HashMap
- Map中存放键值对的Key不能重复,value是可以重复的
- 在TreeMap中插入键值对时,key不能为空,否则就会抛NullPointerException异常,value可以为空。(TreeMap底层是一颗红黑树,涉及key之间的比较)
- HashMap的key和value都可以为空。
- Map中的Key可以全部分离出来,存储到Set中来进行访问(Key不能重复)。
- Map中的value可以全部分离出来,存储在Collection的集合中,若存储在其子集中则强转为Collection(value可以有重复)。
- Map中键值对的Key不能直接修改,value可以修改,如果要修改key,只能先将该key删除掉,然后再来进行重新插入。
- TreeMap和HashMap是实现Map的集合类
TreeMap与HashMap:
下文细讲TreeMap与HashMap。
3、Set集合
3.1 Set集合说明
Set集合是纯Key模型,也就是说,Set只存储了Key。
Set集合中的Key值也不能重复存在,能够达到天然去重的效果。
Set与Map主要的不同有两点:
- Set是继承自Collection的接口类。
- Set是纯Key模型,只存储了Key。
3.2 Set常用方法
因为Set是是继承自Collection的接口类,所以其方法很多与我们之前学的Collection接口下的类是相同的,这里不再赘述。
需要注意的是:
- 如果将其他集合的元素添加到Set集合中,可以到达天然去重的效果;
- Set集合可以使用迭代器遍历;
3.3 Set注意事项及其实现类
- Set是继承自Collection的一个接口类。
- Set中只存储了key,并且要求key一定要唯一。
- TreeSet的底层是使用TreeMap来实现的,其使用Key与Object的一个默认对象作为键值对插入到Map中。
- Set最大的功能就是对集合中的元素进行去重。
- 实现Set接口的常用类有TreeSet和HashSet(下文细讲),还有一个LinkedHashSet,LinkedHashSet是在HashSet的基础上维护了一个双向链表来记录元素的插入次序。
- Set中的Key不能修改,如果要修改,先将原来的删除掉,然后再重新插入
- TreeSet中不能插入null的key(底层为搜索二叉树,涉及key的比较),HashSet可以。
TreeSet与HashSet:
4、TreeMap&TreeSet
为什么要将TreeMap和TreeSet放到一起说呢?因为这两者间是有关系的。
4.1 集合类TreeMap(Key-Value模型)
4.1.1 底层结构
TreeMap是Map集合下的一个集合类,底层是一颗红黑树,红黑树是一颗二叉搜索树,所以其Key值必须具备可比较功能。
也就是说,如果其Key是自定义类型,则这个自定义类必须实现Comparable接口或者给TreeMap的构造方法提供比较器。
因为TreeMap底层为红黑树,故其插入删除查找元素的时间复杂度为O(logN)
4.2 集合类TreeSet(纯Key模型)
4.2.1 底层结构
TreeSet是Set集合下的一个集合类,底层也是一颗红黑树,红黑树是一颗二叉搜索树,所以其Key值也必须具备可比较功能。
故,TreeSet插入删除查找元素的时间复杂度也为O(logN)
同样,如果其Key是自定义类型,则这个自定义类必须实现Comparable接口或者给TreeSet的构造方法提供比较器。
4.3 TreeMap与TreeSet之间的关系
虽然TreeMap是Map下的集合,TreeSet是Set下的集合,
但是细心的小伙伴已经发现,TreeMap和TreeSet的底层结构不仅都是红黑树,而且他们的Key值都不能重复出现,那么他们之间是不是有什么关系呢?
没错,其实TreeSet的底层是使用TreeMap来实现的。
可是为什么呢?接下来,让我们从TreeSet的源码中找到原因。
4.3.1 再谈TreeSet之构造方法
我们可以看到,当我们调用TreeSet的无参构造方法创建TreeSet对象时,其实是创建了一个TreeMap对象并传给了带一个参数的构造方法,并用NavigableMap类型的成员变量m将这个TreeMap对象引用起来。
而NavigableMap是什么呢,我们点过去后发现是一个接口,并且拓展了SortedMap接口,而我们发现SortedMap接口拓展了Map接口。
我们再观察TreeMap,发现TreeMap实现了NavigableMap接口。
所以,其实TreeMap有着下图的实现结构:
也就是说NavigableMap可以用来接收TreeMap对象实现向上转型,同时也说明,当我们实例化一个TreeSet对象时,实际上创建的是一个TreeMap对象。
也就是说,TreeSet的底层其实就是TreeMap!!!
4.3.2 再谈TreeSet之add方法
因为TreeSet的底层是TreeMap,所以添加元素add时,实际上调用的是TreeMap的put方法,而其value值是PRESENT,而PRESENT永远都是一个Object对象。
所以,不管add的Key是什么东西,其value值永远都是一个Object对象。
4.4 TreeMap&TreeSet总结
- TreeMap底层是一颗红黑树,二叉搜索树。
- TreeSet的底层是TreeMap,所以TreeSet也是一颗红黑树,二叉搜索树。
- TreeSet的底层是TreeMap,所以其Key不可重复,具有Map的去重功能。
5、哈希表
5.1 概念
在顺序结构以及平衡树中,元素关键码与其存储位置之间没有对应的关系,因此在查找一个元素时,必须要经过关键码(Key)的多次比较。顺序查找时间复杂度为O(N),平衡树中为树的高度即O(logN),搜索的效率取决于搜索过程中 元素的比较次数。
而哈希表可以通过哈希函数使元素的存储位置与它的关键码之间能够建立一一映射的关系,不经过任何比较,一次直接从表中得到要搜索的元素。
该方式即为哈希(散列)方法,哈希方法中使用的转换函数称为哈希(散列)函数,构造出来的结构称为哈希表(或者称散列表)。
插入元素:
- 根据待插入元素的关键码,以此函数计算出该元素的存储位置并按此位置进行存放
查找元素:
- 对元素的关键码进行同样的计算,把求得的函数值当做元素的存储位置,在结构中按此位置取元素比较,若 关键码相等,则搜索成功
哈希表 插入/删除/查找操作的时间复杂度为 O(1)。
5.2 冲突-概念
不同关键字通过相同哈希函数计算出相同的哈希地址,该种现象称为哈希冲突或哈希碰撞。
把具有不同关键码而具有相同哈希地址的数据元素称为"同义词"。
由于我们哈希表底层数组的容量往往是小于实际要存储的关键字的数量的,
这就导致一个问题:冲突的发生是必然的,但我们能做的应该是尽量的降低冲突率
5.2 冲突-避免
避免冲突有两个办法,一个是设计合理的哈希函数,一个是调节负载因子。
5.2.1 设计合理的哈希函数
哈希函数设计原则:
- 哈希函数的定义域必须包括需要存储的全部关键码,而如果散列表允许有m个地址时,其值域必须在0到m-1之间
- 哈希函数计算出来的地址能均匀分布在整个空间中
- 哈希函数应该比较简单
常见哈希函数:
注意:哈希函数设计的越精妙,产生哈希冲突的可能性就越低,但是无法避免哈希冲突
在实际应用中,其实也轮不到我们来设计哈希函数...hhh😂
5.2.2 调节负载因子
负载因子的计算公式为:负载因子 = 已有键值对数量 / 散列表容量。
它表示在散列表中,当插入一个新的键值对时,可以允许的最大填充程度。
负载因子越大,散列表的填充程度越高,冲突的发生率越高。相反,负载因子越小,散列表的填充程度越低,插入和查找操作的性能可能会更好,冲突的发生率越低,但空间利用率会降低。
因为我们不能降低元素填入个数,所以我们只能扩容哈希表来降低冲突率。
当元素个数和散列表容量的比值接近或等于负载因子时,就要对哈希表进行扩容操作。
换句话说,哈希表就是以空间换取时间的一种数据结构。
Java中,定义的负载因子大小为0.75。
5.3 冲突-解决
我们知道,冲突的发生是必然的,那么,当冲突发生后,我们该如何做呢?
解决哈希冲突两种常见的方法是:闭散列和开散列。
5.3.1 闭散列
闭散列:也叫开放定址法,当发生哈希冲突时,如果哈希表未被装满,说明在哈希表中必然还有空位置,那么可以把key存放到冲突位置中的"下一个"空位置中去。
找"下一个”"空位置,有两种方法:
- 线性探测法:从发生冲突的位置开始,依次向后探测,直到寻找到下一个空位置为止。(线性探测的缺陷是产生冲突的数据堆积在一块)
- 二次探测法:采用移动数值的平方次来找空位置。例如:如果键15的哈希值对应的空间已经被占用,算法可能会尝试使用平方数序列(如1^2, -1^2, 2^2, -2^2, ...)来计算新的哈希值,直到找到一个空位置为止。这种方法有助于避免哈希表中数据的聚集,提高哈希表的性能和数据的均匀分布。
5.3.2 🌟开散列/哈希桶/开链法
开散列法又叫链地址法(开链法),首先对关键码集合用散列函数计算散列地址,具有相同地址的关键码归于同一子集合,每一个子集合称为一个桶,各个桶中的元素通过一个单链表链接起来,各链表的头结点存储在哈希表中。
拉链法解决冲突的特点:
- 将所有关键字为同义词的结点链接在同一个单链表中。
- 拉链法处理冲突简单,且无堆积现象,即非同义词决不会发生冲突,因此平均查找长度较短。
即 数组+链表模式:
也就是说,开散列中每个桶中放的都是发生哈希冲突的元素。
HashMap采用的就是开散列法解决冲突。
但是当冲突严重时,链表的长度就会过于长,这样会影响搜索性能,
在Java中,当 数组长度超过64 && 链表长度超过8 ,链表就会转化为红黑树。
5.4 HashMap&HashSet
5.4.1 hashCode与equals方法
- hashCode方法的作用是生成哈希值,通过哈希值计算出key在数组中的位置下标。
- equals方法的作用是判断,两个key的内容是否相等。
例如:在使用put或者getValue方法时,通过hashCode找到元素的位置下标后,还需要使用equals方法一个一个的和链表中的元素比较,找到该元素在链表中的具体位置,若equals为true,说明找到了该元素。
故:当哈希表中的key为自定义类时,一定要重写equals和hashCode方法!!!
注意:
- 若两个key通过equals比较结果为true,说明两个key的内容相同,说明通过hashCode得到的哈希值一定是相等的;
- 但是,若两个key 通过hashCode得到的哈希值相等,那么只能说明这两个key在数组中的位置是相同的,不能说明两个key的内容相同,也就是说equals可能为true也可能为flase。
总结:如果equals为true,那么hashCode出的哈希值一定相等; 如果hashCode出的哈希值相等,那么equals不一定为true!!!
5.5 性能分析
虽然哈希表一直在和冲突做斗争,但在实际使用过程中,我们认为哈希表的冲突率是不高的,冲突个数是可控的, 也就是每个桶中的链表的长度是一个常数,所以,通常意义下,我们认为哈希表的插入/删除/查找时间复杂度是 O(1) 。
5.6 总结
- HashMap 和 HashSet 即 java 中利用哈希表实现的 Map 和 Set
- HashMap 和 HashSet 中使用的是 哈希桶/开散列 方式解决冲突的
- java 会在冲突链表长度大于一定阈值后,将链表转变为搜索树(红黑树)
- java 中计算哈希值实际上是调用的类的 hashCode 方法,进行 key 的相等性比较是调用 key 的 equals 方法。所以如果要用自定义类作 HashMap 的key值或者 HashSet 的key值,必须重写 hashCode 和 equals 方法。
- equals 相等的对象,hashCode 一定是一致的。
- hashCode一致,equals不一定相等。
- HashMap和HashSet不涉及元素之间的比较,所以不用像TreeMap或TreeSet具备可比较功能。
相关文章:

数据结构(Java):Map集合Set集合哈希表
目录 1、介绍 1.1 Map和Set 1.2 模型 2、Map集合 2.1 Map集合说明 2.2 Map.Entry<K,V> 2.3 Map常用方法 2.4 Map注意事项及实现类 3、Set集合 3.1 Set集合说明 3.2 Set常用方法 3.3 Set注意事项及其实现类 4、TreeMap&TreeSet 4.1 集合类TreeM…...
网络战时代的国家安全:策略、技术和国际合作
网络战时代的国家安全涉及到策略、技术和国际合作等多个方面。以下是对这些问题的简要概述: 网络战策略 网络战策略是指在现代战争中,通过网络技术进行的信息收集、处理、分析、调度和指挥等一系列行动,旨在同时影响和干扰对方的网络系统&am…...
【elasticsearch实现优先展示连词并按某个字段折叠显示最新一条】
elasticsearch实现优先展示连词并按某个字段折叠显示最新一条 前言match_phrase 顺序前缀 boost 权重collapse 折叠基本用法高级功能排序 前言 场景要求: 优先展示关键词连词的商品按照某个字段折叠相同字段,并按指定排序字段选择第一个 match_phras…...

Golang | Leetcode Golang题解之第284题窥视迭代器
题目: 题解: type PeekingIterator struct {iter *Iterator_hasNext bool_next int }func Constructor(iter *Iterator) *PeekingIterator {return &PeekingIterator{iter, iter.hasNext(), iter.next()} }func (it *PeekingIterator) hasNe…...

C语言中的结构体
文章目录 前言一、结构体是什么?二、结构体的定义三、结构体的初始化四、结构体的嵌套五、结构体数组 1结构体数组的定义:六、结构体指针 一、结构体是什么? 我们知道一群类型相同的数据组合到一起是数组,那一群不同类型的数据组…...

3.qml与c++模块化开发
目录 模块化开发封装c模块并使用封装qml模块并使用 模块化开发 什么是模块化开发呢? 举个例子: 我们有一台台式电脑,我们台式电脑有显卡,内存,磁盘,cpu,键盘,鼠标等 你可以将这些部…...

怎么使用github上传XXX内所有文件
要将 目录中的所有文件上传到 GitHub,你可以按照以下步骤进行: 创建一个新的 GitHub 仓库 登录到你的 GitHub 账户。 点击右上角的加号(),选择 “New repository”。 输入仓库名称(例如:202407…...

合作伙伴中心Partner Center中添加了Copilot预览版
目录 一、引言 二、Copilot 功能概述 2.1 Copilot 简介 2.2 Copilot 的核心功能 2.3 Copilot 的访问和使用 三、Copilot 的使用方法 3.1 Copilot 功能区域 3.2 Copilot 使用示例 3.2.1 编写有效提示 3.2.2 使用反馈循环 四、负责任的人工智能 4.1 Copilot 结果的可…...

Navidrome音乐服务器 + 音流APP = 释放你的手机空间
20240727 By wdhuag 目录 前言: 参考: Navidrome音乐服务器 Demo试用: 支持多平台: 下载: 修改配置: 设置用NSSM成服务启动: 服务器本地访问网址: 音流 歌词封面API&am…...

Prometheus安装部署
文章目录 1.Prometheus(普罗米修斯)安装部署1.1部署环境准备1.2部署prometheus1.3主机数据展示 2.Grafana安装部署2.1部署Grafana2.2配置Grafana数据源2.2配置Grafana仪表板 3.AlertManager安装部署3.1部署alertmanager3.2告警邮件发送配置3.3测试邮件告警效果3.4自定义邮件告警…...
算法(查找算法---二分查找/索引查找/哈希表查找)
二、查找算法 什么是查找算法: 在一个数据序列中,查找某个数据是否存在或存在的位置,在实际开发过程中使用的频率非常高,例如对数据常见的操作有增、删、改、查,增加数据时需要查询新增加的数据是否重复,…...

SQL labs-SQL注入(二)
环境搭建参考 SQL注入(一) 一,SQL labs-less2。 http://192.168.61.206:8001/Less-2/?id-1 union select 1,2,group_concat(username , password) from users-- 与第一关没什么太大的不同,唯一区别就是闭合方式为数字型。 二…...
go 语言踏出第一步
1、下载Go语言安装包:在官方网站(https://golang.org/dl/)上下载适合你操作系统的Go语言安装包。选择一个tar.gz格式的包。 2、解压安装包:打开终端,进入下载目录,并使用以下命令解压安装包: ta…...

SpringBoot-21 SpringBoot微服务的发布与部署(3种方式)
基于 SpringBoot 的微服务开发完成之后,现在到了把它们发布并部署到相应的环境去运行的时候了。 SpringBoot 框架只提供了一套基于可执行 jar 包(executable jar)格式的标准发布形式,但并没有对部署做过多的界定,而且为…...
在occluded Person Re-ID中,选择clip还是ViT作为backbone?
在遮挡行人再识别(Occluded Person Re-Identification, Occluded Person Re-ID)任务中,使用CLIP(Contrastive Language-Image Pre-Training)作为backbone和使用Vision Transformer(ViT)作为back…...

Linuxnat网络配置
📑打牌 : da pai ge的个人主页 🌤️个人专栏 : da pai ge的博客专栏 ☁️宝剑锋从磨砺出,梅花香自苦寒来 ☁️运维工程师的职责:监…...

77.WEB渗透测试-信息收集-框架组件识别利用(1)
免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 内容参考于: 易锦网校会员专享课 上一个内容:76.WEB渗透测试-信息收集- WAF、框架组件识别(16) javaÿ…...
ExcelJS:轻松实现Excel文件的读取、操作与写入
文章目录 发现宝藏1. 简介2. 安装3. 创建工作簿4. 设置工作簿属性5. 添加工作表6.删除工作表7.访问工作表8. 列操作9. 行操作10. 单元格操作 发现宝藏 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【宝…...
Java 多线程技术详解
文章目录 Java 多线程技术详解目录引言多线程的概念为什么使用多线程?多线程的特征多线程的挑战 多线程的实现方式3.1 继承 Thread 类示例代码: 3.2 实现 Runnable 接口示例代码: 3.3 使用 Executor 框架示例代码: 3.4 使用 Calla…...
一份简单实用的MATLAB M语言编码风格指南
MATLAB M语言编码风格指南 1. 文件命名2. 函数命名3. 注释4. 变量命名5. 布局、注释和文档6. 代码结构7. 错误处理8. 性能优化9. 格式化输出 MATLAB M文件的编码规范对于确保代码的可读性、可维护性和一致性非常重要。下面是一份MATLAB M语言编码规范的建议,可以作为…...

XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

面向无人机海岸带生态系统监测的语义分割基准数据集
描述:海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而,目前该领域仍面临一个挑战,即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
比较数据迁移后MySQL数据库和OceanBase数据仓库中的表
设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...