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对象,其中包括容 ...
随机推荐
- union和union all的区别
UNION 写一篇联合查询(把前后两个表的查询结果集合在前表中)首先有个为什么需要 相同记录数?? 记错了.应该是union两张表的查询字段数目要一致,字段类型要相似相同的数据类型,至少是相似,可转化 ...
- javascript判断某种元素是否进入可视区域
判断是否在指定的可视区域内,先用最简单的方式,比如整个页面为可视区域 找到几个关键因素: sTop= $(window).scrollTop(); //滚动条距顶部的高度 clientHeight= ...
- day3 字典,集合,文件
一.深浅copy 浅copy只copy第一层,不copy第二层.copy后,第一层指向不同内存地址.第二层指向相同的内存地址. 导入copy模块,deepcopy深copy.deepcopy后,均指向 ...
- RMQ 训练 之 codevs 1690 开关灯 已经搞定
思路 懒标记法 记stop[rt] 表示 rt这个线段树节点的下方儿子们需要被更新几次 记住是下方 量纲不要乱 否则写的一堆渣代码 我的代码里面black是维护黑灯的数量 其实做烦了 如果是维 ...
- Windows服务器上使用bat定时执行php
windows上和linux上有一个类似的cmd和bat文件,bat文件类似于shell文件,执行这个bat文件,就相当于依次执行里面的命令(当然,还可以通过逻辑来实现编程),所以,我们可以利用bat ...
- 跨平台编程:关于VS和QT那些事
1.Win平台 Qt5.7 for Win32 (VS2013) 编辑器:Qt Creator 4.0 编译器:MSVC12 for X86 (cl.exe&link.exe) 调试器:CDB ...
- Google Developing for Android 一 - 相关上下文介绍
前几天在G+上看到Google Developers站点,有一个Android系列的文章,分享到个人微博,周末闲来没事就学写了下,把它们简单的翻译了下,没想到一发不可收拾,六篇文章全部都翻译完了,有些 ...
- 尚学堂Spring视频教程(四):使用Annotation
之前我们的bean都配置在XML里,并且通过bean的property标签来指定依赖关系,如果项目很大,那岂不是要配置很多这样的property标签?Spring提供了注解的方式来解决这个问题 @Au ...
- C++设计模式-Adapter适配器模式
Adapter适配器模式作用:将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 分为类适配器模式和对象适配器模式. 系统的数据和 ...
- 安装boost库(Windows)
1. 下载 官网:http://www.boost.org/ 主页:https://sourceforge.net/projects/boost/ 当前最新版:V1.61.0 2. 编译 首先,生成b ...