网站首页 > 文章精选 正文
位运算是java中比较基础的知识,位运算的计算速度很快,jdk中不少源码都是使用位运算(例如ArrayList,HashMap)。
但是在日常开发的过程中,我们很少会使用位运算。相比较它的计算速度的优点,它可读性不高的”缺点“似乎对于普通的业务开发来说更加突出。
我们更加乐意直接使用 +,-,*,/这些直接的运算符。
本文将给大家介绍一种位运算在业务中的应用场景,希望能给大家带来帮助,如有不对之处,欢迎指正。
本位不对位运算的基础做展开介绍,如果不熟悉位运算的基础概念的,请先自行google了解。
一、常规业务打标思路
日常业务开发的过程中,经常会有对业务模型打标 (true/false) 的需求。
例如:
true表示男生,false表示女生
true表示参与活动优惠,false表示无法参与活动优惠
true表示超级管理员,false表示普通用户
.....
一般情况下针对这种需求,我们通常会使用一个独立的字段去表示Domain的状态。随着业务的发展,需要打标的逻辑越来越多。对应到Domain/表结构中标识的字段也会不断的上升。
@Data
public class User {
private Long userId;
private String userName;
private boolean canLogin;
private boolean isMale;
private boolean isAdmin;
....
}
二、位运算优化逻辑
为了解决这种非A即B的字段标识的膨胀问题,我们可以使用位运算去整合这些字段。
例如上文展示的User Domain,我们整合canLogin,isMale,isAdmin为一个字段,认为是一个feature标识(设置字段为featureTag)。
@Data
public class User {
private Long userId;
private String userName;
private int featureTag;
}
我们可以定义一个feature的枚举定义每一位标识什么
public enum UserFeatureEnum{
CAN_LOGIN(0),
IS_MALE(1);
IS_ADMIN(2);
private int bit;
UserFeatureEnum(int bit) {
this.bit = bit;
}
public int getValue() {
return this.bit;
}
}
然后我们可以通过一下的BitUtil来check当前用户某个特性的状态
public class BitUtil {
public static int setBit(int options, int bitIndex) {
int val = 1 << bitIndex;
return options | val;
}
public static int unsetBit(int options, int bitIndex) {
int val = 1 << bitIndex;
return options & (~ val);
}
public static boolean isBitSetted(int options, int bitIndex) {
int val = 1 << bitIndex;
return (options & val) == val;
}
public static boolean isBitUnSetted(int options, int bitIndex) {
int val = 1 << bitIndex;
return (options & val) == 0;
}
}
这样我们如果去校验user是否为男性就可以这么操作
boolean isMale = BitUtil.isBitSetted(user.getfeatureTag(),UserFeatureEnum.IS_MALE.getValue());
设置当前用户为女性
user.setfeatureTag(BitUtil.unsetBit(user.getfeatureTag(),UserFeatureEnum.IS_MALE.getValue()))
设置当前用户为男性
user.setfeatureTag(BitUtil.setBit(user.getfeatureTag(),UserFeatureEnum.IS_MALE.getValue()))
这样我们将日益膨胀的标志字段给合并了,数据库也能够只用一个字段就能够标识Domain的多个feature。
后续如果需要增加一个feature时,就不需要修改表结构了,只需要增加一个枚举值及设置、判断逻辑就行。
像线上项目,改个表结构还要走一道道的DBA审批流程
三、优劣势对比
- 相比较常规的业务设计,位运算在空间节省与扩展性上更加突出,但是可读性就比较差。
- 在DB检索上,常规设计可以直接将字段作为条件进行过滤,位运算需要在条件上进行一下位运算。
- 在ES检索上,常规设计可以直接将字段作为条件进行过滤,位运算就不支持了,需要冗余出一个字段,如果Domain的存储结构是ES,并且feature字段有检索需求,那还是按照常规设计比较好。
- 如果涉及到与客户端交互的功能,版本A的client支持的功能,在版本B就不能支持了。由于客户端是安装在用户本地的,不可能一直强制用户做升级。因此这种时候可以在使用一个feature字段,标识当前客户端支持的一些特性,服务端去解析返回结果。请求参数清晰简单,动态性比较高。
四、最后
文中如有不正确之处,欢迎指正,写文不易,点个赞吧,么么哒~
作者:柏炎
链接:
https://juejin.cn/post/7122362756627431438
猜你喜欢
- 2025-05-05 一个后勾腿动作,有效疏通血管,改善下肢发麻,促进全身燃脂
- 2025-05-05 大型调相机起动及并网研究(什么是调相机,与发电机区别)
- 2025-05-05 你们都是托:动态对比度其实是骗你的
- 2025-05-05 最容易被忽视的身体素质——柔韧性
- 2025-05-05 减压阀能减静压吗?(减压阀能减静压吗视频)
- 2025-05-05 第6讲-结构设计作用(结构设计的作用)
- 2025-05-05 性能测试必懂的内存知识点(性能测试内存占用一般多少算合格)
- 2025-05-05 元王CAE仿真系列之疲劳分析篇(疲劳仿真软件)
- 2025-05-05 静态混合器在化工中的作用(静态混合器结构)
- 2025-05-05 测绘人员必读:RTK常用功能讲解(rtk测量操作步骤)
- 05-05MyBatis的三种分页方式,你学废了吗?
- 05-05如何写一个简单的分页(最简单的分页)
- 05-05详解如何使用Spring Data JPA进行数据的分页与排序
- 05-05手速太快引发分页翻车?前端竞态陷阱揭秘
- 05-05前端分页机制的具体实现(分页前端需要做什么)
- 05-05一个后勾腿动作,有效疏通血管,改善下肢发麻,促进全身燃脂
- 05-05大型调相机起动及并网研究(什么是调相机,与发电机区别)
- 05-05你们都是托:动态对比度其实是骗你的
- 最近发表
- 标签列表
-
- newcoder (56)
- 字符串的长度是指 (45)
- drawcontours()参数说明 (60)
- unsignedshortint (59)
- postman并发请求 (47)
- python列表删除 (50)
- 左程云什么水平 (56)
- 计算机网络的拓扑结构是指() (45)
- 稳压管的稳压区是工作在什么区 (45)
- 编程题 (64)
- postgresql默认端口 (66)
- 数据库的概念模型独立于 (48)
- 产生系统死锁的原因可能是由于 (51)
- 数据库中只存放视图的 (62)
- 在vi中退出不保存的命令是 (53)
- 哪个命令可以将普通用户转换成超级用户 (49)
- noscript标签的作用 (48)
- 联合利华网申 (49)
- swagger和postman (46)
- 结构化程序设计主要强调 (53)
- 172.1 (57)
- apipostwebsocket (47)
- 唯品会后台 (61)
- 简历助手 (56)
- offshow (61)