Spring Data Redis 教程

SetOperations 操作接口

SetOperations 操作接口定义了怎样操作 Redis 的 set 类型。在 RedisTemplate 中,可以通过 opsForSet() 方法获取该操作接口。代码如下:

SetOperations<String,String> ops = redisTemplate.opsForSet();

设置值

使用 add() 方法可以将一个或多个值设置给键的集合。方法定义如下:

  • Long add(K key, V... values) 将给定的一个或多个值设置给指定的键

示例:

SetOperations<String,String> ops = redisTemplate.opsForSet();
// 设置多个值给 set-key 键
ops.add("set-key", "value1", "value2", "value3");
// 获取 set-key 键的值
Set<String> values = ops.members("set-key");
System.out.println("set-key=" + Arrays.toString(values.toArray()));

运行示例,输出结果:

set-key=[value2, value3, value1]

获取值

使用 members() 方法获取指定键的所有值,方法定义如下:

  • Set<V> members(K key) 将返回指定键的所有值

具体用法,请参考 add() 方法。

随机出栈

使用 pop() 方法可以从指定键中随机移除且返回元素。方法定义如下:

  • V pop(K key) 从键的集合中随机移除并返回一个成员

  • List<V> pop(K key, long count) 从键的集合中随机删除并返回 count 个成员

示例:

Set<String> values;
SetOperations<String,String> ops = redisTemplate.opsForSet();
// 设置多个值给 set-key 键
ops.add("set-key", "value1", "value2", "value3", "value4", "value5");

// 随机返回一个
String val = ops.pop("set-key");
System.out.println("val=" + val);

values = ops.members("set-key");
System.out.println("set-key=" + Arrays.toString(values.toArray()));

// 随机返回多个
List<String> vals = ops.pop("set-key", 3);
System.out.println("vals=" + Arrays.toString(vals.toArray()));

values = ops.members("set-key");
System.out.println("set-key=" + Arrays.toString(values.toArray()));

运行示例,输出结果:

val=value4
set-key=[value2, value1, value5, value3]
vals=[value5, value3, value1]
set-key=[value2]

注意:如果执行 ops(key, count) 方法时,Redis 版本为 3,则会抛出如下错误:org.springframework.data.redis.RedisSystemException: Error in execution; nested exception is io.lettuce.core.RedisCommandExecutionException: ERR wrong number of arguments for 'spop' command。

上面错误的主要原因是 Redis 版本太低了,这个命令后面才支持,建议升级到 3.2 及以后,见 https://github.com/redis/jedis/issues/1247

计算集合交集

使用 intersect() 方法可以计算两个集合,或者多个集合跟某个集合的交集。方法定义如下:

  • Set<V> intersect(K key, Collection<K> otherKeys) 获取 key 和所有 otherKeys 集合中键的交集

  • Set<V> intersect(K key, K otherKey) 获取 key 和 otherKey 对应集合间的交集

  • Long intersectAndStore(K key, Collection<K> otherKeys, K destKey) 获取 key 和所有 otherKeys 集合中键的交集,并将结果存储在 destKey 键中。

  • Long intersectAndStore(K key, K otherKey, K destKey) 获取 key 和 otherKey 对应集合间的交集,并将结果存储在 destKey 键中。

示例:

Set<String> values;
SetOperations<String,String> ops = redisTemplate.opsForSet();
// 准备数据
ops.add("set-key1", "value1", "value2", "value3");
ops.add("set-key2", "value2", "value3", "value4");
ops.add("set-key3", "value3", "value4", "value5");

values = ops.members("set-key1");
System.out.println("set-key1=" + Arrays.toString(values.toArray()));

values = ops.members("set-key2");
System.out.println("set-key2=" + Arrays.toString(values.toArray()));

values = ops.members("set-key3");
System.out.println("set-key3=" + Arrays.toString(values.toArray()));

// 获取 set-key1 和 set-key2 集合的交集(即在两个集合中均存在的元素)
values = ops.intersect("set-key1", "set-key2");
System.out.println("intersect=" + Arrays.toString(values.toArray()));

