Java版的Redis各种类型的使用方法
来源:互联网 发布:电脑版数据恢复精灵 编辑:程序博客网 时间:2024/05/17 02:30
Java版的Redis
分类: NoSql Java 业余项目2012-06-20 16:12 587人阅读 评论(2) 收藏 举报
Redis是一个基于Key-value结构的Nosql数据库,它支持各种常见的数据结构以及非常方便的操作,
与其说它是一个数据库,不如说它是一个保存各种数据结构的服务器。今天闲来没事,用Java集合类
实现了Redis的一些基本功能,算是温习下Java了。
1.Redis入门
Redis的Key键值为字符串,但是Value值支持许多种类型,如String字符串,List链表,Set无序集合,
SortedSet有序集合,甚至是Hash表。
各种数据结构通过不同的存取方法来区分。如Set/Get直接将值存为String,LPush/LPop/LRange将
值存到一个链表中,SAdd/ZAdd则区分了无序和有序集合。
下面我们来看下在Java中使用基本的集合类如何实现这些简单而方便的操作。
2.Java版的Redis
代码的组织结构如下图:
- package com.cdai.studio.redis;
- import java.util.HashSet;
- import java.util.LinkedList;
- import java.util.TreeSet;
- @SuppressWarnings("unchecked")
- public class RedisDB {
- private Persistence persistence = new Persistence();
- private Serializer serializer = new Serializer();
- private static final Object[] NULL = new Object[0];
- // =================================================
- // String value
- // =================================================
- public void Set(String key, Object value) {
- persistence.put(key, serializer.marshal(value));
- }
- public Object Get(String key) {
- return serializer.unmarshal(persistence.get(key));
- }
- public Object[] MGet(String... keys) {
- Object[] values = new Object[keys.length];
- for (int i = 0; i < keys.length; i++)
- values[i] = Get(keys[i]);
- return values;
- }
- public int Incr(String key) {
- Object value = Get(key);
- Integer valueRef = (value == null) ? 1 : (Integer) value;
- Set(key, valueRef + 1);
- return valueRef;
- }
- // =================================================
- // List value
- // =================================================
- public void LPush(String key, Object... values) {
- Object list = persistence.get(key);
- if (list == null)
- list = new LinkedList<Object>();
- else
- list = serializer.unmarshal(list);
- LinkedList<Object> listRef = (LinkedList<Object>) list;
- for (Object value : values)
- listRef.addFirst(value);
- persistence.put(key, serializer.marshal(list));
- }
- public void RPush(String key, Object... values) {
- Object list = persistence.get(key);
- if (list == null)
- list = new LinkedList<Object>();
- else
- list = serializer.unmarshal(list);
- LinkedList<Object> listRef = (LinkedList<Object>) list;
- for (Object value : values)
- listRef.addLast(value);
- persistence.put(key, serializer.marshal(list));
- }
- public Object[] LRange(String key, int start, int end) {
- Object list = persistence.get(key);
- if (list == null)
- return NULL;
- LinkedList<Object> listRef = (LinkedList<Object>) serializer.unmarshal(list);
- if (end > listRef.size())
- end = listRef.size();
- return listRef.subList(start, end).toArray();
- }
- // =================================================
- // Unsorted Set value
- // =================================================
- public void SAdd(String key, Object... values) {
- Object set = persistence.get(key);
- if (set == null)
- set = new HashSet<Object>();
- else
- set = serializer.unmarshal(set);
- HashSet<Object> setRef = (HashSet<Object>) set;
- for (Object value : values)
- setRef.add(value);
- persistence.put(key, serializer.marshal(set));
- }
- public Object[] SMembers(String key) {
- Object set = persistence.get(key);
- if (set == null)
- return NULL;
- set = serializer.unmarshal(set);
- return ((HashSet<Object>) set).toArray();
- }
- public Object[] SInter(String key1, String key2) {
- Object set1 = persistence.get(key1);
- Object set2 = persistence.get(key2);
- if (set1 == null || set2 == null)
- return NULL;
- HashSet<Object> set1Ref = (HashSet<Object>) serializer.unmarshal(set1);
- HashSet<Object> set2Ref = (HashSet<Object>) serializer.unmarshal(set2);
- set1Ref.retainAll(set2Ref);
- return set1Ref.toArray();
- }
- public Object[] SDiff(String key1, String key2) {
- Object set1 = persistence.get(key1);
- Object set2 = persistence.get(key2);
- if (set1 == null || set2 == null)
- return NULL;
- HashSet<Object> set1Ref = (HashSet<Object>) serializer.unmarshal(set1);
- HashSet<Object> set2Ref = (HashSet<Object>) serializer.unmarshal(set2);
- set1Ref.removeAll(set2Ref);
- return set1Ref.toArray();
- }
- // =================================================
- // Sorted Set value
- // =================================================
- public void ZAdd(String key, Object... values) {
- Object set = persistence.get(key);
- if (set == null)
- set = new TreeSet<Object>();
- else
- set = serializer.unmarshal(set);
- TreeSet<Object> setRef = (TreeSet<Object>) set;
- for (Object value : values)
- setRef.add(value);
- persistence.put(key, serializer.marshal(set));
- }
- public Object[] SRange(String key, Object from) {
- Object set = persistence.get(key);
- if (set == null)
- return NULL;
- set = serializer.unmarshal(set);
- return ((TreeSet<Object>) set).tailSet(from).toArray();
- }
- }
- package com.cdai.studio.redis;
- import java.io.ByteArrayInputStream;
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.io.ObjectInputStream;
- import java.io.ObjectOutputStream;
- import java.io.Serializable;
- import java.util.Arrays;
- class Serializer {
- Object marshal(Object object) {
- if (object == null)
- return null;
- return new BytesWrapper((Serializable) object);
- }
- Object unmarshal(Object object) {
- if (object == null)
- return null;
- return ((BytesWrapper) object).readObject();
- }
- }
- class BytesWrapper {
- private byte[] bytes;
- <T extends Serializable> BytesWrapper(T object) {
- writeBytes(object);
- }
- <T extends Serializable> void writeBytes(T object) {
- try {
- ByteArrayOutputStream buffer = new ByteArrayOutputStream();
- ObjectOutputStream output = new ObjectOutputStream(buffer);
- output.writeObject(object);
- output.flush();
- bytes = buffer.toByteArray();
- output.close();
- }
- catch (IOException e) {
- e.printStackTrace();
- throw new IllegalStateException(e);
- }
- }
- Object readObject() {
- try {
- ObjectInputStream input = new ObjectInputStream(new ByteArrayInputStream(bytes));
- Object object = input.readObject();
- input.close();
- return object;
- }
- catch (Exception e) {
- e.printStackTrace();
- throw new IllegalStateException(e);
- }
- }
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + Arrays.hashCode(bytes);
- return result;
- }
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- BytesWrapper other = (BytesWrapper) obj;
- if (!Arrays.equals(bytes, other.bytes))
- return false;
- return true;
- }
- }
- package com.cdai.studio.redis;
- import java.util.HashMap;
- class Persistence {
- private HashMap<String, Object> storage =
- new HashMap<String, Object>();
- void put(String key, Object value) {
- storage.put(key, value);
- }
- Object get(String key) {
- return storage.get(key);
- }
- }
3.简单的客户端
- package com.cdai.studio.redis;
- import java.io.IOException;
- import java.io.ObjectInputStream;
- import java.io.ObjectOutputStream;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.util.List;
- public class RedisServer {
- private RedisDB redis;
- public RedisServer(RedisDB redis) {
- this.redis = redis;
- }
- @SuppressWarnings("unchecked")
- public void start() {
- ServerSocket serverSocket = null;
- try {
- serverSocket = new ServerSocket(1234);
- while (true) {
- Socket socket = serverSocket.accept();
- ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
- List<Object> request = (List<Object>) input.readObject();
- Object response = null;
- if ("Set".equals(request.get(0))) {
- redis.Set((String) request.get(1), request.get(2));
- }
- else if ("Get".equals(request.get(0))) {
- response = redis.Get((String) request.get(1));
- }
- ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
- output.writeObject(response);
- input.close();
- output.close();
- socket.close();
- }
- }
- catch (Exception e) {
- e.printStackTrace();
- }
- finally {
- if (serverSocket != null) {
- try {
- serverSocket.close();
- } catch (IOException e) {
- }
- }
- }
- }
- }
- package com.cdai.studio.redis;
- import java.io.ObjectInputStream;
- import java.io.ObjectOutputStream;
- import java.io.Serializable;
- import java.net.Socket;
- import java.util.Arrays;
- import java.util.List;
- public class RedisClient {
- public <T extends Serializable> void Set(String key, Object value) {
- sendRequest(Arrays.asList("Set", key, value));
- }
- public Object Get(String key) {
- return sendRequest(Arrays.<Object>asList("Get", key));
- }
- private Object sendRequest(List<Object> payload) {
- Socket socket = null;
- try {
- socket = new Socket("localhost", 1234);
- ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
- output.writeObject(payload);
- output.flush();
- ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
- Object response = input.readObject();
- output.close();
- input.close();
- return response;
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (socket != null) {
- try {
- socket.close();
- } catch (Exception e) {
- }
- }
- }
- return null;
- }
- }
4.实现简单的Twitter
- package com.cdai.studio.redis;
- import java.util.Arrays;
- public class RedisTest {
- public static void main(String[] args) {
- RedisDB redis = new RedisDB();
- // 1.Create user follow relationship
- redis.SAdd("users", "A", "B", "C");
- // User A follows B, C
- redis.SAdd("users:A:following", "B", "C");
- redis.SAdd("users:B:followers", "A");
- redis.SAdd("users:C:followers", "A");
- // User C follows B
- redis.SAdd("users:C:following", "B");
- redis.SAdd("users:B:followers", "C");
- // 2.1 B send tweet
- int tid = redis.Incr("tweets:next_id");
- redis.Set("tweets:" + tid, "B publish hello");
- redis.LPush("global:timeline", tid);
- redis.LPush("users:B:timeline", tid);
- for (Object follower : redis.SMembers("users:B:followers"))
- redis.LPush("users:" + follower + ":timeline", tid);
- // 2.2 C send tweet
- tid = redis.Incr("tweets:next_id");
- redis.Set("tweets:" + tid, "C publish world");
- redis.LPush("global:timeline", tid);
- redis.LPush("users:C:timeline", tid);
- for (Object follower : redis.SMembers("users:C:followers"))
- redis.LPush("users:" + follower + ":timeline", tid);
- Object[] tids = redis.LRange("global:timeline", 0, 9);
- String[] tweetids = new String[tids.length];
- for (int i = 0; i < tids.length; i++)
- tweetids[i] = "tweets:" + tids[i];
- System.out.println(Arrays.toString(redis.MGet(tweetids)));
- }
- }
5.需要注意的问题
byte数组的equals和hashcode默认实现比较对象地址的,要借助于Arrays的equals和hashcode方法。
String字符串序列化和反序列化时要注意编码格式的问题,编码解码时应该使用相同的编码。
HashSet上的操作,removeAll补集,retainAll交集,addAll并集。
6.更加强大的Redis
Redis自己实现了各种数据结构,可以非常方便地增删改查,并且效率很高。这里我们只是用
Java来简单的学习了下Redis基本功能,其实Redis还支持很多其他的高级功能,如消息订阅、
数据过期设置、事务、数据持久化。想要进一步学习的话可以试着用Java实现它们。
- Java版的Redis各种类型的使用方法
- redis各种类型的存储情况分析
- vector,map各种容器类型的使用方法总结
- Redis各种数据结构(类型)的简要区别
- Toast的各种使用方法
- for_each的各种使用方法
- AutoLayout的各种使用方法
- AutoLayout的各种使用方法
- Toolbar的各种使用方法
- AutoLayout的各种使用方法
- AutoLayout的各种使用方法
- SlidingMenu的各种使用方法
- java的各种变量类型的转换
- Java的各种类型转换的例子
- 一个java Enumeration类型的使用方法
- Java的枚举类型使用方法详解
- Java的枚举类型使用方法详解
- php redis 的使用方法
- 原来Java的类名,方法名,变量名,参数名可以用中文啊
- 从一个表数据导入到另外一个表
- PHP安装全攻略
- 隐藏键盘的三种方法
- 全国软件设计大赛--递归求数组中最大元素
- Java版的Redis各种类型的使用方法
- 最小生成树之prim算法
- smarty中的修改器
- 妙用png的"逐次逼近显示"
- #pragma warning
- 如何分析一个产品?
- 10条HTML容易出错的转义符
- 如何在线打开word文档并高亮显示指定关键字
- Ubuntu 下rename 命令的使用