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个元素 删除成功