// 获取 set-key1、set-key2 和 set-key3 集合的交集
values = ops.intersect("set-key1", Arrays.asList("set-key2", "set-key3"));
System.out.println("intersect=" + Arrays.toString(values.toArray()));

// 获取 set-key1、set-key2 和 set-key3 集合的交集,并将结果存储到 set-result 中
ops.intersectAndStore("set-key1", Arrays.asList("set-key2", "set-key3"),
        "set-result");
values = ops.members("set-result");
System.out.println("intersect=" + Arrays.toString(values.toArray()));

运行示例,输出结果:

set-key1=[value2, value3, value1]
set-key2=[value4, value2, value3]
set-key3=[value4, value5, value3]
intersect=[value2, value3]
intersect=[value3]
intersect=[value3]

计算集合差异

使用 difference() 方法计算指定两个或多个集合的差异。方法定义如下:

  • Set<V> difference(K key, Collection<K> otherKeys) 计算 key 和 otherKeys 集合的差异,返回 key 集合中所有没有在 otherKeys 所有集合中出现的元素集合。

  • Set<V> difference(K key, K otherKey) 计算 key 和 otherKey 集合的差异,返回 key 集合中所有没有在 otherKey 集合中出现的元素集合。

  • Long differenceAndStore(K key, Collection<K> otherKeys, K destKey) 计算 key 和 otherKeys 集合的差异,返回 key 集合中所有没有在 otherKeys 所有集合中出现的元素集合。并且将计算结果保存到 destKey 中。

  • Long differenceAndStore(K key, K otherKey, K destKey) 计算 key 和 otherKey 集合的差异,返回 key 集合中所有没有在 otherKey 集合中出现的元素集合。并且将计算结果保存到 destKey 中。

示例:

Set<String> values;
SetOperations<String,String> ops = redisTemplate.opsForSet();
// 准备数据
ops.add("set-key1", "value1", "value2", "value3");
ops.add("set-key2", "value3");
ops.add("set-key3", "value2");

values = ops.members("set-key1");
System.out.println("set-key1=" + Arrays.toString(values.toArray()));

values = ops.members("set-key2");
System.out.println("set-key2=" + Arrays.toString(values.toArray()));

values = ops.members("set-key3");
System.out.println("set-key3=" + Arrays.toString(values.toArray()));

// 获取 set-key1 集合中没有在 set-key2 集合中的元素
values = ops.difference("set-key1", "set-key2");
System.out.println("values=" + Arrays.toString(values.toArray()));

// 获取 set-key1 集合中没有在 set-key2 或 set-key3 集合中的元素
values = ops.difference("set-key1", Arrays.asList("set-key2", "set-key3"));
System.out.println("values=" + Arrays.toString(values.toArray()));

// 获取 set-key1 集合中没有在 set-key2 或 set-key3 集合中的元素,
// 且将结果存储到 set-result 键
ops.differenceAndStore("set-key1", Arrays.asList("set-key2", "set-key3"),
        "set-result");
values = ops.members("set-result");
System.out.println("values=" + Arrays.toString(values.toArray()));

运行示例,输出结果:

set-key1=[value1, value2, value3]
set-key2=[value3]
set-key3=[value2]
values=[value1, value2]
values=[value1]
values=[value1]

计算集合并集

使用 union() 方法可以计算多个集合的并集,方法定义如下:

  • Set<V> union(K key, Collection<K> otherKeys) 获取 key 和 otherKeys 多个集合的并集

  • Set<V> union(K key, K otherKey) 获取 key 和 otherKey 两个集合的并集

  • Long unionAndStore(K key, Collection<K> otherKeys, K destKey) 获取 key 和 otherKeys 多个集合的并集,并且将结果存储到 destKey 集合

  • Long unionAndStore(K key, K otherKey, K destKey) 获取 key 和 otherKey 两个集合的并集,并且将结果存储到 destKey 集合

示例:

Set<String> values;
SetOperations<String,String> ops = redisTemplate.opsForSet();
// 准备数据
ops.add("set-key1", "value1", "value2", "value3");
ops.add("set-key2", "value3", "value4");
ops.add("set-key3", "value5");

