java 判断true false_编程技巧:使用整数同时进行多个true|false判断

情景 :

假设需要判断某银行用户的其中一个账号(profileA),币种(Currency)为人民币(CNY),余额是否大于1,0000,然后进行某业务逻辑处理。

概述:

为了进行这种判断,需要判断/验证该账号是否为profileA、币种是否为CNY,余额是否大于1,0000这3种情况,在代码中可能会写出一大堆if...else语句,不仅不雅观,还不便于理解。如果使用一个整数int来同时标识多个判断的结果,就可以避免一大堆if...else的情况。当然这个例子只是作为demo说明情况,具体怎么处理还得根据实际出发,而且要是需要作更多判断,这个方法就会更实用。

分析说明:

对于计算机来说,所有数据都是由二进制数来表示,对于每一位(bit)来说,有0或1这2种情况,分别对应的boolean值为false和true。在Java中,每个int的大小为4 byte(注意是基本类型的int,而不是引用类型的Integer),一共有4*8=32位(bit),每一个位可对应一个boolean值的话,那么1个int最多可以同时对应32个boolean值。

以JDK中的实现,java.lang.reflect.Modifier为例:

定义每个二进制位数上的含义(modifier),并得到相应十六进制数;(其实十进制也可以,只是在十六进制下其实就是1/2/4/8这几个数字在不同的位上循环,比十进制数要直观,可以在下图感受一下)

如果同时验证多个条件,可以通过逻辑与(OR, "|")将多个条件组合起来。例如可以自定义“同时满足public、static、final这3个修饰词”这个条件:

public static final int PUBLIC_STATIC_FINAL = PUBLIC | STATIC | FINAL;

将要验证的编码(整数)传入,与modifier进行逻辑与(AND, "&")运算,所得结果再与modifier比较即可;

return (mod & modifier) == modifier;

b34baff8bc57c9cd98b703d39c136c19.png

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 public classModifier{2 public static final int PUBLIC = 0x00000001; //0001

3 public static final int PRIVATE = 0x00000002; //0010

4 public static final int PROTECTED = 0x00000004; //0100

5 public static final int STATIC = 0x00000008; //1000

6 ......7 public static boolean isPublic(intmod) {8 return (mod & PUBLIC) != 0;9 }10 ......11 }

展开/收起

验证:主要看System.out.println();打印输出的几行即可,其他都是辅助理解。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 packagecom.scv.lawrence;2 importjava.lang.reflect.Field;3 importjava.lang.reflect.Modifier;4

5 public classDemo {6 public static final int STATIC_FINAL = Modifier.STATIC |Modifier.FINAL;7 public static final int PUBLIC_STATIC_FINAL = Modifier.PUBLIC | Modifier.STATIC |Modifier.FINAL;8

9 public static boolean compare(int mod, inttoken){10 return (mod & token) ==token;11 }12

13 private static int age = 999;14 private static final String name = "Lawrence";15 public final String gender = "Male";16

17 public static final int PUBLIC_STATIC = Modifier.PUBLIC |Modifier.STATIC;18

19 public static void main(String[] args) throwsException {20 Field myAge = Demo.class.getDeclaredField("age");21 Field myName = Demo.class.getDeclaredField("name");22 Field myGender = Demo.class.getDeclaredField("gender");23

24 int ageMod =myAge.getModifiers();25 int nameMod =myName.getModifiers();26 int genderMod =myGender.getModifiers();27

28 System.out.println("age的modifier(十进制): " +ageMod);29 System.out.println("\t" + "是否包含static和final:" +compare(ageMod, STATIC_FINAL));30 System.out.println("\t" + "是否包含static:" +compare(ageMod, Modifier.STATIC));31

32 System.out.println("************");33 System.out.println("name的modifier(十进制): " +nameMod);34 System.out.println("\t" + "是否包含static和final:" +compare(nameMod, STATIC_FINAL));35 System.out.println("\t" + "是否包含static:" +compare(nameMod, Modifier.STATIC));36

37 System.out.println("************");38 System.out.println("gender的modifier(十进制): " +genderMod);39 System.out.println("\t" + "是否包含static和final:" +compare(genderMod, STATIC_FINAL));40 System.out.println("\t" + "是否包含static:" +compare(genderMod, Modifier.STATIC));41 }42

43 }44

