• Redis(ZADD)使用Java API实现简单排名


    Redis

    ZADD key score member [[score member] [score member] ...]

    将一个或多个 member 元素及其 score 值加入到有序集 key 当中。

    如果某个 member 已经是有序集的成员,那么更新这个memberscore 值,并通过重新插入这个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]


    同分一般排名也相同,有兴趣朋友可以在读取的时候使用自定义算法实现。



  • 相关阅读:
    POJ 1251 Jungle Roads
    ZOJ 1586 QS Network
    51nod 1001 数组中和等于k的数对
    51nod 1298 圆与三角形
    51nod 2006 二分图最大匹配
    HDU 3081 Marriage Match II 二分图最大匹配
    2017 Multi-University Training Contest
    Codeforces Round #427 (Div. 2) D. Palindromic characteristics
    HDU 4280 最大流Dinic算法优化
    POJ 3662 Telephone Lines (分层图做法)
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3067604.html
Copyright © 2020-2023  润新知