values = ops.members("set-key1");
System.out.println("set-key1=" + Arrays.toString(values.toArray()));

values = ops.members("set-key2");
System.out.println("set-key2=" + Arrays.toString(values.toArray()));

values = ops.members("set-key3");
System.out.println("set-key3=" + Arrays.toString(values.toArray()));

// 获取 set-key1 和 set-key2 集合的并集
values = ops.union("set-key1", "set-key2");
System.out.println("values=" + Arrays.toString(values.toArray()));

// 获取 set-key1、set-key2 和 set-key3 集合的并集
values = ops.union("set-key1", Arrays.asList("set-key2", "set-key3"));
System.out.println("values=" + Arrays.toString(values.toArray()));

// 获取 set-key1 和 set-key2 集合的并集,并且存储到 set-result 集合
ops.unionAndStore("set-key1", "set-key2", "set-result");
values = ops.members("set-result");
System.out.println("values=" + Arrays.toString(values.toArray()));

运行示例,输出结果:

set-key1=[value2, value1, value3]
set-key2=[value4, value3]
set-key3=[value5]
values=[value2, value1, value4, value3]
values=[value1, value4, value3, value2, value5]
values=[value2, value1, value4, value3]

随机返回元素

使用 randomMember() 方法可以从集合中随机返回一个或多个元素,方法定义如下:

  • V randomMember(K key) 从键的集合中随机返回一个元素

  • List<V> randomMembers(K key, long count) 从键的集合中随机返回 count 个元素

  • Set<V> distinctRandomMembers(K key, long count) 从键的集合中随机返回 count 个不重复的元素

示例:

Set<String> values;
SetOperations<String,String> ops = redisTemplate.opsForSet();
// 准备数据(set 集合不能重复)
ops.add("set-key", "value1", "value2", "value3", "value4",
        "value5", "value1", "value2", "value3", "value4", "value5");
values = ops.members("set-key");
System.out.println("values=" + Arrays.toString(values.toArray()));

// 从键集合中随机返回一个元素
String randomVal = ops.randomMember("set-key");
System.out.println("randomVal=" + randomVal);

// 从键集合中随机返回3个元素
List<String> randomVals = ops.randomMembers("set-key", 3);
System.out.println("randomVals=" + Arrays.toString(randomVals.toArray()));

// 从键集合中随机返回3个元素,但是不能有重复元素
// 这个操作在 set 集合中没有实际作用,因为 set 集合不允许重复元素
values = ops.distinctRandomMembers("set-key", 3);
System.out.println("randomVals=" + Arrays.toString(values.toArray()));

运行示例,输出结果:

values=[value2, value5, value3, value1, value4]
randomVal=value2
randomVals=[value5, value2, value1]
randomVals=[value1, value2, value4]

判断元素是否存在

使用 isMember() 方法判断指定的键是否存在某个元素,方法定义如下:

  • Boolean isMember(K key, Object o) 检查 key 的集合中是否存在 o 元素。

示例:

Boolean flag;
Set<String> values;
SetOperations<String,String> ops = redisTemplate.opsForSet();
// 准备数据
ops.add("set-key", "value1", "value2", "value3", "value4");
values = ops.members("set-key");
System.out.println("values=" + Arrays.toString(values.toArray()));

// 判断元素 value1 是否在 set-key 集合中存在
flag = ops.isMember("set-key", "value1");
System.out.println("Does value1 exist? " + flag);

flag = ops.isMember("set-key", "value5");
System.out.println("Does value5 exist? " + flag);

运行示例,输出结果:

values=[value2, value1, value4, value3]
Does value1 exist? true
Does value5 exist? false

元素移动

使用 move() 方法可以将一个元素从一个集合移动到另一个集合。方法定义如下:

  • Boolean move(K key, V value, K destKey) 将 value 从 key 移动到 destKey 集合

示例:

Set<String> values;
SetOperations<String,String> ops = redisTemplate.opsForSet();
// 准备数据
ops.add("set-key", "value1", "value2", "value3", "value4");
values = ops.members("set-key");
System.out.println("values=" + Arrays.toString(values.toArray()));

