Spring Data Redis 中,ZSet 类型的响应式接口为 ReactiveZSetOperations,该接口定义的方法和 ZSetOperations、BoundZSetOperations 接口定义的方法非常类似。
我们可以通过 ReactiveRedisTemplate 的 opsForZSet() 方法获取获取,代码如下:
ReactiveZSetOperations<String,String> ops = reactiveRedisTemplate.opsForZSet();
reactor.core.publisher.Mono<Boolean> add(K key, V value, double score) 将 value 添加到 key 对应的 zset 集合,如果它已经存在则更新其 score。
reactor.core.publisher.Mono<Long> addAll(K key, Collection<? extends ZSetOperations.TypedTuple<V>> tuples) 将 tuples 添加到 key 的 zset 集合中,如果它已经存在则更新它们的分数。
示例:
@Test public void add() throws Exception { LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>(); ReactiveZSetOperations<String,String> ops = reactiveRedisTemplate.opsForZSet(); // 添加一个元素 ops.add("zset-key", "value1", 10) .subscribe(new Consumer<Boolean>() { @Override public void accept(Boolean aBoolean) { if(aBoolean) { queue.add("成功添加元素"); } else { queue.add("添加元素失败"); } } }); System.out.println(queue.take()); // 添加多个元素 ops.addAll("zset-key", Arrays.asList( new DefaultTypedTuple<String>("value2", 20D), new DefaultTypedTuple<String>("value3", 30D), new DefaultTypedTuple<String>("value4", 40D) )).subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("成功添加" + aLong + "个元素"); } }); // 输出所有元素 ops.scan("zset-key").collectList().subscribe(new Consumer<List<ZSetOperations.TypedTuple<String>>>() { @Override public void accept(List<ZSetOperations.TypedTuple<String>> typedTuples) { for(ZSetOperations.TypedTuple<String> typedTuple : typedTuples) { System.out.println("value=" + typedTuple.getValue() + ", score=" + typedTuple.getScore()); } queue.add("元素个数" + typedTuples.size()); } }); System.out.println(queue.take()); }
运行示例,输出结果如下:
成功添加元素 成功添加3个元素 value=value1, score=10.0 value=value2, score=20.0 value=value3, score=30.0 value=value4, score=40.0 元素个数4
reactor.core.publisher.Mono<Long> count(K key, org.springframework.data.domain.Range<Double> range) 计算 key 对应的 zset 集合中的元素个数,元素的分数在最小值(min)和最大值(max)之间。
示例:
@Test public void count() throws Exception { LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>(); ReactiveZSetOperations<String,String> ops = reactiveRedisTemplate.opsForZSet(); // 添加多个元素 ops.addAll("zset-key", Arrays.asList( new DefaultTypedTuple<String>("value1", 10D), new DefaultTypedTuple<String>("value2", 20D), new DefaultTypedTuple<String>("value3", 30D), new DefaultTypedTuple<String>("value4", 40D) )).subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("成功添加" + aLong + "个元素"); } }); System.out.println(queue.take()); ops.count("zset-key", Range.of(Range.Bound.inclusive(20D), Range.Bound.inclusive(30D))) .subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("有" + aLong + "个元素"); } }); System.out.println(queue.take()); }
运行示例,输出结果如下:
成功添加4个元素 有2个元素
reactor.core.publisher.Mono<Boolean> delete(K key) 移除给定的 key
示例:
@Test public void delete() throws Exception { LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>(); ReactiveZSetOperations<String,String> ops = reactiveRedisTemplate.opsForZSet(); // 添加多个元素 ops.addAll("zset-key", Arrays.asList( new DefaultTypedTuple<String>("value1", 10D), new DefaultTypedTuple<String>("value2", 20D) )).subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("成功添加" + aLong + "个元素"); } }); System.out.println(queue.take()); // 删除 zset-key ops.delete("zset-key").subscribe(new Consumer<Boolean>() { @Override public void accept(Boolean aBoolean) { if(aBoolean) { queue.add("删除 zset-key 成功"); } else { queue.add("删除 zset-key 失败"); } } }); System.out.println(queue.take()); // 输出所有元素 ops.scan("zset-key").collectList().subscribe(new Consumer<List<ZSetOperations.TypedTuple<String>>>() { @Override public void accept(List<ZSetOperations.TypedTuple<String>> typedTuples) { for(ZSetOperations.TypedTuple<String> typedTuple : typedTuples) { System.out.println("value=" + typedTuple.getValue() + ", score=" + typedTuple.getScore()); } queue.add("元素个数" + typedTuples.size()); } }); System.out.println(queue.take()); }
运行示例,输出结果如下:
成功添加2个元素 删除 zset-key 成功 元素个数0
reactor.core.publisher.Mono<Double> incrementScore(K key, V value, double delta) 按增量(delta)递增 zset 集合中值等于 value 的元素的分数。
示例:
@Test public void incrementScore() throws Exception { LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>(); ReactiveZSetOperations<String,String> ops = reactiveRedisTemplate.opsForZSet(); // 添加一个元素 ops.add("zset-key", "value1", 10) .subscribe(new Consumer<Boolean>() { @Override public void accept(Boolean aBoolean) { if(aBoolean) { queue.add("成功添加元素"); } else { queue.add("添加元素失败"); } } }); System.out.println(queue.take()); // 将 zset-key 集合中 value1 的分数添加 100 ops.incrementScore("zset-key", "value1", 100) .subscribe(new Consumer<Double>() { @Override public void accept(Double aDouble) { queue.add("修改 zset-key 的 value1 分数成功,最新分数:" + aDouble); } }); System.out.println(queue.take()); }
运行示例,输出结果如下:
成功添加元素 修改 zset-key 的 value1 分数成功,最新分数:110.0
reactor.core.publisher.Mono<Long> intersectAndStore(K key, Collection<K> otherKeys, K destKey) 计算 key 和 otherKeys 对应集合的交集,并将结果存储到 destKey 集合中。
reactor.core.publisher.Mono<Long> intersectAndStore(K key, K otherKey, K destKey) 计算 key 和 otherKey 对应集合的交集,并将结果存储到 destKey 集合中。
示例:
@Test public void intersectAndStore() throws Exception { LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>(); ReactiveZSetOperations<String,String> ops = reactiveRedisTemplate.opsForZSet(); // 添加元素 ops.addAll("zset-key1", Arrays.asList( new DefaultTypedTuple<String>("value1", 10D), new DefaultTypedTuple<String>("value2", 20D), new DefaultTypedTuple<String>("value3", 30D) )).subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("成功向zset-key1添加" + aLong + "个元素"); } }); System.out.println(queue.take()); // 添加元素 ops.addAll("zset-key2", Arrays.asList( new DefaultTypedTuple<String>("value1", 10D), new DefaultTypedTuple<String>("value2", 20D), new DefaultTypedTuple<String>("value4", 40D) )).subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("成功向zset-key2添加" + aLong + "个元素"); } }); System.out.println(queue.take()); // 添加元素 ops.addAll("zset-key3", Arrays.asList( new DefaultTypedTuple<String>("value1", 10D), new DefaultTypedTuple<String>("value2", 20D), new DefaultTypedTuple<String>("value5", 40D) )).subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("成功向zset-key3添加" + aLong + "个元素"); } }); System.out.println(queue.take()); // 计算三个key的交集,将结果存储到 destKey 集合 ops.intersectAndStore("zset-key1", Arrays.asList("zset-key2", "zset-key3"), "destKey").subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("结果大小:" + aLong); } }); System.out.println(queue.take()); // 验证 destKey ops.scan("destKey").collectList().subscribe(new Consumer<List<ZSetOperations.TypedTuple<String>>>() { @Override public void accept(List<ZSetOperations.TypedTuple<String>> typedTuples) { for(ZSetOperations.TypedTuple<String> typedTuple : typedTuples) { System.out.println("value=" + typedTuple.getValue() + ", score=" + typedTuple.getScore()); } queue.add("元素个数" + typedTuples.size()); } }); System.out.println(queue.take()); }
运行示例,输出结果如下:
成功向zset-key1添加3个元素 成功向zset-key2添加3个元素 成功向zset-key3添加3个元素 结果大小:2 value=value1, score=30.0 value=value2, score=60.0 元素个数2
从上面输出结果可知,value1 和 value2 的分数是 zset-key1、zset-key2 和 zset-key3 元素的总和。
reactor.core.publisher.Flux<V> range(K key, org.springframework.data.domain.Range<Long> range) 从 zset 集合中获取开始(start)和结束(end)之间的元素。
示例:
@Test public void range() throws Exception { LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>(); ReactiveZSetOperations<String,String> ops = reactiveRedisTemplate.opsForZSet(); // 添加元素 ops.addAll("zset-key", Arrays.asList( new DefaultTypedTuple<String>("value1", 10D), new DefaultTypedTuple<String>("value2", 40D), new DefaultTypedTuple<String>("value3", 20D), new DefaultTypedTuple<String>("value4", 50D), new DefaultTypedTuple<String>("value5", 30D) )).subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("成功向zset-key添加" + aLong + "个元素"); } }); System.out.println(queue.take()); // 上面元素添加到 zset 后,顺序为: // value1,value3,value5,value2,value4 // 根据 zset 中元素排序后的顺序获取下标在 0 和 2 之间的元素 Range<Long> range = Range.of(Range.Bound.inclusive(0L), Range.Bound.inclusive(2L)); ops.range("zset-key", range).collectList() .subscribe(new Consumer<List<String>>() { @Override public void accept(List<String> strings) { for(String str : strings) { System.out.println(str); } } }); }
运行示例,输出结果如下:
成功向zset-key添加5个元素 value1 value3 value5
reactor.core.publisher.Flux<V> rangeByLex(K key, org.springframework.data.domain.Range<String> range) 从 zset 中获取所有具有字典顺序的元素,其值介于 Range.getLowerBound() 和 Range.getUpperBound() 之间。
reactor.core.publisher.Flux<V> rangeByLex(K key, org.springframework.data.domain.Range<String> range, RedisZSetCommands.Limit limit) 从 zset 中获取所有具有字典顺序的元素的 n 个元素,其中 n = RedisZSetCommands.Limit.getCount(),从 RedisZSetCommands.Limit.getOffset() 开始,值介于 Range.getLowerBound() 和 Range.getUpperBound() 之间。
示例:
@Test public void rangeByLex() throws Exception { LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>(); ReactiveZSetOperations<String,String> ops = reactiveRedisTemplate.opsForZSet(); // 添加元素 ops.addAll("zset-key", Arrays.asList( new DefaultTypedTuple<String>("Admin", 10D), new DefaultTypedTuple<String>("Back", 40D), new DefaultTypedTuple<String>("Control", 20D), new DefaultTypedTuple<String>("Date", 50D), new DefaultTypedTuple<String>("Edit", 30D) )).subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("成功向zset-key添加" + aLong + "个元素"); } }); System.out.println(queue.take()); // 使用字典顺序检索 range.getLowerBound() 到 range.getUpperBound() 之间的元素 Range<String> range = Range.of(Range.Bound.inclusive("B"), Range.Bound.inclusive("D")); System.out.println("getLowerBound()=" + range.getLowerBound()); System.out.println("getUpperBound()=" + range.getUpperBound()); ops.rangeByLex("zset-key", range).collectList() .subscribe(new Consumer<List<String>>() { @Override public void accept(List<String> strings) { for(String str : strings) { System.out.println(str); } queue.add(range.getLowerBound() + "~" + range.getUpperBound() + "之间有" + strings.size() + "个元素"); } }); System.out.println(queue.take()); }
运行示例,输出结果如下:
成功向zset-key添加5个元素 getLowerBound()=B getUpperBound()=D Control B~D之间有1个元素
reactor.core.publisher.Flux<V> rangeByScore(K key, org.springframework.data.domain.Range<Double> range) 从 zset 中获取分数在最小值(min)和最大值(max)之间的元素。
reactor.core.publisher.Flux<V> rangeByScore(K key, org.springframework.data.domain.Range<Double> range, RedisZSetCommands.Limit limit) 从排序的集合中获取从开始到结束的元素,其中得分介于最小和最大之间。
reactor.core.publisher.Flux<ZSetOperations.TypedTuple<V>> rangeByScoreWithScores(K key, org.springframework.data.domain.Range<Double> range) 从 zset 中获取分数介于最小值(min)和最大值(max)之间的 RedisZSetCommands.Tuples 集合。
reactor.core.publisher.Flux<ZSetOperations.TypedTuple<V>> rangeByScoreWithScores(K key, org.springframework.data.domain.Range<Double> range, RedisZSetCommands.Limit limit) 从开始到结束的范围内获取一组 Redis ZSet Commands.Tuples,其中分数在最小值和最大值之间。
reactor.core.publisher.Flux<ZSetOperations.TypedTuple<V>> rangeWithScores(K key, org.springframework.data.domain.Range<Long> range) 从 zset 集中获取开始和结束之间的一组 RedisZSetCommands.Tuples。
示例:
@Test public void rangeByScore() throws Exception { LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>(); ReactiveZSetOperations<String,String> ops = reactiveRedisTemplate.opsForZSet(); // 添加元素 ops.addAll("zset-key", Arrays.asList( new DefaultTypedTuple<String>("Admin", 10D), new DefaultTypedTuple<String>("Back", 40D), new DefaultTypedTuple<String>("Control", 20D), new DefaultTypedTuple<String>("Date", 50D), new DefaultTypedTuple<String>("Edit", 30D) )).subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("成功向zset-key添加" + aLong + "个元素"); } }); System.out.println(queue.take()); Range<Double> range = Range.of(Range.Bound.inclusive(20D), Range.Bound.inclusive(30D)); ops.rangeByScore("zset-key", range).collectList() .subscribe(new Consumer<List<String>>() { @Override public void accept(List<String> strings) { for(String str : strings) { System.out.println(str); } queue.add(range.getLowerBound() + "~" + range.getUpperBound() + "分数之间存在" + strings.size() + "个元素"); } }); System.out.println(queue.take()); }
运行示例,输出结果如下:
成功向zset-key添加5个元素 Control Edit 20.0~30.0分数之间存在2个元素
reactor.core.publisher.Mono<Long> rank(K key, Object o) 确定指定值在 zset 集中的索引。
reactor.core.publisher.Mono<Long> reverseRank(K key, Object o) 当得分从高到低时,确定排序集中具有值的元素的索引。
示例:
@Test public void rank() throws Exception { LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>(); ReactiveZSetOperations<String,String> ops = reactiveRedisTemplate.opsForZSet(); // 添加元素 ops.addAll("zset-key", Arrays.asList( new DefaultTypedTuple<String>("Admin", 10D), new DefaultTypedTuple<String>("Back", 40D), new DefaultTypedTuple<String>("Control", 20D), new DefaultTypedTuple<String>("Date", 50D), new DefaultTypedTuple<String>("Edit", 30D) )).subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("成功向zset-key添加" + aLong + "个元素"); } }); System.out.println(queue.take()); // 查找 Back 元素在 zset-key 中的索引 ops.rank("zset-key", "Back").subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("Back 的索引位置:" + aLong); } }); System.out.println(queue.take()); }
运行示例,输出结果如下:
Back 的索引位置:3
reactor.core.publisher.Mono<Long> remove(K key, Object... values) 从 zset 集中删除值。
reactor.core.publisher.Mono<Long> removeRange(K key, org.springframework.data.domain.Range<Long> range) 从 key 对应的 zset 集中删除开始和结束之间范围内的元素。
reactor.core.publisher.Mono<Long> removeRangeByScore(K key, org.springframework.data.domain.Range<Double> range) 从 key 对应的 zset 集中删除分数在 min 和 max 之间的元素。
示例:
@Test public void remove() throws Exception { LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>(); ReactiveZSetOperations<String,String> ops = reactiveRedisTemplate.opsForZSet(); // 添加元素 ops.addAll("zset-key", Arrays.asList( new DefaultTypedTuple<String>("Admin", 10D), new DefaultTypedTuple<String>("Back", 40D), new DefaultTypedTuple<String>("Control", 20D), new DefaultTypedTuple<String>("Date", 50D), new DefaultTypedTuple<String>("Edit", 30D) )).subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("成功向zset-key添加" + aLong + "个元素"); } }); System.out.println(queue.take()); // 删除元素 Date 和 Edit 元素 ops.remove("zset-key", "Date", "Edit").subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("成功删除" + aLong + "元素"); } }); System.out.println(queue.take()); // 输出result集合 ops.scan("zset-key").collectList() .subscribe(new Consumer<List<ZSetOperations.TypedTuple<String>>>() { @Override public void accept(List<ZSetOperations.TypedTuple<String>> typedTuples) { for(ZSetOperations.TypedTuple<String> typedTuple : typedTuples) { System.out.println("value=" + typedTuple.getValue() + ", score=" + typedTuple.getScore()); } queue.add("zset-key 集合中有" + typedTuples.size() + "个元素"); } }); System.out.println(queue.take()); }
运行示例,输出结果如下:
成功向zset-key添加5个元素 成功删除2元素 value=Admin, score=10.0 value=Control, score=20.0 value=Back, score=40.0 zset-key 集合中有3个元素
reactor.core.publisher.Flux<V> reverseRange(K key, org.springframework.data.domain.Range<Long> range) 按从高到低的顺序排列 zset 集合中的元素,然后获取开始到结束之间的元素。
reactor.core.publisher.Flux<V> reverseRangeByLex(K key, org.springframework.data.domain.Range<String> range) 从 ZSET 中获取所有具有反向字典顺序的元素,其值介于 Range.getLowerBound() 和 Range.getUpperBound() 之间。
reactor.core.publisher.Flux<V> reverseRangeByLex(K key, org.springframework.data.domain.Range<String> range, RedisZSetCommands.Limit limit) 从 key 的 ZSET 反向字典排序中获取 n 个元素,从 RedisZSetCommands.Limit.getOffset() 开始,值介于 Range.getLowerBound() 和 Range.getUpperBound() 之间,其中 n = RedisZSetCommands.Limit.getCount()。
reactor.core.publisher.Flux<V> reverseRangeByScore(K key, org.springframework.data.domain.Range<Double> range) 按从高到低顺序排序 zset 集合中的元素,然后获取分数在最小值和最大值之间的元素。
reactor.core.publisher.Flux<V> reverseRangeByScore(K key, org.springframework.data.domain.Range<Double> range, RedisZSetCommands.Limit limit) 按从高到低顺序排序 zset 集合中的元素,然后获取分数在最小值和最大值之间的 limit 个元素。
reactor.core.publisher.Flux<ZSetOperations.TypedTuple<V>> reverseRangeByScoreWithScores(K key, org.springframework.data.domain.Range<Double> range) 从由高到低排序的 zset 排序集中获取分数在最小值和最大值之间的一组 RedisZSetCommands.Tuple。
reactor.core.publisher.Flux<ZSetOperations.TypedTuple<V>> reverseRangeByScoreWithScores(K key, org.springframework.data.domain.Range<Double> range, RedisZSetCommands.Limit limit) 获取从开始到结束范围内的 RedisZSetCommands.Tuple 集,其中分数介于排序集高 -> 低的排序集的最小值和最大值之间。
reactor.core.publisher.Flux<ZSetOperations.TypedTuple<V>> reverseRangeWithScores(K key, org.springframework.data.domain.Range<Long> range) 从由高到低排序的有序集合中,从开始到结束的范围内获取一组 RedisZSetCommands.Tuples。
示例:
@Test public void reverseRange() throws Exception { LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>(); ReactiveZSetOperations<String,String> ops = reactiveRedisTemplate.opsForZSet(); // 添加元素 ops.addAll("zset-key", Arrays.asList( new DefaultTypedTuple<String>("Admin", 10D), new DefaultTypedTuple<String>("Back", 40D), new DefaultTypedTuple<String>("Control", 20D), new DefaultTypedTuple<String>("Date", 50D), new DefaultTypedTuple<String>("Edit", 30D) )).subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("成功向zset-key添加" + aLong + "个元素"); } }); System.out.println(queue.take()); // 逆序获取范围内的元素(从高到低)获取下标 0 ~ 3 之间的元素 Range<Long> range = Range.of(Range.Bound.inclusive(0L), Range.Bound.inclusive(3L)); ops.reverseRange("zset-key", range).collectList() .subscribe(new Consumer<List<String>>() { @Override public void accept(List<String> strings) { for(String str : strings) { System.out.println(str); } queue.add(range.getLowerBound() + "~" + range.getUpperBound() + "之间存在" + strings.size() + "个元素"); } }); System.out.println(queue.take()); }
运行示例,输出结果如下:
成功向zset-key添加5个元素 Date Back Edit Control 0~3之间存在4个元素
reactor.core.publisher.Mono<Double> score(K key, Object o) 使用 key 从 zset 集中获取具有值的元素的分数(score)。
reactor.core.publisher.Mono<Long> size(K key) 返回给定 key 对应 zset 集合元素的个数。
reactor.core.publisher.Mono<Long> unionAndStore(K key, Collection<K> otherKeys, K destKey) 合并 key 和 otherKeys 集合,并且将合并结果存储在目标 destKey 集合中。
reactor.core.publisher.Mono<Long> unionAndStore(K key, K otherKey, K destKey) 合并 key 和 otherKey 集合,并且将合并结果存储在目标 destKey 集合中。
示例:
@Test public void unionAndStore() throws Exception { LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>(); ReactiveZSetOperations<String,String> ops = reactiveRedisTemplate.opsForZSet(); // 添加元素 ops.addAll("zset-key1", Arrays.asList( new DefaultTypedTuple<String>("value1", 10D), new DefaultTypedTuple<String>("value2", 20D), new DefaultTypedTuple<String>("value3", 30D) )).subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("成功向zset-key1添加" + aLong + "个元素"); } }); System.out.println(queue.take()); // 添加元素 ops.addAll("zset-key2", Arrays.asList( new DefaultTypedTuple<String>("value1", 10D), new DefaultTypedTuple<String>("value2", 20D), new DefaultTypedTuple<String>("value4", 40D) )).subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("成功向zset-key2添加" + aLong + "个元素"); } }); System.out.println(queue.take()); // 合并元素 ops.unionAndStore("zset-key1", "zset-key2", "result") .subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) { queue.add("合并元素成功,元素个数:" + aLong); } }); System.out.println(queue.take()); // 输出result集合 ops.scan("result").collectList() .subscribe(new Consumer<List<ZSetOperations.TypedTuple<String>>>() { @Override public void accept(List<ZSetOperations.TypedTuple<String>> typedTuples) { for(ZSetOperations.TypedTuple<String> typedTuple : typedTuples) { System.out.println("value=" + typedTuple.getValue() + ", score=" + typedTuple.getScore()); } queue.add("result 集合中有" + typedTuples.size() + "个元素"); } }); System.out.println(queue.take()); }
运行示例,输出结果如下:
成功向zset-key1添加3个元素 成功向zset-key2添加3个元素 合并元素成功,元素个数:4 value=value1, score=20.0 value=value3, score=30.0 value=value2, score=40.0 value=value4, score=40.0 result 集合中有4个元素