Redis 数据结构(二)—集合和有序集合

集合(Set)允许用户将多个各不相同的元素(文本或二进制数据)存储到集合中,以无序的方式存储元素。

有序集合(Sorted Set)同时具有"有序"和"集合"两种性质。每个元素由一个成员和分值组成。成员以字符串方式存储,而分值以64位双精度浮点数格式存储。

1 集合 Set

|-------|-----------------------------------------------------------------------------------------------------------------------------|
| 添加和移除 | SADD、SREM |
| 集合 | 移动一个元素到另一个集合:SMOVE 返回集合包含的所有元素:SMEMBERS 返回集合包含的元素数量:SCARD 检查元素是否存在于集合:SISMEMBER 随机获取集合中的元素:SRANDMEMBER 随机从集合中移除指定数量的元素:SPOP |
| 集合运算 | 交集:SINTER、SINTERSTORE 并集:SUNION、SUNIONSTORE 差集:SDIFF、SDIFFSTORE |

表 集合数据结构相关命令

1.1 示例

打标签:购物网站为商品添加标签,方便顾客了解商品的不同特性及筛选商品。

java 复制代码
public class GoodsTags {

    private final static Jedis jedis = RedisPool.getJEdis();
    private final static String GOODS_TAGS_KEY = "goods_tags_set::%s";

    public static void addTags(String goodsId,String ... tags) {
        jedis.sadd(String.format(GOODS_TAGS_KEY,goodsId),tags);
    }

    public static boolean hasTag(String goodsId,String tag) {
        return jedis.sismember(String.format(GOODS_TAGS_KEY,goodsId),tag);
    }

    public static void removeTag(String goodsId,String tag) {
        jedis.srem(String.format(GOODS_TAGS_KEY,goodsId),tag);
    }

    public static void showTags(String goodsId) {
        System.out.println(jedis.smembers(String.format(GOODS_TAGS_KEY,goodsId)));
    }

    public static void main(String[] args) {
        addTags("1","苹果","电脑","M2","办公","程序员");
        showTags("1");
        System.out.println("has 办公:" + hasTag("1","办公"));
        removeTag("1","办公");
        System.out.println("has 办公:" + hasTag("1","办公"));
    }
}

共同关注与推荐关注:在抖音上,访问某个用户的个人主页时,页面会展示出我们和这个用户都在关注的人。

除此之外,还会为用户推荐他可能感兴趣的关注对象。简单的实现算法是:从用户正在关注集合中随机选出指定数量的用户作为种子用户,然后对这些种子用户的正在关注集合执行并集计算,最后从这个并集中随机选出一些用户作为推荐关注对象。

java 复制代码
public class CommonAndRecommendUser {

    private final static Jedis jedis = RedisPool.getJEdis();
    private final static String FOLLOWING_KEY = "user_following_set:%s";
    private final static String TEMP_USER_RECOMMEND_KEY = "temp_user_recommend_set";

    public static void addFollowing(String user,String ... targetUsers) {
        String key = String.format(FOLLOWING_KEY, user);
        jedis.spop(key,999);
        jedis.sadd(key,targetUsers);
    }

    public static void showFollowing(String user) {
        System.out.println(jedis.smembers(String.format(FOLLOWING_KEY,user)));
    }

    public static void showCommon(String user,String target) {
        System.out.println(jedis.sinter(String.format(FOLLOWING_KEY,user),String.format(FOLLOWING_KEY,target)));
    }

    public static void showRecommend(String user) {
        List<String> members = jedis.srandmember(String.format(FOLLOWING_KEY, user), 5);
        Set<String> keys = new HashSet<>();
        if (members != null && !members.isEmpty()) {
            for (String it : members) keys.add(String.format(FOLLOWING_KEY,it));
            jedis.sunionstore(TEMP_USER_RECOMMEND_KEY,keys.toArray(new String[1]));
            jedis.sdiffstore(TEMP_USER_RECOMMEND_KEY,TEMP_USER_RECOMMEND_KEY,String.format(FOLLOWING_KEY, user));
            jedis.srem(TEMP_USER_RECOMMEND_KEY,user);
            System.out.println(jedis.srandmember(TEMP_USER_RECOMMEND_KEY,5));
        }
    }