// 将 value2 移动到 set-key2 集合
Boolean flag = ops.move("set-key", "value2", "set-key2");
if(flag) {
    System.out.println("Move successfully.");
}

values = ops.members("set-key2");
System.out.println("set-key2=" + Arrays.toString(values.toArray()));

values = ops.members("set-key");
System.out.println("set-key=" + Arrays.toString(values.toArray()));

运行示例,输出结果:

values=[value2, value1, value4, value3]
Move successfully.
set-key2=[value2]
set-key=[value1, value4, value3]

移除元素

使用 remove() 方法可以从指定键的集合中移除一个或多个元素,方法定义如下:

  • Long remove(K key, Object... values) 从 key 的集合中移除 values 元素,且返回移除元素的数量

示例:

Set<String> values;
SetOperations<String,String> ops = redisTemplate.opsForSet();
// 准备数据
ops.add("set-key", "value1", "value2", "value3", "value4");
values = ops.members("set-key");
System.out.println("values=" + Arrays.toString(values.toArray()));

// 移除多个元素
Long size = ops.remove("set-key", "value2", "value4", "value6");
System.out.println("size=" + size);

values = ops.members("set-key");
System.out.println("values=" + Arrays.toString(values.toArray()));

运行示例,输出结果:

values=[value2, value1, value4, value3]
size=2
values=[value1, value3]

获取集合大小

使用 size() 方法可以返回指定键的集合的大小,方法定义如下:

  • Long size(K key) 获取指定键的集合大小

示例:

Set<String> values;
SetOperations<String,String> ops = redisTemplate.opsForSet();
// 准备数据
ops.add("set-key", "value1", "value2", "value3", "value4");
values = ops.members("set-key");
System.out.println("values=" + Arrays.toString(values.toArray()));

// 获取集合大小
Long size = ops.size("set-key");
System.out.println("size=" + size);

运行示例,输出结果:

values=[value2, value1, value4, value3]
size=4

集合迭代

使用 scan() 方法可以对键的集合进行迭代,方法定义如下:

  • Cursor<V> scan(K key, ScanOptions options) 迭代 key 集合

ScanOptions 是用于 SCAN 命令的选项,ScanOptions 需要设置 pattern 和 count。其中:

  • pattern 指定匹配的模式

  • count 指定从数据集里返回多少元素,默认值为 10

示例:

Set<String> values;
Cursor<String> cursor;
SetOperations<String,String> ops = redisTemplate.opsForSet();
// 准备数据
for(int i = 0; i < 5; i++) {
    ops.add("set-key", "hello" + i, "world" + i, "value" + i);
}

// 迭代集合
// 构建一个默认的 ScanOptions 对象,不指定 count 和 pattern
// 将迭代整个集合所有数据
values = new HashSet<>();
cursor = ops.scan("set-key", ScanOptions.scanOptions().build());
while (cursor.hasNext()) {
    values.add(cursor.next());
}
System.out.println("values=" + Arrays.toString(values.toArray()));

// 迭代所有 value 开头的元素
values = new HashSet<>();
cursor = ops.scan("set-key", ScanOptions.scanOptions()
    // 匹配所有 value 开头的元素
    .match("value*").build());
while (cursor.hasNext()) {
    values.add(cursor.next());
}
System.out.println("values=" + Arrays.toString(values.toArray()));

// 迭代 2 个 value 开头的元素
values = new HashSet<>();
cursor = ops.scan("set-key", ScanOptions.scanOptions()
    .count(2L)
    // 匹配所有 value 开头的元素
    .match("value*").build());
while (cursor.hasNext()) {
    values.add(cursor.next());
}
System.out.println("values=" + Arrays.toString(values.toArray()));

运行示例,输出结果:

values=[world4, world2, world3, value2, hello0, value1, hello1, value4, value3, hello4, value0, hello2, hello3, world0, world1]
values=[value2, value1, value4, value3, value0]
values=[value2, value1, value4, value3, value0]
说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号