Java怎么知道list实体修改了那些数据

Java怎么知道list实体修改了那些数据,第1张

修改了很多的
1背景在Java中,我们可以使用listremove()移除list中的特定值,但是如果需要移除所有出现的特定值,就值得研究一番了。此文将会使用多种方法来尝试解决此问题,并说明其优缺点。2方法一:使用简单循环比如我们想移除某个value,很多人会这样写:
然而,以上代码存在严重问题,例如:对于一个List类型的List,当我们调用其listremoce(int)方法时,实际移除的是index为1的值(在这个例子中是2),而不是我们想要的value为1的值。此循环将删光除了0位的所有值,并在最后一次循环中抛出越界异常。我们尝试这样修改如此就可以避免此问题但是,以上代码还有很大的优化空间,我们接着看。3方法二在上述代码中,listcontains()和listremove()方法都查找了一次首次出现的值的index,这显然是做了不必要的重复工作,我们尝试这样优化代码:这样就只需要查找一次index但这段代码仍旧拥有很大的优化空间,因为我们没有保留每次查找的进度,导致事实上每次查找都是从头开始,我们尝试继续优化。4方法三使用for循环一次遍历,保留了查找进度需要注意的是,当移除value,会导致后续index全部-1,所以我们一定要记得把index-1,否则将导致数组越界异常!5方法四使用迭代器迭代器也可以保留状态6方法五相比于不断修改原来的List,我们其实可以一次遍历的同时把值写入一个新的List,且新的List一定小于等于旧的List。对于ArrayList可以一次分配足够的空间,避免resize的 *** 作。或虽然使用了额外的存储空间,但时间复杂度大大降低,还是值得的。7方法六使用Java8引入的流 *** 作其实和方法五等效,但简单了许多8方法七使用listremoveIf()配合lambda表达式底层是迭代器实现9总结其实在实际生产中,使用最后两种方法是最方便的。对于需要大量修改的List可以使用方法六,避免多次resize和shifting的性能损失,但需要额外内存。对于只有少量修改的List可以使用方法七。

List list是声明(定义)一个List类型的变量,list= new ArrayList()是创建一个ArrayList对象(分配内存空间),
关于开辟内存空间的问题你可以这样理解,list是变量名,是对象的引用(就是指针,指向对象所在的地址,虽然java里没有了指针),它是放在栈内存的,而实际的ArrayList对象是放在堆内存的。
所以List list;是在栈里分配空间给list, list= new ArrayList();是在堆分配空间给 ArrayList对象,并将对象的地址给list list无需提前知道是ArrayList还是LinkedList,这是多态,LinkedList和ArrayList是List的子类,父类指针指向子类对象

当同时满足以下条件时,使用ziplist编码:

SpringBoot—实现n秒内出现x个异常报警

思路:
借助Redis的zSet集合,score存储的是异常时的时间戳,获取一定时间范围内的set集合。判断set个数是否满足条件,若满足条件则触发报警;

注意点:

相关API:

Redis实现延迟队列方法介绍
基于Redis实现DelayQueue延迟队列设计方案

相关API:

SpringBoot2x—使用Redis的bitmap实现布隆过滤器(Guava中BF算法)

布隆过滤器: 是专门用来检测集合中是否存在特定元素的数据结构。
存在误差率: 即将不在集合的元素误判在集合中。

所以布隆过滤器适合查询准确度要求没这么苛刻,但是对时间、空间效率比较高的场景。

实现方式:Redis实现布隆过滤器——借鉴Guava的BF算法:

SpringBoot2x中使用Redis的bitmap结构(工具类)

注意:bitmap使用存在风险,若仅仅计算hash值,会导致bitmap占用空间过大。一般需要对hash值进行取余处理。

根据Redis是否存在key,判断锁是否被获取;

锁应该是一个对象,记录持有锁的线程信息、当前重入次数。所以应该使用Redis的Hash结构来存储锁对象。

31 网络波动造成释放锁失败怎么解决?

需要为锁加上超时时间;

32 任务未执行完毕时,锁由于超时时间被释放?

线程一旦加锁成功,可以启动一个后台线程,每隔多少秒检查一次,如果线程还持有锁,可以不断延长锁的生存时间。

主从切换时,从服务器上没有加锁信息,导致多个客户端同时加锁。

list结构底层是ziplist/quicklist(可看着一个双端队列)。常用命令:

使用list作为对象的缓存池。通过rpush放入对象,通过lpop取出对象。

若是阻塞取,可以使用blpop命令实现。

Redis和Lua脚本(实现令牌桶限流)

数据结构选择hash。
hash里面维护:最后放入令牌时间、当前桶内令牌量、桶内最大数量、令牌放置速度(元数据)。

被动式维护:

命令:incr原子累加;

对一段固定时间窗口内的请求进行计数,如果请求数超过了阈值,则舍弃该请求;如果没有达到设定的阈值,则接受该请求,且计数加1。当窗口时间结束,重置计数器为0。

优点:实现简单,容易理解;
缺点:流量曲线可能不够平滑,有“突刺现象”。

1 一段时间内(不超过时间窗口)系统服务不可用。 比如窗口大小1s,限流为100,恰好某个窗口第1ms来了100个请求,然后2ms-999ms请求都会被拒绝。这段时间用户会感觉系统服务不可用(即不够平滑)。

2 窗口切换时可能会出现两倍于阈值流量的请求。 比如窗口大小1s,限流大小100,然后在某个窗口的第999ms有100个请求,窗口前期没有请求。所以这100个请求都会通过。然后下一个窗口的第1ms又来100个请求,然后全部通过。其实也是1ms内通过的200个请求。

命令:Redis的incr命令

是对固定窗口计数器的优化,解决的是切换窗口两倍阈值流量的场景。

具体解决方案是:将限流窗口分为多个小的限流窗口,各个限流窗口分别计数。当前时间大于窗口最大时间时,将头部的小窗口数据舍弃,尾部新增小窗口来处理新请求。

优点:本质上是对固定窗口的优化

相对于 list 而言,tuple 是不可变的,这使得它可以作为 dict 的 key,或者扔进 set 里,而 list 则不行。

tuple 放弃了对元素的增删(内存结构设计上变的更精简),换取的是性能上的提升:创建 tuple 比 list 要快,存储空间比 list 占用更小。所以就出现了“能用 tuple 的地方就不用 list”的说法。

多线程并发的时候,tuple 是不需要加锁的,不用担心安全问题,编写也简单多了。

元组这么受欢迎,其实最关键的一点是它的语法的灵活和便捷性,提高了编程体验。其中最大的一个特性就是使函数可以返回多个值,这个特性很常用。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/yw/13366913.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-22
下一篇 2023-07-22

发表评论

登录后才能评论

评论列表(0条)

保存