    public static void main(String[] args) {
        addFollowing("黄先生","刘女士","小陈","小吴","小李","小张");
        addFollowing("刘女士","黄先生","小陈","小吴");
        addFollowing("小李","黄先生","小吴","小张","小孔");
        addFollowing("小张","老李","老吴","黄先生");

        showFollowing("黄先生");
        showFollowing("刘女士");

        showCommon("黄先生","刘女士");
        showCommon("小李","小张");

        showRecommend("黄先生");
        showRecommend("刘女士");
    }
}

2 有序集合Sorted Set

有序集合具有以下特点:

  1. 有序性:按照分数的大小进行排序。
  2. 唯一性:不会出现重复的元素。
  3. 快速查找:可以快速查找某个元素的位置、分数以及排名等信息。
  4. 范围操作:根据分数的范围来获取一段区间内的元素。
  5. 更新分数:可以对集合中的元素进行分数增减操作。

|-------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 添加和移除 | ZADD、ZREM 弹出分值最高、最低的成员:ZPOPMAX、ZPOPMIN |
| 分值 | 获取成员的分值:ZSCORE 对成员的分值执行整数运算:ZINCRBY |
| 集合 | 集合的大小:ZCARD 成员在集合中的排名:ZRANK、ZREVRANK 指定索引范围内的成员:ZRANGE、ZREVRANGE 指定分数范围内的成员:ZRANGEBYSCORE、ZREVRANGEBYSCORE(指定范围时,更大的分数在前面) 统计指定分值范围内的成员数量:ZCOUNT 移除指定排名范围内的成员:ZREMRANGEBYRANK 移除指定分值范围内的成员:ZREMRANGEBYSCORE |
| 集合运算 | 并集:ZUNIONSTORE 交集:ZINTERSTORE |
| 字典 | 指定字典序列范围内的成员:ZRANGEBYLEX、ZREVRANGEBYLEX 统计字典序列指定范围内的成员数量:ZLENCOUNT 移除位于字典序列指定范围内的成员:ZREMRANGEBYLEX |
| 阻塞 | BZPOPMAX、BZPOPMIN |

表 有序集合相关命令

2.1 示例

自动补全:在搜索框输入某些文字的时候,系统的自动补全特性就会列出一些比较著名的以这些文字开头的选项。

java 复制代码
public class AutoComplete {

    private final static Jedis jedis = RedisPool.getJEdis();
    private final static String COMPLETE_KEY = "auto_complete_sorted_set::%s";

    public static void feed(String str) {
        if (str != null) {
            for (int i = 1; i < str.length() + 1; i++) {
                String key = String.format(COMPLETE_KEY,str.substring(0,i));
                System.out.println("key:" + key);
                jedis.zincrby(key,1,str);
            }
        }
    }

    public static void hint(String str) {
        if (str != null) {
            String key = String.format(COMPLETE_KEY,str);
            Set<String> set = jedis.zrange(key, 0, -1);
            System.out.println(set);
        }
    }

    public static void main(String[] args) {
        feed("黄子韬");
        feed("黄晓明");
        feed("黄渤");
        feed("黄金海岸");
        feed("黄嘉千");
        feed("黄金价格");
        feed("黄历");
        feed("黄石公园");
        feed("黄家驹");
        feed("黄雷");

        hint("黄");
        hint("黄金");
    }
}
相关推荐
马克Markorg7 小时前
常见的向量数据库和具有向量数据库能力的数据库
数据库
郝学胜-神的一滴8 小时前
深入解析Python字典的继承关系:从abc模块看设计之美
网络·数据结构·python·程序人生
JH30738 小时前
SpringBoot 优雅处理金额格式化:拦截器+自定义注解方案
java·spring boot·spring
Coder_Boy_9 小时前
技术让开发更轻松的底层矛盾
java·大数据·数据库·人工智能·深度学习
helloworldandy10 小时前
使用Pandas进行数据分析:从数据清洗到可视化
jvm·数据库·python
invicinble10 小时前
对tomcat的提供的功能与底层拓扑结构与实现机制的理解
java·tomcat
较真的菜鸟10 小时前
使用ASM和agent监控属性变化
java
黎雁·泠崖10 小时前
【魔法森林冒险】5/14 Allen类(三):任务进度与状态管理
java·开发语言
数据知道11 小时前
PostgreSQL 故障排查:如何找出数据库中最耗时的 SQL 语句
数据库·sql·postgresql
qq_124987075311 小时前
基于SSM的动物保护系统的设计与实现(源码+论文+部署+安装)
java·数据库·spring boot·毕业设计·ssm·计算机毕业设计