Detailed Explanation of Several Realization Methods of java Fixed Size Queue

  • 2021-10-27 07:29:42
  • OfStack

Directory preface is based on FixedLinkedHashMap in Hutool
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 list

Introducing 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.


Related articles: