java固定大小隊列的幾種實現(xiàn)方式詳解
前言
最近團(tuán)隊有同學(xué)在開發(fā)中,遇到一個需求,統(tǒng)計最近10次的異常次數(shù),咨詢有沒有類似的list。針對這個問題,記錄一下幾種處理方式。
基于Hutool中的FixedLinkedHashMap
引入maven依賴
<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.4.0</version> </dependency>
使用示例
// 初始化時指定大小 private final FixedLinkedHashMap<String, Integer> fixedLinkedHashMap = new FixedLinkedHashMap<>(LIST_SIZE); // 其余寫入和讀取操作同LinkedHashMap類似 // 對于key,可以按照自己的業(yè)務(wù)需求填寫 fixedLinkedHashMap.put(UUID.randomUUID().toString(), 1); // 讀取操作 // 獲取元素個數(shù) long size = fixedLinkedHashMap.values().size(); // 統(tǒng)計其中的總和 int sum = fixedLinkedHashMap.values().stream().mapToInt(value -> value).sum();
基于Guava的EvictingQueue
引入maven依賴
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>30.1.1-jre</version> </dependency>
使用示例
// 初始化時指定大小 private final EvictingQueue<Integer> evictingQueue = EvictingQueue.create(LIST_SIZE); // 添加元素 evictingQueue.add(MOCK_EXCEPTION_COUNT); // 讀取元素 // 元素個數(shù) size = evictingQueue.size(); // 統(tǒng)計其中的和 sum = evictingQueue.stream().mapToInt(value -> value).sum();
注意: 引入了目前(2021-07-12)最新的guava版本30.1.1-jre,EvictingQueue類還是標(biāo)記了@Beta。
基于Redis的list操作
示例在SpringBoot應(yīng)用中,使用RedisTemplate。
主要基于Redis列表的三個操作。
- LPUSH:將元素插入頭部
- LTRIM: 對列表進(jìn)行裁剪,可以指定起始位置
- LRANGE: 獲取列表指定范圍內(nèi)的元素
引入maven依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
使用示例
// 初始化RedisTemplate @Resource private RedisTemplate<String, Integer> redisTemplate; ListOperations<String, Integer> stringIntegerListOperations = redisTemplate.opsForList(); // LPUSH操作 stringIntegerListOperations.leftPush(REDIS_LIST_KEY, MOCK_EXCEPTION_COUNT); // LTRIM stringIntegerListOperations.trim(REDIS_LIST_KEY, 0, LIST_SIZE - 1); // LRANGE操作 List<Integer> range = stringIntegerListOperations.range(REDIS_LIST_KEY, 0, LIST_SIZE - 1); // 對結(jié)果操作 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<String, Integer> fixedLinkedHashMap = new FixedLinkedHashMap<>(LIST_SIZE); private final EvictingQueue<Integer> evictingQueue = EvictingQueue.create(LIST_SIZE); @Resource private RedisTemplate<String, Integer> 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<String, Integer> stringIntegerListOperations = redisTemplate.opsForList(); stringIntegerListOperations.leftPush(REDIS_LIST_KEY, MOCK_EXCEPTION_COUNT); stringIntegerListOperations.trim(REDIS_LIST_KEY, 0, LIST_SIZE - 1); List<Integer> 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
總結(jié)
以上三種方式均可實現(xiàn)固定長度的list。FixedLinkedHashMap和EvictingQueue是基于內(nèi)存的,所以僅支持節(jié)點情況。而基于Redis的list除了單節(jié)點情況,同樣可以在分布式情況使用。
到此這篇關(guān)于java固定大小隊列的文章就介紹到這了,更多相關(guān)java固定大小隊列內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Springboot項目升級2.2.x升至2.7.x的示例代碼
本文主要介紹了Springboot項目升級2.2.x升至2.7.x的示例代碼,會有很多的坑,具有一定的參考價值,感興趣的可以了解一下2023-09-09Java定時任務(wù)schedule和scheduleAtFixedRate的異同
本文主要介紹了Java定時任務(wù)schedule和scheduleAtFixedRate的異同,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05解決springSecurity 使用默認(rèn)登陸界面登錄后無法跳轉(zhuǎn)問題
這篇文章主要介紹了解決springSecurity 使用默認(rèn)登陸界面登錄后無法跳轉(zhuǎn)問題,項目環(huán)境springboot下使用springSecurity 版本2.7.8,本文通過實例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧2023-12-12Spring ApplicationListener的使用詳解
這篇文章主要介紹了Spring ApplicationListener的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06Deepin系統(tǒng)安裝eclipse2021-03及CDT插件的安裝教程
本教程教大家deepin20.1操作系統(tǒng)上安裝eclipse_2021-03版的詳細(xì)步驟及CDT插件的安裝方法,通過圖文展示的非常明了,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2021-06-06