Redis(ZADD)使用Java API实现简单排名
2013-05-08 17:40
661 查看
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 值递减(从大到小)来排列。
具有相同 score 值的成员按字典序的逆序(reverse lexicographical order)排列。
除了成员按 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]
同分一般排名也相同,有兴趣朋友可以在读取的时候使用自定义算法实现。
相关文章推荐
- Redis(ZADD)使用Java API实现简单排名
- Python使用Redis实现作业调度系统(超简单)
- Redis-port安装使用实现redis迁移codis,以及简单redis pipe实现将mysql迁移redis
- 简单使用redis实现sso单点登录
- API接口非幂等性问题及使用redis实现简单的分布式锁
- 使用Redis的脚本功能实现Redis中数据简单查询
- 使用Redis List简单实现抢红包
- Redis使用总结(3):实现简单的消息队列
- 使用Redis的脚本功能实现Redis中数据简单查询
- python实现简单redis客户端(3)使用asyncio添加异步支持
- 使用simple_flow 10行代码简单实现redis的复制功能
- Python使用Redis实现一个简单作业调度系统
- Python使用Redis实现作业调度系统(超简单)
- Python使用Redis实现作业调度系统(超简单)
- Redis:使用SET命令实现简单的高可用(HA)
- redis之安装与简单使用
- 使用回调函数实现一个简单的计算器;
- 使用KEIL C51实现的简单合作式多任务操作系统内核