Spring中使用Redis之有序集合类型

本文深入讲解Redis有序集合的特性及基本命令,包括zadd、zcard等,同时演示如何在Spring环境中配置并操作有序集合,提供了详细的代码示例。

一、Redis有序集合简介
有序集合和集合类似,只是说它的有序的,和无序集合的主要区别在于每一个元素除了值以外,它还会多一个分数。分数是一个浮点数,在Java中是使用双精度来表示的,根据分数,Redis就可以支持对分数从小到大或者从大到小到排序。这里和无序集合一样,对于每一个元素都是唯一到,但是对于不同元素而言,它的分数可以是一样的。元素也String数据类型,也是一种基于Hash的存储结构。集合是通过哈希来实现的,所以添加、删除、查找的复杂度都是O(1),集合中最大的成员数量为40多亿个。有序集合依赖key来标识它是属于哪一个集合,依赖分数进行排序,所以值和分数是必须的,而实际上不仅可以对分数进行排序,在一定条件下,可以对值进行排序。

二、有序集合的基本命令
【1】zadd key score1 value1 [ score2 value2 …],功能:向有序集合的key,添加一个或者多个成员,如果不存在对应的key,则创建键为key的有序集合。
【2】zcard key,功能:获取有序集合的成员数。
【3】zcount key min max,功能:根据负数返回对应的成员数量,min为最小值,max为最大值,默认包含min和max,采用数学区间表示的方法,如果需要“不包含”,则在分数前加入"(",注意不支持"[“表示。
【4】zincrby key increment member,功能:给有序集合成员值为member的分数增加increment分数。
【5】zinterstore desKey countKeys key1 [key2 key3 …],功能:求多个有序集合的交集,并且将结果保存到desKey中,countKeys 是一个整数,表示又多少个有序集合数量。
【6】zlexcount key min max,功能:求有序集合成员的值在min到max的范围,返回一个整数,采用数学区间表示的方法,如果需要“不包含”,则在分数前加入”(","[“表示包含该值,则在分数前面加入”["。
【7】zrangekey start stop [withscores] ,功能:按照分值的大小(从小到大)返回成员,加入start和stop参数可以截取某一段返回,如果输入withscores,则连同分数一起返回。
【8】zrank key member,功能:按照从小到大求有序集合的排行,排名第一的为0,第二的为1…以此类推。
【9】zrangebylex key min max [limit offset count],功能:根据值的大小,从小到大排序,min为最小值,max为最大值;limit为可选项,当Redis求出范围集合后,会产生下标0-n,然后根据偏移量offset和限定返回值数量count,来返回对应的成员。
【10】zrangebyscore key min max [ withscores ] 【limit offset count】,功能:根据分数的大小,从小到大获取范围,选项withscores和limit参考zrange命令和zrangebylex。
【11】zremrangebyscore key start stop,根据分数区间进行删除,按照score进行排序,然后排除0到len-1的下标,然后再根据start和stop进行删除。
【12】zremrangebyrank key start stop,功能:按照分数排行从小到大进行删除,从0开始计算。
【13】zremrangebylex key min max,功能:按照值的分布进行删除。
【14】zrevrange key start stop [withscores],功能:从小到大按分数进行排序,参数参照zrange,但是这个排序是从大到小。
【15】zrevrangebyscore key max min [withscores],功能:从大到小按照分数进行排序,参数参照zrangebyscore。
【16】zrevrank key member,功能:按照从大到小的顺序,对元素进行排行,排名第一为0,第二为1…以此类推。
【17】zscore key member,功能:返回成员的分数值,即返回成员的分数。
【18】zunionstore desKey countkeys key1 [key2 key3 …],功能:求多喝有序集合的并集,其中countkeys是有序集合的个数。

三、Spring中使用Redis操作有序集合类型

步骤一:创建Maven项目,在pom.xml文件中导入一下三个依赖。

     <dependencies>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-nop</artifactId>
            <version>1.7.2</version>
        </dependency>
        <!-- 导入Spring中的redis依赖 -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
            <version>2.1.6.RELEASE</version>
        </dependency>
        <!-- 导入jedis依赖 -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.1</version>
        </dependency>
    </dependencies>

步骤二:在applicationContext.xml文件中配置Redis。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- Jedis 的连接池配置 -->
    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <!-- 最大空闲连接数量-->
        <property name="maxIdle" value="50"/>
        <!-- 最大连接数量-->
        <property name="maxTotal" value="100"/>
        <!-- 最大等待时间-->
        <property name="maxWaitMillis" value="20000"/>
    </bean>

    <bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/>

    <!-- Redis服务中心-->
    <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <property name="hostName" value="localhost"/>
        <property name="port" value="6379"/>
        <property name="poolConfig" ref="poolConfig"/>
    </bean>

    <!-- Redis模板类-->
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory" ref="connectionFactory"/>
        <property name="defaultSerializer" ref="stringRedisSerializer"/>
        <property name="valueSerializer" ref="stringRedisSerializer"/>
    </bean>
</beans>

步骤三:创建一个RedisOrderSetDemo类,使用Spring测试Redis链表操作,如下所示:

package demo;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.redis.connection.RedisZSetCommands;
import org.springframework.data.redis.connection.SortParameters;
import org.springframework.data.redis.core.DefaultTypedTuple;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;

import java.util.HashSet;
import java.util.Set;

/**
 * @author czd
 */
public class RedisOrderSetDemo {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        RedisTemplate redisTemplate = applicationContext.getBean(RedisTemplate.class);

        //Spring提供接口TypeTuple操作有序集合
        Set<ZSetOperations.TypedTuple> set1 = new HashSet<>();
        Set<ZSetOperations.TypedTuple> set2 = new HashSet<>();

        //计算分数和值
        int j = 9;
        for (int i = 1; i <= 9; i++) {
            double score1 = Double.valueOf(i);
            String value1 = "x" + i;
            double score2 = Double.valueOf(j);
            String value2 = j % 2 == 1 ? "y" + j : "x" + j;

            //使用Spring提供的默认TypedTuple——DefaultTypedTuple
            ZSetOperations.TypedTuple typedTuple1 = new DefaultTypedTuple(value1, score1);
            ZSetOperations.TypedTuple typedTuple2 = new DefaultTypedTuple(value2, score2);
            set1.add(typedTuple1);
            set2.add(typedTuple2);
        }

        //将元素插入有序集合zset1,相当于zadd key score1 value1 [ score2 value2 …]
        redisTemplate.opsForZSet().add("zset1", set1);
        redisTemplate.opsForZSet().add("zset2", set2);

        Long size = null;
        //统计有序集合的总数,相当于zcard key
        size = redisTemplate.opsForZSet().zCard("zset1");
        System.out.println("zset1中的元素个数是:" + size);

        //求分数3-6的元素个数,相当于zcount key min max
        size = redisTemplate.opsForZSet().count("zset1", 3, 6);
        System.out.println("求分数3-6的元素个数:" + size);

        Set set = null;
        //从下标1开始截取5个元素,但是不返回分数,相当于zrangekey start stop
        set = redisTemplate.opsForZSet().range("zset1", 1, 5);

        //截取集合全部元素,返回分数,相当于zrangekey start stop [withscores]
        set = redisTemplate.opsForZSet().rangeWithScores("zset1", 0, -1);

        //将zset1和zset2两个集合的交集放入到集合inter_zset中,相当于zinterstore desKey countKeys key1 [key2 key3 …]
        redisTemplate.opsForZSet().intersectAndStore("zset1", "zset2", "inter_zset");

        //使用Spring提供的Range区间
        RedisZSetCommands.Range range = RedisZSetCommands.Range.range();
        //小于
//        range.lt("x8");
//        //大于
//        range.gt("x1");
        //返回大于x1小于x8的集合,相当于zrangebylex key min max
//        set = redisTemplate.opsForZSet().rangeByLex("zset1", range);

        //小于等于
//        range.lte("x8");
        //大于等于
//        range.gte("x1");
        //返回大于等于x1小于等于x8的集合
//        set = redisTemplate.opsForZSet().rangeByLex("zset1", range);

        //限制返回个数
        RedisZSetCommands.Limit limit = RedisZSetCommands.Limit.limit();
        limit.count(4);

        //求大于等于x1小于等于x8,并且限制返回4个元素的集合,相当于zrangebylex key min max [limit offset count]
//        set = redisTemplate.opsForZSet().rangeByLex("zset1", range, limit);

        //求排行,排名第1返回0,第2返回1,以此类推,相当于zrank key member
        Long rank = redisTemplate.opsForZSet().rank("zset1","x4");
        System.out.println("x4的排名为:" + rank);

        //删除元素,返回删除个数
        size = redisTemplate.opsForZSet().remove("zset1","x5","x6");
        System.out.println("删除个数:" + size);

        //按照排行从0开始算起,删除排名第2和第3的元素,相当于zremrangebyrank key start stop
        redisTemplate.opsForZSet().removeRange("zset1",1,2);

        //获取集合的全部元素,-1代表全部元素,相当于zrangekey start stop [withscores]
        set = redisTemplate.opsForZSet().rangeWithScores("zset1",0,-1);

        //给集合中的一个元素的分数加上11,相当于zincrby key increment member
        redisTemplate.opsForZSet().incrementScore("zset1","x1",11);

        //从大到小按分数进行排序,获取下标1到10的元素,并且带分数,相当于zrevrange key start stop [withscores]
        set = redisTemplate.opsForZSet().reverseRangeByScoreWithScores("zset1",1,10);

    }
}

运行效果如下所示:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值