Redis(ZADD)使用Java API實現簡單排名
阿新 • • 發佈:2019-01-05
Redis
ZADD key score member [[score member] [score member] ...]
將一個或多個 member 元素及其 score 值加入到有序集 key 當中。
如果某個 member 已經是有序集的成員,那麼更新這個member 的score 值,並通過重新插入這個member 元素,來保證該member 在正確的位置上。
score 值可以是整數值或雙精度浮點數。
如果 key 不存在,則建立一個空的有序集並執行ZADD 操作。
當 key 存在但不是有序集型別時,返回一個錯誤。
- 可用版本:
- >= 1.2.0
- 時間複雜度:
- O(M*log(N)), N
- 返回值:
-
被成功新增的新成員的數量,不包括那些被更新的、已經存在的成員。
# 新增單個元素 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 值遞減(從大到小)來排列。除了成員按 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]
同分一般排名也相同,有興趣朋友可以在讀取的時候使用自定義演算法實現。