45 /*output:46 *47 * age的modifier(十进制): 1048 * 是否包含static和final:false49 * 是否包含static:true50 * ************51 * name的modifier(十进制): 2652 * 是否包含static和final:true53 * 是否包含static:true54 * ************55 * gender的modifier(十进制): 1756 * 是否包含static和final:false57 * 是否包含static:false58 */

展开/收起

场景应用:

自定义Profile类,在实例化的时候就计算并保存其类型;

在ToolBox类中定义各种标识的含义;

在main()中对profile进行验证并执行相应业务逻辑;

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 packagecom.scv.lawrence;2

3 public classFragment {4

5 public static voidmain(String[] args) {6 Profile[] profiles = {new Profile("ABC0001", "CNY", 12_0000),7 new Profile("SRC0001", "CNY", 21_0000), //target profile

8 new Profile("ZZZ666GRE", "USD", 9000)};9

10 for(Profile p: profiles){11 if(ToolBox.isTargetProfile(p, ToolBox.PRO_A_CNY_GT)){12 //Do something.

13 System.out.println("Got target profile.");14 };15 }16

17 }18

19 }20

21 classToolBox{22 public static final int PROFILE_A = 0x0000_0001; //0001

23 public static final int CNY = 0x0000_0002; //0010

24 public static final int GT_10K = 0x0000_0004; //0100

25 public static final int LT_10K = 0x0000_0008; //1000

26

27 public static final int PRO_A_CNY_GT = PROFILE_A | CNY | GT_10K; //0111,profileA、币种为人民币、余额大于1,0000

28 public static final int PRO_A_CNY_LT = PROFILE_A | CNY | LT_10K; //1111,profileA、币种为人民币、余额不足1,0000

29

30 protected static voidsetToken(Profile p){31 if("SRC0001".equals(p.getName())) p.token += 0x00000001;32 if("CNY".equals(p.getCurrency())) p.token += 0x00000002;33 if(p.getBalance() > 1_0000) p.token += 0x00000004;34 }35

36 public static boolean isTargetProfile(Profile p, intmod){37 return (p.getToken() & mod) ==mod;38 }39 }40

41 classProfile{42 privateString name;43 privateString currency;44 private doublebalance;45 protected inttoken;46

47 public intgetToken(){48 return this.token;49 }50

51 publicProfile() {}52 public Profile(String name, String currency, doublebalance){53 this.name =name;54 this.currency =currency;55 this.balance =balance;56 ToolBox.setToken(this);57 }58 publicString getName() {59 returnname;60 }61 public voidsetName(String name) {62 this.name =name;63 }64 publicString getCurrency() {65 returncurrency;66 }67 public voidsetCurrency(String currency) {68 this.currency =currency;69 }70 public doublegetBalance() {71 returnbalance;72 }73 public void setBalance(doublebalance) {74 this.balance =balance;75 };76

77

78 }

View Code

如要添加新的业务,只需要在ToolBox定义新的内容,即可。

p.s:数字下划线是JDK 1.7的语法糖,仅有方便阅读(人类)的作用,编译时会自动去掉。如1_0000_0000、100_000_000、100000000这几个数字在编译后都一样,但极大地方便了阅读。

优点:

代码量少,避免大量if...else判断,易于维护;

高效;

缺点:

初次接触的话可能不易理解;

与switch相比:

轻松进行多个条件的判断,且可以进行子集条件的判断,即对于满足A|B|C|D的条件,也会同时满足A|B、B|D或B|C|D等等。switch并不具备这样的能力。

如有纰漏,还望指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值