java固定大小队列的几种实现方式详解

队列的特点是节点的排队次序和出队次序按入队时间先后确定,即先入队者先出队,后入队者后出队,这篇文章主要给大家介绍了关于java固定大小队列的几种实现方式,需要的朋友可以参考下

前言

最近团队有同学在开发中,遇到一个需求,统计最近10次的异常次数,咨询有没有类似的list。针对这个问题,记录一下几种处理方式。

基于Hutool中的FixedLinkedHashMap

引入maven依赖

  cn.hutoolhutool-all5.4.0

使用示例

 // 初始化时指定大小 private final FixedLinkedHashMap fixedLinkedHashMap = new FixedLinkedHashMap<>(LIST_SIZE); // 其余写入和读取操作同LinkedHashMap类似 // 对于key,可以按照自己的业务需求填写 fixedLinkedHashMap.put(UUID.randomUUID().toString(), 1); // 读取操作 // 获取元素个数 long size = fixedLinkedHashMap.values().size(); // 统计其中的总和 int sum = fixedLinkedHashMap.values().stream().mapToInt(value -> value).sum(); 

基于Guava的EvictingQueue

引入maven依赖

  com.google.guavaguava30.1.1-jre

使用示例

 // 初始化时指定大小 private final EvictingQueue evictingQueue = EvictingQueue.create(LIST_SIZE); // 添加元素 evictingQueue.add(MOCK_EXCEPTION_COUNT); // 读取元素 // 元素个数 size = evictingQueue.size(); // 统计其中的和 sum = evictingQueue.stream().mapToInt(value -> value).sum(); 

注意: 引入了目前(2021-07-12)最新的guava版本30.1.1-jre,EvictingQueue类还是标记了@Beta。

基于Redis的list操作

示例在SpringBoot应用中,使用RedisTemplate。

主要基于Redis列表的三个操作。

  1. LPUSH:将元素插入头部
  2. LTRIM: 对列表进行裁剪,可以指定起始位置
  3. LRANGE: 获取列表指定范围内的元素

引入maven依赖

  org.springframework.bootspring-boot-starter-data-redis

使用示例

 // 初始化RedisTemplate @Resource private RedisTemplate redisTemplate; ListOperations stringIntegerListOperations = redisTemplate.opsForList(); // LPUSH操作 stringIntegerListOperations.leftPush(REDIS_LIST_KEY, MOCK_EXCEPTION_COUNT); // LTRIM stringIntegerListOperations.trim(REDIS_LIST_KEY, 0, LIST_SIZE - 1); // LRANGE操作 List range = stringIntegerListOperations.range(REDIS_LIST_KEY, 0, LIST_SIZE - 1); // 对结果操作 size = range.size(); sum = range.stream().mapToInt(value -> value).sum(); 

完整示例

 @Service @Slf4j public class FixedListScheduler { private static final int LIST_SIZE = 10; private static final int MOCK_EXCEPTION_COUNT = 1; private static final String REDIS_LIST_KEY = "redis_fixed_list"; private final FixedLinkedHashMap fixedLinkedHashMap = new FixedLinkedHashMap<>(LIST_SIZE); private final EvictingQueue evictingQueue = EvictingQueue.create(LIST_SIZE); @Resource private RedisTemplate redisTemplate; @Scheduled(cron = "*/1 * * * * ?") public void schedule() { fixedLinkedHashMap.put(UUID.randomUUID().toString(), MOCK_EXCEPTION_COUNT); long size = fixedLinkedHashMap.values().size(); int sum = fixedLinkedHashMap.values().stream().mapToInt(value -> value).sum(); log.info("fixedLinkedHashMap size:{}, sum:{}", size, sum); evictingQueue.add(MOCK_EXCEPTION_COUNT); size = evictingQueue.size(); sum = evictingQueue.stream().mapToInt(value -> value).sum(); log.info("evictingQueue size:{}, sum:{}", size, sum); ListOperations stringIntegerListOperations = redisTemplate.opsForList(); stringIntegerListOperations.leftPush(REDIS_LIST_KEY, MOCK_EXCEPTION_COUNT); stringIntegerListOperations.trim(REDIS_LIST_KEY, 0, LIST_SIZE - 1); List range = stringIntegerListOperations.range(REDIS_LIST_KEY, 0, LIST_SIZE - 1); if (!CollectionUtils.isEmpty(range)) { sum = range.stream().mapToInt(value -> value).sum(); log.info("redis FixedList size:{}, sum:{}", range.size(), sum); } } } 

程序启动一段时间后的日志,可以看到是满足要求的。

2021-07-12 18:35:29.006  INFO 8622 --- [pool-2-thread-1] com.yichao.myblogs.FixedListScheduler    : evictingQueue size:10, sum:10
2021-07-12 18:35:29.009  INFO 8622 --- [pool-2-thread-1] com.yichao.myblogs.FixedListScheduler    : redis FixedList size:10, sum:10
2021-07-12 18:35:30.002  INFO 8622 --- [pool-2-thread-1] com.yichao.myblogs.FixedListScheduler    : fixedLinkedHashMap size:10, sum:10
2021-07-12 18:35:30.002  INFO 8622 --- [pool-2-thread-1] com.yichao.myblogs.FixedListScheduler    : evictingQueue size:10, sum:10
2021-07-12 18:35:30.005  INFO 8622 --- [pool-2-thread-1] com.yichao.myblogs.FixedListScheduler    : redis FixedList size:10, sum:10
2021-07-12 18:35:31.005  INFO 8622 --- [pool-2-thread-1] com.yichao.myblogs.FixedListScheduler    : fixedLinkedHashMap size:10, sum:10
2021-07-12 18:35:31.005  INFO 8622 --- [pool-2-thread-1] com.yichao.myblogs.FixedListScheduler    : evictingQueue size:10, sum:10
2021-07-12 18:35:31.008  INFO 8622 --- [pool-2-thread-1] com.yichao.myblogs.FixedListScheduler    : redis FixedList size:10, sum:10
2021-07-12 18:35:32.005  INFO 8622 --- [pool-2-thread-1] com.yichao.myblogs.FixedListScheduler    : fixedLinkedHashMap size:10, sum:10
2021-07-12 18:35:32.005  INFO 8622 --- [pool-2-thread-1] com.yichao.myblogs.FixedListScheduler    : evictingQueue size:10, sum:10
2021-07-12 18:35:32.009  INFO 8622 --- [pool-2-thread-1] com.yichao.myblogs.FixedListScheduler    : redis FixedList size:10, sum:10
2021-07-12 18:35:33.002  INFO 8622 --- [pool-2-thread-1] com.yichao.myblogs.FixedListScheduler    : fixedLinkedHashMap size:10, sum:10
2021-07-12 18:35:33.002  INFO 8622 --- [pool-2-thread-1] com.yichao.myblogs.FixedListScheduler    : evictingQueue size:10, sum:10
2021-07-12 18:35:33.005  INFO 8622 --- [pool-2-thread-1] com.yichao.myblogs.FixedListScheduler    : redis FixedList size:10, sum:10

总结

以上三种方式均可实现固定长度的list。FixedLinkedHashMap和EvictingQueue是基于内存的,所以仅支持节点情况。而基于Redis的list除了单节点情况,同样可以在分布式情况使用。

到此这篇关于java固定大小队列的文章就介绍到这了,更多相关java固定大小队列内容请搜索html中文网以前的文章或继续浏览下面的相关文章希望大家以后多多支持html中文网!

以上就是java固定大小队列的几种实现方式详解的详细内容,更多请关注0133技术站其它相关文章!

赞(0) 打赏
未经允许不得转载:0133技术站首页 » Java