Redis从基础命令到实战之集合类型(Set)
Redis集合类型的基础功能也是存储字符串列表,和列表类型的区别是字符串不能重复且没有顺序。当然,存储元素唯一性也可以通过应用程序保证,单从这一点上并没有体现出对比列表类型的特点。
其实,集合类型的一个鲜明特性是可以对多个集合求交集、并集和差集。例如在一个社交应用中,A用户有C、D两个好友,B用户有D、E两个好友,可用通过sinter A B的命令很方便的查出A和B的共同好友。
本节中将利用这个特性给实践练习中的商品管理模块添加一个按分类查找商品的功能。
一、常用命令
import java.util.Set;
import redis.clients.jedis.Jedis;
public class SetExample {
public static void main(String[] args) {
Jedis jedis = JedisProvider.getJedis();
jedis.flushDB();
// 向sets集合中加入元素, 成功返回1, 失败返回0
Long sadd = jedis.sadd("fruit", "apple");
print("sadd fruit apple=" + sadd);
//不能添加重复元素
sadd = jedis.sadd("fruit", "apple");
print("sadd fruit apple again=" + sadd);
jedis.sadd("fruit", "banana", "orange", "grape");
// 返回所有元素
print("smembers fruit=" + jedis.smembers("fruit"));
// 删除元素
long srem = jedis.srem("fruit", "apple");
print("srem fruit apple=" + srem);
// 判断是否存在元素
boolean exists = jedis.sismember("fruit", "apple");
print("sismember fruit apple=" + exists);
exists = jedis.sismember("fruit", "banana");
print("sismember fruit banana=" + exists);
// 统计元素个数
print("scard fruit=" + jedis.scard("fruit"));
// 随机获取一个元素
print("srandmember fruit=" + jedis.srandmember("fruit"));
// 随机弹出一个元素
print("spop fruit=" + jedis.spop("fruit"));
jedis.sadd("fruit", "apple", "banana", "orange", "grape");
jedis.sadd("food", "orange", "grape", "peach", "lemon");
// 求交集
Set<String> set = jedis.sinter("fruit", "food");
print("sinter fruit food=" + set);
// 求交集并存储到指定集合
jedis.sinterstore("sinter", "fruit", "food");
print("sinterstore sinter=" + jedis.smembers("sinter"));
// 求并集
set = jedis.sunion("fruit", "food");
print("sunion fruit food=" + set);
// 求差集(fruit中有, food中没有的元素)
set = jedis.sdiff("fruit", "food");
print("sdiff fruit food=" + set);
jedis.close();
}
private static void print(String info) {
System.out.println(info);
System.out.println("------------------------------------------------------");
System.out.println();
}
}
二、实践练习
首先修改商品类,添加一个设置分类的属性 Goods.java
private Set<String> tags;
public Set<String> getTags() {
return tags;
}
public void setTags(Set<String> tags) {
this.tags = tags;
}
然后给商品管理类添加两个字符串数组用于随机获得分类
private final String[] SIZE = { "small", "middle", "big" };
private final String[] COLOR = { "red", "yellow", "green" };
修改添加商品的方法,同时保存分类信息
/**
* 添加一个商品
* @param goods
* @return
*/
public boolean addGoods(Goods goods) {
long id = getIncrementId();
Map<String, String> map = new HashMap<>();
map.put("id", String.valueOf(id));
map.put("title", goods.getTitle());
map.put("price", String.valueOf(goods.getPrice())); //随机获得三个分类
String size = SIZE[new Random().nextInt(SIZE.length)];
String color = COLOR[new Random().nextInt(COLOR.length)]; String key = "goods:" + id;
boolean added = jedis.hmset(key, map).equals("OK");
if(added) {
jedis.rpush("goods:list", String.valueOf(id));
//记录商品所属分类
jedis.sadd("goods:" + id + ":tags", size, color);
//记录每个分类下包含的商品ID
jedis.sadd("tag:" + size + ":goods", String.valueOf(id));
jedis.sadd("tag:" + color + ":goods", String.valueOf(id));
}
return added;
}
按分类查找商品
/**
* 查找指定尺寸和颜色的商品
* @param size
* @param color
* @return
*/
public List<Goods> findGoodsByTag(String size, String color) {
Set<String> ids = jedis.sinter("tag:" + size + ":goods", "tag:" + color + ":goods");
List<Goods> goodsList = new ArrayList<>();
for(String id : ids) {
String key = "goods:" + id;
Map<String, String> maps = jedis.hgetAll(key);
Goods goods = new Goods();
goods.setId(NumberUtils.toLong(maps.get("id")));
goods.setTitle(maps.get("title"));
goods.setPrice(NumberUtils.toFloat(maps.get("price")));
//读取分类
goods.setTags(jedis.smembers("goods:" + id + ":tags"));
goodsList.add(goods);
}
return goodsList;
}
测试代码
public static void main(String[] args) {
SetLession sl = new SetLession();
sl.clear();
//添加一批商品
for(int i = 0; i< 42; i++) {
Goods goods = new Goods(0, "goods" + String.format("%05d", (i + 1)), i);
sl.addGoods(goods);
}
//读取商品总数
System.out.println("商品总数: " + sl.getTotalCount());
//删除第29件商品
sl.delGoods(29);
System.out.println("删除后商品总数: " + sl.getTotalCount());
//分页显示
List<Goods> list = sl.getGoodsList(2, 20);
System.out.println("第二页商品:");
for(Goods goods : list) {
System.out.println(goods);
}
//按分类查找
List<Goods> listByTag = sl.findGoodsByTag("big", "green");
System.out.println("所有尺寸为big,颜色为green的商品:");
for(Goods goods : listByTag) {
System.out.println(goods);
}
}
Redis从基础命令到实战之集合类型(Set)的更多相关文章
- Redis从基础命令到实战之列表类型(List)
经过上一篇基于Redis散列类型的改造后,实战练习中的商品管理已经具备了增加.修改整体.修改部分属性和分页查询功能,但仍然不支持删除商品的功能.这是因为商品总数是以一个自增数字记录的,且关联了新商品k ...
- Redis从基础命令到实战之字符串类型
字符串类型是Redis中最基本的数据类型,能存储任何形式的字符串和和二进制数据.本文以代码形式列举常用的操作命令,并在实践部分演示一个简单的商品管理功能,实现了通常使用关系型数据库开发的增改查功能,注 ...
- Redis从基础命令到实战之有序集合类型(SortedSet)
有序集合类型是Redis五种数据类型中最高级的.也是最复杂的类型.有序集合具有集合类型的特性,在其基础上给每个元素关联了一个分值,或称为权重,操作时既可以在添加元素时指定分值,也可以单独修改集合中某一 ...
- Redis从基础命令到实战之散列类型(Hash)
从上一篇的实例中可以看出,用字符串类型存储对象有一些不足,在存储/读取时需要进行序列化/反序列化,即时只想修改一项内容,如价格,也必须修改整个键值.不仅增大开发的复杂度,也增加了不必要的性能开销. 一 ...
- Redis常用命令入门4:集合类型
集合类型 之前我们已经介绍过了最基本的字符串类型.散列类型.列表类型,下面我们一起学习一下集合类型. 集合类型也是体现redis一个比较高价值的一个类型了.因为Redis的集合类型,所以我们可以很容易 ...
- redis之基础命令
一.redis介绍 1.redis特性 Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件 redis是c语言编写的,支持数据持久化,是key-val ...
- redis的基础命令操作
文章目录 前言 一.字符串类型 二.哈希类型 三.列表类型 四.集合类型 五.有序集合类型 六.通过命令 前言 redis的数据结构 redis存储的是key,value格式的数据,其中的key是字符 ...
- Redis自学笔记:3.6入门-有序集合类型
3.6有序集合类型 3.6.1介绍 在集合类型基础上,为集合中每个元素都关联了一个分数,故可以获得 分数最高(最低)的前N个元素,可以获得指定范围内的元素等 有序集合中每个元素不同,但它们的分数却可以 ...
- 2015/9/4 Python基础(8):映射和集合类型
Python里唯一的映射类型是字典.映射类型对象里,hash值(key)和指向的对象(值)是一对多的关系.字典对象是可变的,这一点上很像列表,它也可以存储任意个数任意类型的Python对象,其中包括容 ...
随机推荐
- 【STM32F4】读取芯片ID和芯片Flash Size
首先声明,手册上给出的FlashSize地址是错误的,正确的应该是0x1FFF7A20,取高16位.确切说应该是(0x1FFF7A23,0x1FFF7A22两个字节), 芯片的这96位ID是产品唯一身 ...
- [Maven]Apache Maven 入门篇
作者:George Ma 上 写这个 maven 的入门篇是因为之前在一个开发者会的动手实验中发现挺多人对于 maven 不是那么了解,所以就有了这个想法.这个入门篇分上下两篇.本文着重动手,用 ma ...
- 菜单栏被flex页面遮挡解决办法
- BFS与DFS
DFS:使用栈保存未被检测的结点,结点按照深度优先的次序被访问并依次被压入栈中,并以相反的次序出栈进行新的检测. 类似于树的先根遍历深搜例子:走迷宫,你没有办法用分身术来站在每个走过的位置.不撞南山不 ...
- java中final 、finally、finalize的区别
比较java中常用关键字以免混淆 final :用来修饰变量,表示变量为最终变量,不能被改变 finally:在处理异常的时候使用,表示最终要执行的代码块 finalize:java Object类中 ...
- git的基础介绍和使用
git工作原理 git的工作原理还是比较简单的,当我们创建了本地代码仓库后,会在本地代码仓库的根目录中生成一个.git的隐藏文件. .git为一个文件目录,又叫做版本库.在本地代码仓库文件夹中,除.g ...
- Window 端口查询
1. Window环境下查询端口使用情况 方法1: 使用netstat [-参数]|findstr [端口号]来直接查询某个端口的具体使用情况 示例: netstat -ano|findstr &qu ...
- __doPostBack()没有定义解决方法(转)
有的时候想在客户端触发服务器端控件的click事件 我们这么写__doPostBack('id','') 但是为什么有的时候会失效? 因为__doPostBack()函数并没有在页面产生(如果没有类似 ...
- 关于android.view.WindowManager$BadTokenException问题出现以及解决的一些记录
1.出现 在app showdialog()时偶尔会出现,根据stackoverflow.com的描述,貌似是show的时候用作context的activity以及destroy了,,,一些异步操作会 ...
- 北京易信软科信息技术有限公司 问卷调查管理系统V2.0
北京易信软科信息技术有限公司 问卷调查管理系统V2.0 支持题目模板配置.题型模板配置.选项模板配置,报表查询功能配置 按月建表功能 运用java开发.velocity技术实现页面加载功能,高性能,高 ...