实例详解Redis实现数据的交集、并集和补集

2022-06-19 0 749

本篇文章给大家带来了关于Redis的相关知识,其中主要介绍了关于实现数据的交集、并集和补集的相关问题,如果全部在JVM内存中进行计算的话,很容易出现内存空间不足导致的OOM异常,下面一起来看一下,希望对大家有帮助。

实例详解Redis实现数据的交集、并集和补集

推荐学习:Redis视频教程

场景说明

今天我们来模拟一个这样的场景,我们在本地有多个文本文件,每个文件里面存了很多的32位的字符串作为用户的唯一标识,每个用户存做一行,假如我们每天都有非常大规模的用户,这样我们可能在工作中就存在需要对这些用户进行交集、并集或补集等处理,最简单的方式是通过Java中的集合来进行运算即可,比如通过HashSet来进行相应的一些运算,但是这样的运算存在一个局限性,那就是我们一般在JVM运行过程中初始的内存是有限的,这样如果全部在JVM内存中进行计算的话,很容易出现内存空间不足导致的OOM异常,那么我们今天来介绍一种拓展性更强的方式来进行这样的一些交并补的运算:通过Redis来实现数据的交集、并集、补集


环境说明

Redis版本: Redis 6.0.6

Jedis版本: 4.2.2

工具类hutool版本: 5.8.0.M3

pom文件:

<dependencies>        <dependency>            <groupId>redis.clients</groupId>            <artifactId>jedis</artifactId>            <version>4.2.2</version>        </dependency>        <dependency>            <groupId>cn.hutool</groupId>            <artifactId>hutool-all</artifactId>            <version>5.8.0.M3</version>        </dependency></dependencies>

交并补计算


初始化常量

public class RedisCalculateUtils {    static String oneFileString = "/Users/tmp/test-1.txt";    static String twoFileString = "/Users/tmp/test-2.txt";    static String diffFileString = "/Users/tmp/diff-test.txt";    static String interFileString = "/Users/tmp/inter-test.txt";    static String unionFileString = "/Users/tmp/union-test.txt";    static String oneFileCacheKey = "oneFile";    static String twoFileCacheKey = "twoFile";    static String diffFileCacheKey = "diffFile";    static String interFileCacheKey = "interFile";    static String unionFileCacheKey = "unionFile";    }

初始化数据到指定文件

/*** 初始化数据并写入文件中*/public static void writeFile() {        File oneFile = new File(oneFileString);        List<String> fs = new ArrayList<>(10000);        for (int i = 10000; i < 15000; i++) {            String s = SecureUtil.md5(String.valueOf(i));            fs.add(s);        }        FileUtil.writeUtf8Lines(fs, oneFile);        File twoFile = new File(twoFileString);        fs.clear();        for (int i = 12000; i < 20000; i++) {            String s = SecureUtil.md5(String.valueOf(i));            fs.add(s);        }        FileUtil.writeUtf8Lines(fs, twoFile);    }

指定文件写入Redis

/*** 读取文件数据并写入Redis*/public static void writeCache() {    try(Jedis jedis = new Jedis("127.0.0.1", 6379)) {        Pipeline p = jedis.pipelined();        List<String> oneFileStringList = FileUtil.readLines(oneFileString, "UTF-8");        for (String s : oneFileStringList) {            p.sadd(oneFileCacheKey, s);        }        p.sync();        List<String> twoFileStringList = FileUtil.readLines(twoFileString, "UTF-8");        for (String s : twoFileStringList) {            p.sadd(twoFileCacheKey, s);        }        p.sync();    } catch (Exception e) {        throw new RuntimeException(e);    }}

差集的计算

    /**     * oneKey对应的Set 与 twoKey对应的Set 的差集 并写入 threeKey     * @param oneKey 差集前面的集合Key     * @param twoKey 差集后面的集合Key     * @param threeKey 差集结果的集合Key     */    public static void diff(String oneKey, String twoKey, String threeKey) {        try(Jedis jedis = new Jedis("127.0.0.1", 6379)) {            long result = jedis.sdiffstore(threeKey, oneKey, twoKey);            System.out.println("oneKey 与 twoKey 的差集的个数:" + result);        } catch (Exception e) {            throw new RuntimeException(e);        }    }

