content: package com.allen.moments.v2.redis;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.data.redis.core.RedisTemplate;
  import org.springframework.data.redis.core.ZSetOperations;
  import org.springframework.stereotype.Component;
  import org.springframework.util.CollectionUtils;
  
  import java.util.*;
  import java.util.concurrent.TimeUnit;
  
  @Component
  public final class RedisUtil {
  
      @Autowired
      private RedisTemplate<String, Object> redisTemplate;
  
      // =============================Common============================
  
      /**
       * set the expiration time of a key
       *
       * @param key  key
       * @param time time in second
       */
      public void expire(String key, long time) {
          try {
              if (time > 0) {
                  redisTemplate.expire(key, time, TimeUnit.SECONDS);
              }
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  
      /**
       * get expiration time of a key
       *
       * @param key not null
       * @return expiration time in seconds
       */
      public long getExpire(String key) {
          return redisTemplate.getExpire(key, TimeUnit.SECONDS);
      }
  
      /**
       * check if a key exists
       *
       * @return true if exists, false otherwise;
       */
      public Boolean hasKey(String key) {
          try {
              return redisTemplate.hasKey(key);
          } catch (Exception e) {
              e.printStackTrace();
              return false;
          }
      }
  
      /**
       * delete key
       *
       * @param key could be one or multiple keys
       *            whether operation is success or not
       */
      @SuppressWarnings("unchecked")
      public void deleteKey(String... key) {
          if (key != null && key.length > 0) {
              if (key.length == 1) {
                  redisTemplate.delete(key[0]);
              } else {
                  redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
              }
          }
      }
  
      // ============================String=============================
  
      /**
       * get value
       *
       * @return value
       */
      public Object get(String key) {
          return key == null ? null : redisTemplate.opsForValue().get(key);
      }
  
  
      public boolean set(String key, Object value) {
          try {
              redisTemplate.opsForValue().set(key, value);
              return true;
          } catch (Exception e) {
              e.printStackTrace();
              return false;
          }
      }
  
      /**
       * set key and value with expiration time
       *
       * @param time expiration time in seconds, -1 for no expiration
       * @return true if success false otherwise
       */
      public boolean set(String key, Object value, long time) {
          try {
              if (time > 0) {
                  redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
              } else {
                  set(key, value);
              }
              return true;
          } catch (Exception e) {
              e.printStackTrace();
              return false;
          }
      }
  
      /**
       * increase a key's value by certain number
       *
       * @param delta the number to add to the key's value
       */
      public Long incr(String key, long delta) {
          if (delta < 0) {
              throw new RuntimeException("delta must be greater or equal to than zero");
          }
          return redisTemplate.opsForValue().increment(key, delta);
      }
  
      /**
       * decrease a key's value by certain number
       *
       * @param delta the number to minus from the key's value
       */
      public long decr(String key, long delta) {
          if (delta < 0) {
              throw new RuntimeException("delta must be greater or equal to than zero");
          }
          return redisTemplate.opsForValue().increment(key, -delta);
      }
  
      // ================================Map=================================
  
      /**
       * HashGet
       *
       * @param key  not null
       * @param item not null
       */
      public Object hashGet(String key, String item) {
          return redisTemplate.opsForHash().get(key, item);
      }
  
      public Map<Object, Object> hashGetAll(String key) {
          return redisTemplate.opsForHash().entries(key);
      }
  
  
      public boolean hashMSet(String key, Map<String, Object> map) {
          try {
              redisTemplate.opsForHash().putAll(key, map);
              return true;
          } catch (Exception e) {
              e.printStackTrace();
              return false;
          }
      }
  
      /**
       * @param time expiration time
       * @return true if success false otherwise
       */
      public boolean hashMSetWithExpiration(String key, Map<String, Object> map, long time) {
          try {
              redisTemplate.opsForHash().putAll(key, map);
              if (time > 0) {
                  expire(key, time);
              }
              return true;
          } catch (Exception e) {
              e.printStackTrace();
              return false;
          }
      }
  
  
      public boolean hashSet(String key, String item, Object value) {
          try {
              redisTemplate.opsForHash().put(key, item, value);
              return true;
          } catch (Exception e) {
              e.printStackTrace();
              return false;
          }
      }
  
      public boolean hashSetWithExpiration(String key, String item, Object value, long time) {
          try {
              redisTemplate.opsForHash().put(key, item, value);
              if (time > 0) {
                  expire(key, time);
              }
              return true;
          } catch (Exception e) {
              e.printStackTrace();
              return false;
          }
      }
  
      /**
       * delete item(s) from hashset
       *
       * @param item could be one or multiple items
       */
      public void hashDelete(String key, Object... item) {
          redisTemplate.opsForHash().delete(key, item);
      }
  
  
      public boolean hashHasKey(String key, String item) {
          return redisTemplate.opsForHash().hasKey(key, item);
      }
  
  
      public double hashIncr(String key, String item, double delta) {
          return redisTemplate.opsForHash().increment(key, item, delta);
      }
  
  
      public double hashDecr(String key, String item, double delta) {
          return redisTemplate.opsForHash().increment(key, item, -delta);
      }
  
      // ============================set=============================
  
  
      public Set<Object> setGetAll(String key) {
          try {
              return redisTemplate.opsForSet().members(key);
          } catch (Exception e) {
              e.printStackTrace();
              return null;
          }
      }
  
  
      public Boolean setHasKey(String key, Object value) {
          try {
              return redisTemplate.opsForSet().isMember(key, value);
          } catch (Exception e) {
              e.printStackTrace();
              return false;
          }
      }
  
  
      public Long setSet(String key, Object... values) {
          try {
              return redisTemplate.opsForSet().add(key, values);
          } catch (Exception e) {
              e.printStackTrace();
              return 0L;
          }
      }
  
  
      public Long setSetWithExpiration(String key, long time, Object... values) {
          try {
              Long count = redisTemplate.opsForSet().add(key, values);
              if (time > 0) {
                  expire(key, time);
              }
              return count;
          } catch (Exception e) {
              e.printStackTrace();
              return 0L;
          }
      }
  
  
      public Long setGetSize(String key) {
          try {
              return redisTemplate.opsForSet().size(key);
          } catch (Exception e) {
              e.printStackTrace();
              return 0L;
          }
      }
  
  
      public void setRemove(String key, Object... values) {
          try {
              redisTemplate.opsForSet().remove(key, values);
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  
  
      public Object sRandomMember(String key) {
          return  redisTemplate.opsForSet().randomMember(key);
      }
  
  
      public List<Object> sRandomMembers(String key, long count) {
          return redisTemplate.opsForSet().randomMembers(key, count);
      }
  
      // ===============================list=================================
  
  
      public List<Object> listGet(String key, long start, long end) {
          try {
              return redisTemplate.opsForList().range(key, start, end);
          } catch (Exception e) {
              e.printStackTrace();
              return null;
          }
      }
  
  
      public long listGetSize(String key) {
          try {
              return redisTemplate.opsForList().size(key);
          } catch (Exception e) {
              e.printStackTrace();
              return 0;
          }
      }
  
  
      public Object listGetByIndex(String key, long index) {
          try {
              return redisTemplate.opsForList().index(key, index);
          } catch (Exception e) {
              e.printStackTrace();
              return null;
          }
      }
  
  
      public boolean listSet(String key, Object value) {
          try {
              redisTemplate.opsForList().rightPush(key, value);
              return true;
          } catch (Exception e) {
              e.printStackTrace();
              return false;
          }
      }
  
  
      public boolean listSetWithExpiration(String key, Object value, long ttl) {
          try {
              redisTemplate.opsForList().rightPush(key, value);
              if (ttl > 0) {
                  expire(key, ttl);
              }
              return true;
          } catch (Exception e) {
              e.printStackTrace();
              return false;
          }
      }
  
  
      public boolean listMSet(String key, List<Object> value) {
          try {
              redisTemplate.opsForList().rightPushAll(key, value);
              return true;
          } catch (Exception e) {
              e.printStackTrace();
              return false;
          }
      }
  
  
      public boolean listMSetWithExpiration(String key, List<Object> value, long time) {
          try {
              redisTemplate.opsForList().rightPushAll(key, value);
              if (time > 0) {
                  expire(key, time);
              }
              return true;
          } catch (Exception e) {
              e.printStackTrace();
              return false;
          }
      }
  
  
      public boolean listUpdateByIndex(String key, long index, Object value) {
          try {
              redisTemplate.opsForList().set(key, index, value);
              return true;
          } catch (Exception e) {
              e.printStackTrace();
              return false;
          }
      }
  
  
      public Long listRemove(String key, long count, Object value) {
          try {
              return redisTemplate.opsForList().remove(key, count, value);
          } catch (Exception e) {
              e.printStackTrace();
              return 0L;
          }
  
      }
  
      // ======================================== bitmap ========================================
      /**
       * @return whether operation is success or not
       */
      public boolean bitGet(String key, int offset) {
          try {
              return redisTemplate.opsForValue().getBit(key, offset);
          } catch (Exception exception) {
              exception.printStackTrace();
              return false;
          }
      }
  
      /**
       * @return whether operation is success or not
       */
      public boolean bitSet(String key, int offset, boolean value) {
          try {
              redisTemplate.opsForValue().setBit(key, offset, value);
              return true;
          } catch (Exception exception) {
              exception.printStackTrace();
              return false;
          }
      }
  
  
  
      // ================================== zSet ==========================================
      public Boolean zAdd(String key, String value, double score) {
          return redisTemplate.opsForZSet().add(key, value, score);
      }
  
  
      public Long zAdd(String key, Set<ZSetOperations.TypedTuple<Object>> values) {
          return redisTemplate.opsForZSet().add(key, values);
      }
  
  
      public Long zRemove(String key, Object... values) {
          return redisTemplate.opsForZSet().remove(key, values);
      }
  
  
      public Double zIncrementScore(String key, String value, double delta) {
          return redisTemplate.opsForZSet().incrementScore(key, value, delta);
      }
  
  
      public Long zRank(String key, Object value) {
          return redisTemplate.opsForZSet().rank(key, value);
      }
  
  
      public Long zReverseRank(String key, Object value) {
          return redisTemplate.opsForZSet().reverseRank(key, value);
      }
  
  
      public Set<Object> zRange(String key, long start, long end) {
          return redisTemplate.opsForZSet().range(key, start, end);
      }
  
  
      public Set<ZSetOperations.TypedTuple<Object>> zRangeWithScores(String key, long start,
                                                                     long end) {
          return redisTemplate.opsForZSet().rangeWithScores(key, start, end);
      }
  
  
      public Set<Object> zRangeByScore(String key, double min, double max) {
          return redisTemplate.opsForZSet().rangeByScore(key, min, max);
      }
  
  
  
      public Long zSize(String key) {
          return redisTemplate.opsForZSet().size(key);
      }
  
  
  
      public Double zScore(String key, Object value) {
          return redisTemplate.opsForZSet().score(key, value);
      }
  
      public Long zRemoveRange(String key, long start, long end) {
          return redisTemplate.opsForZSet().removeRange(key, start, end);
      }
  
      public Long zRemoveRangeByScore(String key, double min, double max) {
          return redisTemplate.opsForZSet().removeRangeByScore(key, min, max);
      }
  
      // ======================================== operations about multiple items ========================================
  
      public Collection<Object> mGet(Collection<String> keys) {
          return redisTemplate.opsForValue().multiGet(keys);
      }
  
      public void mSet(Map<String, Object> kvs) {
          redisTemplate.opsForValue().multiSet(kvs);
      }
  
  
  
  
  
  }
  
  