Spring Data Redis 中,list 类型的响应式接口为 ReactiveListOperations,该接口定义的方法和 ListOperations、BoundListOperations 接口定义的方法非常类似。
可以通过 ReactiveRedisTemplate 的 opsForList() 方法获取获取,代码如下:
ReactiveListOperations<String,String> ops = reactiveRedisTemplate.opsForList();
reactor.core.publisher.Flux<V> range(K key, long start, long end) 从键的列表中获取 start 到 end 之间的元素
示例:
@Test public void range() throws Exception { // 利用阻塞队列实现等待 LinkedBlockingDeque<String> queue = new LinkedBlockingDeque<>(); ReactiveListOperations<String,String> ops = reactiveRedisTemplate.opsForList(); // 添加元素 ops.leftPushAll("list-key", "value1", "value2", "value3", "value4") .subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("leftPushAll 执行成功,添加 " + aLong + " 个元素"); } }); System.out.println(queue.take()); // 使用 range 获取列表部分元素 ops.range("list-key", 1, 2) .subscribe(new Consumer<String>() { @Override public void accept(String s) { System.out.println(s); } }); }
运行示例,输出结果如下:
leftPushAll 执行成功,添加 4 个元素 value3 value2
注意,上面示例使用了 LinkedBlockingDeque 阻塞队列来实现两个或多个异步响应式操作的同步操作。
reactor.core.publisher.Mono<Long> leftPush(K key, V value) 将值添加到键存储列表的左边
reactor.core.publisher.Mono<Long> leftPush(K key, V pivot, V value) 将值添加到键存储列表中 prvot 值的前面,即值的左边
reactor.core.publisher.Mono<Long> leftPushAll(K key, Collection<V> values) 将多个值添加到键存储列表的左边
reactor.core.publisher.Mono<Long> leftPushAll(K key, V... values) 将多个值添加到键存储列表的左边
reactor.core.publisher.Mono<Long> leftPushIfPresent(K key, V value) 仅当列表存在时,才将值添加到键存储的列表
示例:
@Test public void leftPush() throws Exception { // 利用阻塞队列实现等待 LinkedBlockingDeque<String> queue = new LinkedBlockingDeque<>(); ReactiveListOperations<String,String> ops = reactiveRedisTemplate.opsForList(); // 添加一个元素 ops.leftPush("list-key", "value1").subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("leftPush 添加成功 aLong=" + aLong); } }); System.out.println(queue.take()); // 添加多个元素 ops.leftPushAll("list-key", "value2", "value3", "value4") .subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("leftPushAll 添加成功 aLong=" + aLong); } }); System.out.println(queue.take()); // 获取列表中的值 ops.range("list-key", 0, -1).subscribe(new Consumer<String>() { @Override public void accept(String s) { System.out.println(s); } }); }
运行示例,输出结果如下:
leftPush 添加成功 aLong=1 leftPushAll 添加成功 aLong=4 value4 value3 value2 value1
reactor.core.publisher.Mono<V> leftPop(K key) 移除并返回存储在键的列表中的第一个元素
reactor.core.publisher.Mono<V> leftPop(K key, Duration timeout) 在指定的超时时间中移除并返回存储在键的列表中的第一个元素
示例:
@Test public void leftPop() throws Exception { // 利用阻塞队列实现等待 LinkedBlockingDeque<String> queue = new LinkedBlockingDeque<>(); ReactiveListOperations<String,String> ops = reactiveRedisTemplate.opsForList(); // 添加数据 ops.leftPushAll("list-key", "value1", "value2", "value3", "value4", "value5") .subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("成功添加了 " + aLong + " 元素"); } }); System.out.println(queue.take()); // 异步获取数据 ops.leftPop("list-key").subscribe(new Consumer<String>() { @Override public void accept(String s) { queue.add("leftPop 执行成功,值=" + s); } }); System.out.println(queue.take()); }
运行示例,输出结果如下:
成功添加了 5 元素 leftPop 执行成功,值=value5
reactor.core.publisher.Mono<Long> rightPush(K key, V value) 将值添加到键存储的列表的右边
reactor.core.publisher.Mono<Long> rightPush(K key, V pivot, V value) 将值添加到键存储的列表中 pivot 值的前面,即右边
reactor.core.publisher.Mono<Long> rightPushAll(K key, Collection<V> values) 将多个值添加到键存储的列表的右边
reactor.core.publisher.Mono<Long> rightPushAll(K key, V... values) 将多个值添加到键存储的列表的右边
reactor.core.publisher.Mono<Long> rightPushIfPresent(K key, V value) 仅当列表存在时才将值追加到键存储的列表的右边
示例:
@Test public void rightPush() throws Exception { // 利用阻塞队列实现等待 LinkedBlockingDeque<String> queue = new LinkedBlockingDeque<>(); ReactiveListOperations<String,String> ops = reactiveRedisTemplate.opsForList(); ops.rightPush("list-key", "value1").subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("rightPush 执行成功"); } }); System.out.println(queue.take()); ops.rightPushAll("list-key", "value2", "value3", "value4", "value5") .subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("rightPushAll 执行成功"); } }); System.out.println(queue.take()); // 获取列表所有元素 ops.range("list-key", 0, -1).subscribe(new Consumer<String>() { @Override public void accept(String s) { System.out.println(s); } }); }
运行示例,输出结果如下:
rightPush 执行成功 rightPushAll 执行成功 value1 value2 value3 value4 value5
reactor.core.publisher.Mono<V> rightPop(K key) 移除并返回键存储的列表中的最后一个元素
reactor.core.publisher.Mono<V> rightPop(K key, Duration timeout) 指定在超时时间内移除并返回键存储的列表中的最后一个元素
reactor.core.publisher.Mono<V> rightPopAndLeftPush(K sourceKey, K destinationKey) 从 sourceKey 的列表中删除最后一个元素,将其追加到 destinationKey 键存储的列表并返回其值
reactor.core.publisher.Mono<V> rightPopAndLeftPush(K sourceKey, K destinationKey, Duration timeout) 从列表中删除 srcKey 处的最后一个元素,将其附加到 dstKey 键存储的列表并返回其值
示例:
@Test public void rightPop() throws Exception { // 利用阻塞队列实现等待 LinkedBlockingDeque<String> queue = new LinkedBlockingDeque<>(); ReactiveListOperations<String,String> ops = reactiveRedisTemplate.opsForList(); // 初始化数据 ops.rightPushAll("list-key", "value1", "value2", "value3", "value4", "value5") .subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("rightPushAll 执行成功,添加了" + aLong + "个元素"); } }); System.out.println(queue.take()); // 出栈数据 ops.rightPop("list-key").subscribe(new Consumer<String>() { @Override public void accept(String s) { System.out.println(s); } }); }
运行示例,输出结果如下:
rightPushAll 执行成功,添加了5个元素 value5
reactor.core.publisher.Mono<Boolean> set(K key, long index, V value) 将 value 设置给列表中 index 索引位置处
reactor.core.publisher.Mono<V> index(K key, long index) 获取列表中指定 index 索引的值
示例:
@Test public void set() throws Exception { // 利用阻塞队列实现等待 LinkedBlockingDeque<String> queue = new LinkedBlockingDeque<>(); ReactiveListOperations<String,String> ops = reactiveRedisTemplate.opsForList(); // 初始化数据 ops.rightPushAll("list-key", "value1", "value2", "value3", "value4", "value5") .subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("rightPushAll 执行成功,添加了" + aLong + "个元素"); } }); System.out.println(queue.take()); // 设置元素 ops.set("list-key", 1, "new value").subscribe(new Consumer<Boolean>() { @Override public void accept(Boolean aBoolean) { queue.add("set 执行" + (aBoolean ? "成功" : "失败")); } }); System.out.println(queue.take()); // 获取所有数据 ops.range("list-key", 0, -1).subscribe(new Consumer<String>() { @Override public void accept(String s) { System.out.println(s); } }); }
运行示例,输出结果如下:
rightPushAll 执行成功,添加了5个元素 set 执行成功 value1 new value value3 value4 value5
reactor.core.publisher.Mono<Long> size(K key) 获取键存储的列表的大小
示例:
@Test public void size() throws Exception { // 利用阻塞队列实现等待 LinkedBlockingDeque<String> queue = new LinkedBlockingDeque<>(); ReactiveListOperations<String,String> ops = reactiveRedisTemplate.opsForList(); // 初始化数据 ops.rightPushAll("list-key", "value1", "value2", "value3", "value4", "value5") .subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("rightPushAll 执行成功,添加了" + aLong + "个元素"); } }); System.out.println(queue.take()); // 获取列表大小 ops.size("list-key").subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { System.out.println("size=" + aLong); } }); }
运行示例,输出结果如下:
rightPushAll 执行成功,添加了5个元素 size=5
reactor.core.publisher.Mono<Long> remove(K key, long count, Object value) 从列表中移除首次出现的 count 个等于 value 的元素
示例:
@Test public void remove() throws Exception { // 利用阻塞队列实现等待 LinkedBlockingDeque<String> queue = new LinkedBlockingDeque<>(); ReactiveListOperations<String,String> ops = reactiveRedisTemplate.opsForList(); // 初始化数据 ops.rightPushAll("list-key", "value1", "value2", "value2", "value2", "value5") .subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("rightPushAll 执行成功,添加了" + aLong + "个元素"); } }); System.out.println(queue.take()); // 删除数据 ops.remove("list-key", 2, "value2").subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("成功删除 " + aLong + " 个元素"); } }); System.out.println(queue.take()); // 获取所有数据 ops.range("list-key", 0, -1).subscribe(new Consumer<String>() { @Override public void accept(String s) { System.out.println(s); } }); }
运行示例,输出结果如下:
rightPushAll 执行成功,添加了5个元素 成功删除 2 个元素 value1 value2 value5
reactor.core.publisher.Mono<Boolean> trim(K key, long start, long end) 将列表中 start 到 end 之间的元素保留,其他元素删除
示例:
@Test public void trim() throws Exception { // 利用阻塞队列实现等待 LinkedBlockingDeque<String> queue = new LinkedBlockingDeque<>(); ReactiveListOperations<String,String> ops = reactiveRedisTemplate.opsForList(); // 初始化数据 ops.rightPushAll("list-key", "value1", "value2", "value3", "value4", "value5") .subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("rightPushAll 执行成功,添加了" + aLong + "个元素"); } }); System.out.println(queue.take()); // 裁剪列表 ops.trim("list-key", 1, 3).subscribe(new Consumer<Boolean>() { @Override public void accept(Boolean aBoolean) { queue.add("trim 执行" + (aBoolean ? "成功" : "失败")); } }); System.out.println(queue.take()); // 获取所有数据 ops.range("list-key", 0, -1).subscribe(new Consumer<String>() { @Override public void accept(String s) { System.out.println(s); } }); }
运行示例,输出结果如下:
rightPushAll 执行成功,添加了5个元素 trim 执行成功 value2 value3 value4
reactor.core.publisher.Mono<Boolean> delete(K key) 删除指定的键
示例:
@Test public void delete() throws Exception { // 利用阻塞队列实现等待 LinkedBlockingDeque<String> queue = new LinkedBlockingDeque<>(); ReactiveListOperations<String,String> ops = reactiveRedisTemplate.opsForList(); // 初始化数据 ops.rightPushAll("list-key", "value1", "value2", "value3", "value4", "value5") .subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("rightPushAll 执行成功,添加了" + aLong + "个元素"); } }); System.out.println(queue.take()); // 删除列表 ops.delete("list-key").subscribe(new Consumer<Boolean>() { @Override public void accept(Boolean aBoolean) { System.out.println(aBoolean ? "删除成功" : "删除失败"); } }); }
运行示例,输出结果如下:
rightPushAll 执行成功,添加了5个元素 删除成功