Detailed Explanation of Several Realization Methods of java Fixed Size Queue
- 2021-10-27 07:29:42
- OfStack
EvictingQueue based on Guava
list Operation Based on Redis
Summarize
Preface
Recently, some students in the team encountered a demand during development, counted the last 10 abnormal times, and consulted whether there was a similar list. To solve this problem, record 1 several processing methods.
Based on FixedLinkedHashMap in Hutool
Introducing maven dependency
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.0</version>
</dependency>
Use sample
// Specify size at initialization
private final FixedLinkedHashMap<String, Integer> fixedLinkedHashMap = new FixedLinkedHashMap<>(LIST_SIZE);
// The remaining write and read operations are the same as LinkedHashMap Similar
// For key Which can be filled out according to your own business requirements
fixedLinkedHashMap.put(UUID.randomUUID().toString(), 1);
// Read operation
// Get the number of elements
long size = fixedLinkedHashMap.values().size();
// Count the sum of them
int sum = fixedLinkedHashMap.values().stream().mapToInt(value -> value).sum();
EvictingQueue based on Guava
Introducing maven dependency
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>30.1.1-jre</version>
</dependency>
Use sample
// Specify size at initialization
private final EvictingQueue<Integer> evictingQueue = EvictingQueue.create(LIST_SIZE);
// Add Element
evictingQueue.add(MOCK_EXCEPTION_COUNT);
// Read element
// Number of elements
size = evictingQueue.size();
// Count the sum of them
sum = evictingQueue.stream().mapToInt(value -> value).sum();
Note: With the introduction of the latest guava version 30.1.1-jre (2021-07-12), the EvictingQueue class is still marked @ Beta.
list Operation Based on Redis
The example uses RedisTemplate in an SpringBoot application.
Three operations mainly based on Redis list.
LPUSH: Insert Element into Header LTRIM: Crop the list to specify the starting position LRANGE: Gets the elements in the specified range of the listIntroducing maven dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
Use sample
// Initialization RedisTemplate
@Resource
private RedisTemplate<String, Integer> redisTemplate;
ListOperations<String, Integer> stringIntegerListOperations = redisTemplate.opsForList();
// LPUSH Operation
stringIntegerListOperations.leftPush(REDIS_LIST_KEY, MOCK_EXCEPTION_COUNT);
// LTRIM
stringIntegerListOperations.trim(REDIS_LIST_KEY, 0, LIST_SIZE - 1);
// LRANGE Operation
List<Integer> range = stringIntegerListOperations.range(REDIS_LIST_KEY, 0, LIST_SIZE - 1);
// Operate on the result
size = range.size();
sum = range.stream().mapToInt(value -> value).sum();
Complete example
@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);
}
}
}
The log after the program starts for 1 period of time can be seen to meet the requirements.
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
Summarize
All the above three methods can realize list with fixed length. FixedLinkedHashMap and EvictingQueue are memory-based, so only node cases are supported. list based on Redis can also be used in distributed situation except single node situation.