服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|数据库技术|

服务器之家 - 数据库 - Redis - Redis实现数据的交集、并集、补集的示例

Redis实现数据的交集、并集、补集的示例

2022-08-10 15:12有梦想的攻城狮 Redis

本文主要介绍了Redis实现数据的交集、并集、补集的示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

场景说明

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

环境说明

  • Redis版本: Redis 6.0.6
  • Jedis版本: 4.2.2
  • 工具类hutool版本: 5.8.0.M3

pom文件:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<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>

交并补计算

初始化常量

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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";
}

初始化数据到指定文件

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* 初始化数据并写入文件中
*/
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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 读取文件数据并写入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);
    }
}

差集的计算

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    /**
     * 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);
        }
    }

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

?
1
2
3
4
5
6
7
8
9
10
11
12
    /**
     * 将计算的差集数据写入到指定文件
     */
    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);
        }
    }

交集的计算

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
     *
     * @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);
        }
    }

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

?
1
2
3
4
5
6
7
8
9
10
11
12
/**
 * 将计算的交集数据写入到指定文件
 */
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);
    }
}

并集的计算

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    /**
     * 计算多个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);
         }
     }

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

?
1
2
3
4
5
6
7
8
9
10
11
12
/**
 * 将计算的并集数据写入到指定文件
 */
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 …]

举例说明:

?
1
2
3
4
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 …]

举例说明:

?
1
2
3
4
key1 = {a,b,c,d}
key2 = {c}
key3 = {a,c,e}
SINTER key1 key2 key3 = {c}

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

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

返回值

  • 结果集中成员数量

SUNIONSTORE destination key [key …]

举例说明:

?
1
2
3
4
key1 = {a,b,c,d}
key2 = {c}
key3 = {a,c,e}
SUNION key1 key2 key3 = {a,b,c,d,e}

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

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

返回值

  • 结果集中的成员数量

参考资料: https://www.redis.com.cn/set.html

到此这篇关于Redis实现数据的交集、并集、补集的示例的文章就介绍到这了,更多相关Redis数据交集、并集、补集内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/zhangzehai2234/article/details/124784284

延伸 · 阅读

精彩推荐
  • Redis详解Redis在SpringBoot工程中的综合应用

    详解Redis在SpringBoot工程中的综合应用

    这篇文章主要介绍了Redis在SpringBoot工程中的综合应用,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友...

    雨田说码7162021-11-19
  • Redisredis部署及各种数据类型使用命令详解

    redis部署及各种数据类型使用命令详解

    这篇文章主要介绍了redis部署及各种数据类型使用命令,编译安装redis及部署过程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价...

    马昌伟7602022-03-06
  • Redis让Redis在你的系统中发挥更大作用的几点建议

    让Redis在你的系统中发挥更大作用的几点建议

    Redis在很多方面与其他数据库解决方案不同:它使用内存提供主存储支持,而仅使用硬盘做持久性的存储;它的数据模型非常独特,用的是单线程。另一个...

    Redis教程网5192019-10-20
  • Redis从源码解读redis持久化

    从源码解读redis持久化

    redis的持久化也就是数据落地,对于任何一个数据系统都要考虑是不是需要数据落地。在系统崩溃或是机房掉电等的情况下,将有用的数据记录在非易失性...

    爱编程厨师3892019-11-16
  • Redis利用ganglia监控redis的最新解决方法

    利用ganglia监控redis的最新解决方法

    这篇文章主要给大家介绍了如何利用ganglia监控redis的最新解决方法,网上的资料基本上就是13年的一篇文章,但发现文章的内容有些许问题,于是整理了下...

    leo108''''s blog3642019-11-01
  • RedisRedis实现分布式队列浅析

    Redis实现分布式队列浅析

    Redis将数据存储在内存中,使得读写速度非常快,经常被用来做缓存系统,这里我们将redis用来做一个分布式的消息队列。这篇文章主要介绍了使用redis来作...

    ioiogoo5412019-10-31
  • RedisRedis migrate数据迁移工具的使用教程

    Redis migrate数据迁移工具的使用教程

    这篇文章主要给大家介绍了关于Redis migrate数据迁移工具的使用教程,文中通过示例代码介绍的非常详细,对大家的学习或者使用Redis具有一定的参考学习价...

    嘟噜聪4392020-09-01
  • Redis为啥懒 Redis 是更好的 Redis

    为啥懒 Redis 是更好的 Redis

    本文是由zicode, 李中凯, 无若翻译的英文文章Lazy Redis is better Redis,小编认为非常不错,这里推荐给大家 ...

    zicode, 李中凯, 无若3292019-11-15