差集计算结果写入到指定文件

    /**     * 将计算的差集数据写入到指定文件     */    public static void writeDiffToFile() {        File diffFile = new File(diffFileString);        try(Jedis jedis = new Jedis("127.0.0.1", 6379)) {            Set<String> result = jedis.smembers(diffFileCacheKey);            FileUtil.writeUtf8Lines(result, diffFile);        } catch (Exception e) {            throw new RuntimeException(e);        }    }

交集的计算

/**     *     * @param cacheKeyArray 交集集合Key     * @param destinationKey 交集集合结果Key     */    public static void inter(String[] cacheKeyArray, String destinationKey) {        try(Jedis jedis = new Jedis("127.0.0.1", 6379)) {            long result = jedis.sinterstore(destinationKey, cacheKeyArray);            System.out.println("cacheKeyArray 的交集的个数:" + result);        } catch (Exception e) {            throw new RuntimeException(e);        }    }

交集计算结果写入指定文件

    /**     * 将计算的交集数据写入到指定文件     */    public static void writeInterToFile() {        File interFile = new File(interFileString);        try(Jedis jedis = new Jedis("127.0.0.1", 6379)) {            Set<String> result = jedis.smembers(interFileCacheKey);            FileUtil.writeUtf8Lines(result, interFile);        } catch (Exception e) {            throw new RuntimeException(e);        }    }

并集的计算

    /**     * 计算多个Key的并集并写入到新的Key     * @param cacheKeyArray 求并集的Key     * @param destinationKey 并集结果写入的KEY     */     public static void union(String[] cacheKeyArray, String destinationKey) {         try(Jedis jedis = new Jedis("127.0.0.1", 6379)) {             long result = jedis.sunionstore(destinationKey, cacheKeyArray);             System.out.println("cacheKeyArray 的并集的个数:" + result);         } catch (Exception e) {             throw new RuntimeException(e);         }     }

并集计算结果写入到指定文件

    /**     * 将计算的并集数据写入到指定文件     */    public static void writeUnionToFile() {         File unionFile = new File(unionFileString);         try(Jedis jedis = new Jedis("127.0.0.1", 6379)) {             Set<String> result = jedis.smembers(unionFileCacheKey);             FileUtil.writeUtf8Lines(result, unionFile);         } catch (Exception e) {             throw new RuntimeException(e);         }     }

Redis命令说明


SDIFFSTORE destination key [key …]

举例说明:

key1 = {a,b,c,d}key2 = {c}key3 = {a,c,e}SDIFF key1 key2 key3 = {b,d}

SDIFFSTORE 命令的作用和SDIFF类似,不同的是它将结果保存到 destination 集合,而把结果集返回给客户端。

如果 destination 集合已经存在,则将其覆盖。

返回值
结果集中成员数量


SINTERSTORE destination key [key …]

举例说明:

key1 = {a,b,c,d}key2 = {c}key3 = {a,c,e}SINTER key1 key2 key3 = {c}

SINTERSTORE 命令与 SINTER 命令类似,不同的是它并不是直接返回结果集,而是将结果保存在 destination 集合中。

如果 destination 集合存在, 则会被覆盖。

返回值
结果集中成员数量


SUNIONSTORE destination key [key …]

举例说明:

key1 = {a,b,c,d}key2 = {c}key3 = {a,c,e}SUNION key1 key2 key3 = {a,b,c,d,e}

SUNIONSTORE 命令的功能类似于 SUNION,不同的是不反回结果集,而是存储在 destination 中。

如果 destination 已经存在,则被覆盖。

返回值
结果集中的成员数量

推荐学习:Redis视频教程

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

【声明:根据2013年1月30日《计算机软件保护条例》2次修订第17条规定: 为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存 储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬! 鉴于此,也希望大家按此说明研究软件!】
本站所有源码尽量保证原汁原味,如有特殊情况会作出声明及标注,网站资源不做任何二次加密(原版加密除外,不影响程序使用的不会做解密处理),方便您更好的学习参考。 在您的能力范围内,为了大环境的良性发展,请尽可能的选择正版资源。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

即刻码站__国内靠谱的站长资源下载平台 php教程 实例详解Redis实现数据的交集、并集和补集 https://www.jike1995.com/37892.html

常见问题
  • 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用
查看详情
  • 最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度
查看详情

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务