Redis
ZADD key score member [[score member] [score member] ...]
將一個或多個 member 元素及其 score 值加入到有序集 key 當中。
如果某個 member 已經是有序集的成員,那么更新這個 member 的 score 值,并通過重新插入這個 member 元素,來保證該 member 在正確的位置上。
score 值可以是整數值或雙精度浮點數。
如果 key 不存在,則創建一個空的有序集并執行 ZADD 操作。
當 key 存在但不是有序集類型時,返回一個錯誤。
對有序集的更多介紹請參見 sorted set 。
- 可用版本:
- >= 1.2.0
- 時間復雜度:
- O(M*log(N)), N 是有序集的基數, M 為成功添加的新成員的數量。
- 返回值:
-
被成功添加的新成員的數量,不包括那些被更新的、已經存在的成員。
?
# 添加單個元素 redis> ZADD page_rank 10 google.com (integer) 1 # 添加多個元素 redis> ZADD page_rank 9 baidu.com 8 bing.com (integer) 2 redis> ZRANGE page_rank 0 -1 WITHSCORES 1) "bing.com" 2) "8" 3) "baidu.com" 4) "9" 5) "google.com" 6) "10" # 添加已存在元素,且 score 值不變 redis> ZADD page_rank 10 google.com (integer) 0 redis> ZRANGE page_rank 0 -1 WITHSCORES # 沒有改變 1) "bing.com" 2) "8" 3) "baidu.com" 4) "9" 5) "google.com" 6) "10" # 添加已存在元素,但是改變 score 值 redis> ZADD page_rank 6 bing.com (integer) 0 redis> ZRANGE page_rank 0 -1 WITHSCORES # bing.com 元素的 score 值被改變 1) "bing.com" 2) "6" 3) "baidu.com" 4) "9" 5) "google.com" 6) "10"
?
?
ZREVRANGE key start stop [WITHSCORES]
返回有序集 key 中,指定區間內的成員。
除了成員按 score 值遞減的次序排列這一點外, ZREVRANGE 命令的其他方面和 ZRANGE 命令一樣。
- 可用版本:
- >= 1.2.0
- 時間復雜度:
- O(log(N)+M), N 為有序集的基數,而 M 為結果集的基數。
- 返回值:
- 指定區間內,帶有 score 值(可選)的有序集成員的列表。
?
redis> ZRANGE salary 0 -1 WITHSCORES # 遞增排列 1) "peter" 2) "3500" 3) "tom" 4) "4000" 5) "jack" 6) "5000" redis> ZREVRANGE salary 0 -1 WITHSCORES # 遞減排列 1) "jack" 2) "5000" 3) "tom" 4) "4000" 5) "peter" 6) "3500"
?
?
API實戰代碼(排名的添加和讀取):
User(用戶類):
?
package com.duobei.model; import java.io.Serializable; public class User implements Serializable { private static final long serialVersionUID = 1L; private String id; //編號 private String name; //姓名 private double score; //得分 private int rank; //排名 public User() { } public User(String id, String name, double score) { this.id = id; this.name = name; this.score = score; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getScore() { return score; } public void setScore(double score) { this.score = score; } public int getRank() { return rank; } public void setRank(int rank) { this.rank = rank; } @Override public String toString() { return "User [id=" + id + ", name=" + name + ", score=" + score + ", rank=" + rank + "]"; } }
自定義序列化封裝類:
?
?
package com.duobei.tools; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class ObjectSer { /** * 對象序列化 * @param obj * @return */ public static byte[] ObjectToByte(Object obj) { byte[] bytes = null; try { ByteArrayOutputStream bo = new ByteArrayOutputStream(); ObjectOutputStream oo = new ObjectOutputStream(bo); oo.writeObject(obj); bytes = bo.toByteArray(); bo.close(); oo.close(); } catch(Exception e) { e.printStackTrace(); } return bytes; } /** * 反序列化 * @param bytes * @return */ public static Object ByteToObject(byte[] bytes) { Object object = null; try { ByteArrayInputStream bais = new ByteArrayInputStream(bytes); ObjectInputStream ois = new ObjectInputStream(bais); object = ois.readObject(); } catch (Exception e) { e.printStackTrace(); } return object; } }
測試類(添加后讀取):
?
?
package com.duobei.test; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Set; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import redis.clients.jedis.ShardedJedis; import redis.clients.jedis.ShardedJedisPool; import com.duobei.model.User; import com.duobei.tools.ObjectSer; public class RankingTest { private ApplicationContext context; private ShardedJedisPool shardedJedisPool; private ShardedJedis jedis; public RankingTest() { } @Before public void init() throws Exception { String config[] = { "applicationContext.xml" }; context = new ClassPathXmlApplicationContext(config); shardedJedisPool = (ShardedJedisPool) context.getBean("shardedJedisPool"); jedis = (ShardedJedis) shardedJedisPool.getResource(); } @Test @Ignore public void rankAdd() { User user1 = new User("12345", "常少鵬", 99.9); User user2 = new User("12346", "王卓卓", 99.8); User user3 = new User("12347", "鄒雨欣", 96.8); User user4 = new User("12348", "鄭偉山", 98.8); User user5 = new User("12349", "李超杰", 99.6); User user6 = new User("12350", "董明明", 99.0); User user7 = new User("12351", "陳國峰", 100.0); User user8 = new User("12352", "楚曉麗", 99.6); jedis.zadd("game".getBytes(), user1.getScore(), ObjectSer.ObjectToByte(user1)); jedis.zadd("game".getBytes(), user2.getScore(), ObjectSer.ObjectToByte(user2)); jedis.zadd("game".getBytes(), user3.getScore(), ObjectSer.ObjectToByte(user3)); jedis.zadd("game".getBytes(), user4.getScore(), ObjectSer.ObjectToByte(user4)); jedis.zadd("game".getBytes(), user5.getScore(), ObjectSer.ObjectToByte(user5)); jedis.zadd("game".getBytes(), user6.getScore(), ObjectSer.ObjectToByte(user6)); jedis.zadd("game".getBytes(), user7.getScore(), ObjectSer.ObjectToByte(user7)); jedis.zadd("game".getBytes(), user8.getScore(), ObjectSer.ObjectToByte(user8)); } @Test //@Ignore public void gameRankShow() { Set<byte[]> set = jedis.zrevrange("game".getBytes(), 0, -1); Iterator<byte[]> iter = set.iterator(); int i = 1; List<User> list = new ArrayList<User>(); while(iter.hasNext()) { User user = (User) ObjectSer.ByteToObject(iter.next()); user.setRank(i++); list.add(user); } for(User user : list) System.out.println(user); } }
測試結果:
?
?
User [id=12351, name=陳國峰, score=100.0, rank=1] User [id=12345, name=常少鵬, score=99.9, rank=2] User [id=12346, name=王卓卓, score=99.8, rank=3] User [id=12352, name=楚曉麗, score=99.6, rank=4] User [id=12349, name=李超杰, score=99.6, rank=5] User [id=12350, name=董明明, score=99.0, rank=6] User [id=12348, name=鄭偉山, score=98.8, rank=7] User [id=12347, name=鄒雨欣, score=96.8, rank=8]
同分一般排名也相同,有興趣朋友可以在讀取的時候使用自定義算法實現。
?
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
