站长家园(原代码之家)(www.adminjie.com)网站源码,微信源码,游戏源码,商业源码分享平台。
当前位置:网站首页 技术文章 网络编程 正文

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

时间:2022-06-02 [网络编程]作者:fabuyuan 浏览:6 次

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

推荐学习: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视频教程

以上就是实例详解Redis实现数据的交集、并集和补集的详细内容,更多请关注站长家园其它相关文章!

本文标签:  redis

转载请注明来源:实例详解Redis实现数据的交集、并集和补集

本文永久链接地址:https://www.adminjie.com/post/13084.html

免责声明:
本站所发布的一切资源仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。

附:
二○○二年一月一日《计算机软件保护条例》第十七条规定:为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬!鉴于此,也希望大家按此说明研究软件!

版权声明:
一、本站致力于为软件爱好者提供国内外软件开发技术和软件共享,着力为用户提供优资资源。
二、本站提供的部分源码下载文件为网络共享资源,请于下载后的24小时内删除。如需体验更多乐趣,还请支持正版。
三、我站提供用户下载的所有内容均转自互联网。如有内容侵犯您的版权或其他利益的,若有侵犯你的权益请:提交版权证明文件到邮箱 2225329873#qq.com(#换为@) 站长会进行审查之后,情况属实的会在三个工作日内为您删除。

  • 站长家园(原代码之家)会员升级
  • 最新文章
    • git怎么撤回刚删除的分支

      git怎么撤回刚删除的分支

      git撤回刚删除分支的方法:1、利用“gitremoteprune”命令查看被删除的分支;2、利用“gitreflog”命令找到被删除分支的最后一次提交记...

    • 如何安装并管理多版本node?方法介绍

      如何安装并管理多版本node?方法介绍

      如何安装并管理多版本node?下面本篇文章给大家介绍一下多版本node的安装与切换详细操作,希望对大家有所帮助!安装多版本node的原因:在项目开发过程中,不同...

    • git为什么会产生冲突

      git为什么会产生冲突

      在git中,冲突产生的原因是因为在合并文件时同一个文件的同一个位置都修改了,并且内容不同;也即两个已经提交的分支的相同文件相同位置的不同操作进行了合并,所以产生...

    • git分离头指针是什么

      git分离头指针是什么

      git分离头指针是一种HEAD指针不再指向分支,而是直接指向某个commit的状态;一般情况下HEAD指针指向分支,而分支是指向提交,分离头指针指的是变更没有基...

    • git bash做什么的

      git bash做什么的

      gitbash是用于git版本控制,上传下载项目代码用的;gitbash是Windows下的一个命令行工具,是基于“msysGNU”环境,有git分布式版...

    热门文章