Redis 有序集合和無序集合一樣也是string類型元素的集合,且不允許重復的成員。不同的是每個元素都會關聯一個double類型的分數。有序集合的成員是唯一的,但分數(score)卻可以重復。redis正是通過分數來為集合中的成員進行從小到大的排序。
ZSetOperations提供了一系列方法對有序集合進行操作。首先初始化spring工廠獲得redisTemplate和opsForZSet
private RedisTemplate<String,Object> redisTemplate; private ZSetOperations<String, Object> opsForZSet; @SuppressWarnings("unchecked") @Before public void before(){ @SuppressWarnings("resource") ApplicationContext context = new ClassPathXmlApplicationContext("/applicationContext.xml"); redisTemplate = (RedisTemplate<String,Object>)context.getBean("redisTemplate"); opsForZSet = redisTemplate.opsForZSet(); }
Boolean add(K key, V value, double score);
Set< V > range(K key, long start, long end);
@Test public void testAdd(){ redisTemplate.delete("fan1"); //將值添加到鍵中的排序集合,如果已存在,則更新其分數。 System.out.println(opsForZSet.add("fan1", "a", 1));//true (這里的1.0可以用1代替,因為用double收參) ZSetOperations.TypedTuple<Object> objectTypedTuple1 = new DefaultTypedTuple<Object>("b",2.0);//這里必須是2.0,因為那邊是用Double收參 ZSetOperations.TypedTuple<Object> objectTypedTuple2 = new DefaultTypedTuple<Object>("c",3.0); Set<ZSetOperations.TypedTuple<Object>> tuples = new HashSet<ZSetOperations.TypedTuple<Object>>(); tuples.add(objectTypedTuple1); tuples.add(objectTypedTuple2); System.out.println(opsForZSet.add("fan1",tuples));//2 //通過索引區間返回有序集合指定區間內的成員,其中有序集成員按分數值遞增(從小到大)順序排列 System.out.println(opsForZSet.range("fan1",0,-1));//[a, b, c] }
Long remove(K key, Object… values);
@Test public void testRemove(){ redisTemplate.delete("fan2"); opsForZSet.add("fan2", "a", 1); System.out.println(opsForZSet.range("fan2", 0, -1));//[a] opsForZSet.remove("fan2", "a"); System.out.println(opsForZSet.range("fan2", 0, -1));//[] }
public Set< K > keys(K pattern)
Double incrementScore(K key, V value, double delta);
@Test public void testIncrementScore(){ redisTemplate.delete("fan3"); System.out.println(redisTemplate.keys("fan3"));//[] //通過增量增加排序集中的元素的分數 System.out.println(opsForZSet.incrementScore("fan3", "a", -1));//-1.0(可見默認技術為0) System.out.println(redisTemplate.keys("fan3"));//[fan3] }
Long rank(K key, Object o);
@Test public void testRank(){ redisTemplate.delete("fan4"); opsForZSet.add("fan4", "a", 1); opsForZSet.add("fan4", "b", 3); opsForZSet.add("fan4", "c", 2); opsForZSet.add("fan4", "d", -1); System.out.println(opsForZSet.range("fan4", 0, -1));//[d, a, c, b](從小到大) //在排序集中確定具有值的元素的索引,並返回其索引(從低到高) System.out.println(opsForZSet.rank("fan4", "b"));//3(從小到大且從零開始) }
Long reverseRank(K key, Object o);
@Test public void testReverseRank(){ redisTemplate.delete("fan5"); opsForZSet.add("fan5", "a", 1); opsForZSet.add("fan5", "b", 3); opsForZSet.add("fan5", "c", 2); opsForZSet.add("fan5", "d", -1); //當從高到低時,確定排序集中的值的元素的索引。 System.out.println(opsForZSet.reverseRank("fan5", "b"));//0(從大到小且從零開始) }
Set< TypedTuple< V >> rangeWithScores(K key, long start, long end);
@Test public void testRangeWithScores(){ redisTemplate.delete("fan6"); opsForZSet.add("fan6", "a", 1); opsForZSet.add("fan6", "b", 3); opsForZSet.add("fan6", "c", 2); opsForZSet.add("fan6", "d", -1); //從排序集中獲取開始和結束之間的元組(Tuple)。 Set<TypedTuple<Object>> rangeWithScores = opsForZSet.rangeWithScores("fan6", 0 , -1); Iterator<TypedTuple<Object>> iterator = rangeWithScores.iterator(); while(iterator.hasNext()){ TypedTuple<Object> next = iterator.next(); System.out.println("value:"+next.getValue()+" score:"+next.getScore()); /* value:d score:-1.0 value:a score:1.0 value:c score:2.0 value:b score:3.0 */ } }
Set< V > rangeByScore(K key, double min, double max);
@Test public void testRangeByScore(){ redisTemplate.delete("fan7"); opsForZSet.add("fan7", "a", 1); opsForZSet.add("fan7", "b", 3); opsForZSet.add("fan7", "c", 2); opsForZSet.add("fan7", "d", -1); //得到分數在最小和最大值之間的元素。(從小到大) Set<Object> rangeByScore = opsForZSet.rangeByScore("fan7", 1, 2); System.out.println(rangeByScore);//[a, c] //從開始到結束的范圍內獲取元素,其中分數在分類集合的最小值和最大值之間。 Set<Object> rangeByScore2 = opsForZSet.rangeByScore("fan7", 0, 10, 0, -1); System.out.println(rangeByScore2);//[a, c, b] Set<Object> rangeByScore3 = opsForZSet.rangeByScore("fan7", -1, 3, 0, 1); System.out.println(rangeByScore3);//[d] }
Set< TypedTuple< V >> rangeByScoreWithScores(K key, double min, double max);
Set< TypedTuple< V >> rangeByScoreWithScores(K key, double min, double max, long offset, long count);
@Test public void testRangeByScoreWithScores(){ redisTemplate.delete("fan8"); opsForZSet.add("fan8", "a", 1); opsForZSet.add("fan8", "b", 3); opsForZSet.add("fan8", "c", 2); opsForZSet.add("fan8", "d", -1); //得到一組元組,其中分數在分類集合的最小值和最大值之間 Set<TypedTuple<Object>> rangeByScoreWithScores = opsForZSet.rangeByScoreWithScores("fan8", 1, 2);//注意("fan8",2,1)是獲取不到數據的 Iterator<TypedTuple<Object>> iterator = rangeByScoreWithScores.iterator(); while(iterator.hasNext()){ TypedTuple<Object> next = iterator.next(); System.out.println("value:"+next.getValue()+" score:"+next.getScore()); /* value:a score:1.0 value:c score:2.0 */ } //從開始到結束的范圍內獲取一組元組,其中分數在分類集中的最小值和最大值之間。 Set<TypedTuple<Object>> rangeByScoreWithScores2 = opsForZSet.rangeByScoreWithScores("fan8", 1, 2, 1, 2); Iterator<TypedTuple<Object>> iterator2 = rangeByScoreWithScores2.iterator(); while(iterator2.hasNext()){ TypedTuple<Object> next = iterator2.next(); System.out.println("value:"+next.getValue()+" score:"+next.getScore()); /* value:c score:2.0 */ } }
Set reverseRange(K key, long start, long end);
Set< TypedTuple< V >> reverseRangeWithScores(K key, long start, long end);
Set< V > reverseRangeByScore(K key, double min, double max);
Set< TypedTuple< V >> reverseRangeByScoreWithScores(K key, double min, double max);
Set< V > reverseRangeByScore(K key, double min, double max, long offset, long count);
Set< TypedTuple< V >> reverseRangeByScoreWithScores(K key, double min, double max, long offset, long count);
@Test public void testReverseRange(){ redisTemplate.delete("fan9"); opsForZSet.add("fan9", "a", 1); opsForZSet.add("fan9", "b", 3); opsForZSet.add("fan9", "c", 2); opsForZSet.add("fan9", "d", -1); //從從高到低的排序集中獲取從頭(start)到尾(end)內的元素。 Set<Object> reverseRange = opsForZSet.reverseRange("fan9", 0, -1); System.out.println(reverseRange);//[b, c, a, d] //從開始(start)到結束(end),從排序從高到低的排序集中獲取元組的集合 Set<TypedTuple<Object>> reverseRangeWithScores = opsForZSet.reverseRangeWithScores("fan9", 0, -1); Iterator<TypedTuple<Object>> iterator = reverseRangeWithScores.iterator(); while(iterator.hasNext()){ TypedTuple<Object> next = iterator.next(); System.out.println("value:"+next.getValue()+" score:"+next.getScore()); /* value:b score:3.0 value:c score:2.0 value:a score:1.0 value:d score:-1.0 */ } //從高到低的排序集中獲取分數在最小和最大值之間的元素。 Set<Object> reverseRangeByScore = opsForZSet.reverseRangeByScore("fan9", -1, 2); System.out.println(reverseRangeByScore);//[c, a, d] //從開始到結束的范圍內獲取元素,其中分數在最小和最大之間,從排序集排序高 - >低。 Set<Object> reverseRangeByScore2 = opsForZSet.reverseRangeByScore("fan9", -1, 2, 2, 3); System.out.println(reverseRangeByScore2);//[d] //得到一組元組,其中分數在最小和最大之間,從排序從高到低 Set<TypedTuple<Object>> reverseRangeByScoreWithScores = opsForZSet.reverseRangeByScoreWithScores("fan9", -1, 2); Iterator<TypedTuple<Object>> iterator2 = reverseRangeByScoreWithScores.iterator(); while(iterator2.hasNext()){ TypedTuple<Object> next = iterator2.next(); System.out.println("value:"+next.getValue()+" score:"+next.getScore()); /* value:c score:2.0 value:a score:1.0 value:d score:-1.0 */ } //從開始到結束的范圍內獲取一組元組,其中分數在最小和最大之間,從排序集排序高 - >低。 Set<TypedTuple<Object>> reverseRangeByScoreWithScores2 = opsForZSet.reverseRangeByScoreWithScores("fan9", -1, 2, 1, 3); Iterator<TypedTuple<Object>> iterator3 = reverseRangeByScoreWithScores2.iterator(); while(iterator3.hasNext()){ TypedTuple<Object> next = iterator3.next(); System.out.println("value:"+next.getValue()+" score:"+next.getScore()); /* value:a score:1.0 value:d score:-1.0 */ } }
Long count(K key, double min, double max);
@Test public void testCount(){ redisTemplate.delete("fan10"); opsForZSet.add("fan10", "a", 1); opsForZSet.add("fan10", "b", 3); opsForZSet.add("fan10", "c", 2); opsForZSet.add("fan10", "d", -1); //計算排序集中在最小和最大分數之間的元素數。 Long count = opsForZSet.count("fan10", -1, 2); System.out.println(count);//3 }
Long size(K key);
Long zCard(K key);
@Test public void testSizeAndZCard(){ redisTemplate.delete("fan11"); opsForZSet.add("fan11", "a", 1); opsForZSet.add("fan11", "b", 3); opsForZSet.add("fan11", "c", 2); opsForZSet.add("fan11", "d", -1); //返回使用給定鍵存儲的排序集的元素數(其實size()底層就是調用的zCard()) Long size = opsForZSet.size("fan11"); System.out.println(size);//4 //使用鍵獲取排序集的大小。 Long zCard = opsForZSet.zCard("fan11"); System.out.println(zCard);//4 }
Double score(K key, Object o);
@Test public void testScore(){ redisTemplate.delete("fan12"); opsForZSet.add("fan12", "a", 1); opsForZSet.add("fan12", "b", 3); opsForZSet.add("fan12", "c", 2); opsForZSet.add("fan12", "d", -1); //使用鍵值從排序集中獲取具有值的元素的分數 Double score = opsForZSet.score("fan12", "b"); System.out.println(score);//3.0 }
Long removeRange(K key, long start, long end);
@Test public void testRemoveRange(){ redisTemplate.delete("fan13"); opsForZSet.add("fan13", "a", 1); opsForZSet.add("fan13", "b", 3); opsForZSet.add("fan13", "c", 2); opsForZSet.add("fan13", "d", -1); //使用鍵從排序集中刪除開始和結束之間范圍內的元素 Long removeRange = opsForZSet.removeRange("fan13", 1, 3); System.out.println(removeRange);//3 System.out.println(opsForZSet.zCard("fan13"));//1 }
Long removeRangeByScore(K key, double min, double max);
@Test public void testRemoveRangeByScore(){ redisTemplate.delete("fan13"); opsForZSet.add("fan13", "a", 1); opsForZSet.add("fan13", "b", 3); opsForZSet.add("fan13", "c", 2); opsForZSet.add("fan13", "d", -1); //使用鍵從排序集中移除最小和最大值之間的元素 Long removeRangeByScore = opsForZSet.removeRangeByScore("fan13", 2, 100); System.out.println(removeRangeByScore);//2 }
Long unionAndStore(K key, K otherKey, K destKey);
Long unionAndStore(K key, Collection< K > otherKeys, K destKey);
@Test public void testUnionAndStore(){ redisTemplate.delete("fan14"); redisTemplate.delete("fan15"); redisTemplate.delete("fan16"); redisTemplate.delete("fan17"); redisTemplate.delete("fan18"); opsForZSet.add("fan14", "a", 1); opsForZSet.add("fan14", "b", 3); opsForZSet.add("fan14", "c", 2); opsForZSet.add("fan14", "d", -1); opsForZSet.add("fan15", "c", 1); opsForZSet.add("fan15", "d", 3); opsForZSet.add("fan15", "e", 2); opsForZSet.add("fan15", "f", -1); //在鍵和其他鍵上的聯合排序集合,並將結果存儲在目標destIny中(注意相交的元素分數相加) Long unionAndStore = opsForZSet.unionAndStore("fan14", "fan15", "fan16"); System.out.println(unionAndStore);//6 Set<TypedTuple<Object>> rangeWithScores = opsForZSet.rangeWithScores("fan16", 0, -1); Iterator<TypedTuple<Object>> iterator = rangeWithScores.iterator(); while(iterator.hasNext()){ TypedTuple<Object> next = iterator.next(); System.out.println("value:"+next.getValue()+" score:"+next.getScore()); /* value:f score:-1.0 value:a score:1.0 value:d score:2.0 value:e score:2.0 value:b score:3.0 value:c score:3.0 可以看出,score相加了 */ } opsForZSet.add("fan17", "e", 5); opsForZSet.add("fan17", "f", -7); opsForZSet.add("fan17", "g", 31); opsForZSet.add("fan17", "h", -11); opsForZSet.add("fan17", "c", -11); //計算給定的多個有序集的並集,並存儲在新的 destKey中 Long unionAndStore2 = opsForZSet.unionAndStore("fan14", Arrays.asList("fan15","fan17"), "fan18"); System.out.println(unionAndStore2);//8 Set<TypedTuple<Object>> rangeWithScores2 = opsForZSet.rangeWithScores("fan18", 0, -1); Iterator<TypedTuple<Object>> iterator2 = rangeWithScores2.iterator(); while(iterator2.hasNext()){ TypedTuple<Object> next = iterator2.next(); System.out.println("value:"+next.getValue()+" score:"+next.getScore()); /* value:h score:-11.0 value:c score:-8.0 value:f score:-8.0 value:a score:1.0 value:d score:2.0 value:b score:3.0 value:e score:7.0 value:g score:31.0 */ } }
Long intersectAndStore(K key, K otherKey, K destKey);
Long intersectAndStore(K key, Collection< K > otherKeys, K destKey);
@Test public void testIntersectAndStore(){ redisTemplate.delete("fan19"); redisTemplate.delete("fan20"); redisTemplate.delete("fan21"); redisTemplate.delete("fan22"); redisTemplate.delete("fan23"); opsForZSet.add("fan19", "a", 1); opsForZSet.add("fan19", "b", 3); opsForZSet.add("fan19", "c", 2); opsForZSet.add("fan19", "d", -1); opsForZSet.add("fan20", "c", 1); opsForZSet.add("fan20", "d", 3); opsForZSet.add("fan20", "e", 8); opsForZSet.add("fan20", "f", -5); opsForZSet.add("fan21", "e", 1); opsForZSet.add("fan21", "f", 3); opsForZSet.add("fan21", "g", 2); opsForZSet.add("fan21", "h", -1); opsForZSet.add("fan21", "c", 9); //計算給定的一個與另一個有序集的交集並將結果集存儲在新的有序集合 key 中 Long intersectAndStore = opsForZSet.intersectAndStore("fan19", "fan20", "fan22"); System.out.println(intersectAndStore);//2 Set<TypedTuple<Object>> rangeWithScores = opsForZSet.rangeWithScores("fan22", 0, -1); Iterator<TypedTuple<Object>> iterator = rangeWithScores.iterator(); while(iterator.hasNext()){ TypedTuple<Object> next = iterator.next(); System.out.println("value:"+next.getValue()+" score:"+next.getScore()); /* value:d score:2.0 value:c score:3.0 */ } //計算給定的一個或多個有序集的交集並將結果集存儲在新的有序集合 key 中 Long intersectAndStore2 = opsForZSet.intersectAndStore("fan19", Arrays.asList("fan20","fan21"), "fan23"); System.out.println(intersectAndStore2);//1 Set<TypedTuple<Object>> rangeWithScores2 = opsForZSet.rangeWithScores("fan23", 0, -1); Iterator<TypedTuple<Object>> iterator2 = rangeWithScores2.iterator(); while(iterator2.hasNext()){ TypedTuple<Object> next = iterator2.next(); System.out.println("value:"+next.getValue()+" score:"+next.getScore()); /* value:c score:12.0 */ } }
Cursor< TypedTuple< V >> scan(K key, ScanOptions options);
@Test public void testScan(){ redisTemplate.delete("fan24"); opsForZSet.add("fan24", "a", 1); opsForZSet.add("fan24", "b", 3); opsForZSet.add("fan24", "c", 2); opsForZSet.add("fan24", "d", -1); //跟iterator一毛一樣,遍歷集合 Cursor<TypedTuple<Object>> scan = opsForZSet.scan("fan24", ScanOptions.NONE); while (scan.hasNext()){ ZSetOperations.TypedTuple<Object> item = scan.next(); System.out.println(item.getValue() + ":" + item.getScore()); /* d:-1.0 a:1.0 c:2.0 b:3.0 */ } }
轉載自:https://blog.csdn.net/weixin_37490221/article/details/78135815