Java编程技巧:if-else优化实践总结归纳
作者:朱季谦 发布时间:2022-04-14 09:04:20
一、使用策略枚举来优化if-else
看到网上蛮多人推荐使用策略模式来优化if-else,但我总觉得,搞一堆策略类来优化大批量if-else,虽然想法很好,但无意之中很可能又会创造出很多类对象,就显得过于繁重了。若想使用策略模式来优化大批量if-else,其实有一种更好的方式,这是策略模式+枚举方式的改良,我以前写过这样一篇优化文章,详细直接点击该文了解:《策略枚举:消除在项目里大批量使用if-else的优雅姿势》
二、使用三目运算符来优化if-else
1、根据if-else条件来判断赋值的,如:
String id="";
if(flag){
id="a";
}else{
id="b";
}
利用三目运算符,可以直接优化成一行代码:
id=flag?"a":"b";
2、利用if-else条件来判断调用方法,如:
Set<String> set1=new HashSet<>();
Set<String> set2=new HashSet<>();
if(flag){
set1.add(id);
}else{
set2.add(id);
}
利用三目运算符,可以直接优化成:
Set<String> set1=new HashSet<>();
Set<String> set2=new HashSet<>();
(flag?set1:set2).add(id);
三、使用Stream优化if中判断条件过多情况
Jdk1.8新特性Stream流有三个这样API,anyMatch,allMatch,noneMatch,各自的作用如下:
anyMatch:判断条件里任意一个满足条件,则返回true;
allMatch:判断条件里所有都满足条件,则返回true;
noneMatch:判断条件里所有都不满足条件,则返回true;
它们的使用方式其实很简单:
List<String> list = Arrays.asList("a", "b", "c","d", "");
//任意一个字符串判断不为空则为true
boolean anyMatch = list.stream().anyMatch( s->StringUtils.isEmpty(s));
//所有字符串判断都不为空则为true
boolean allMatch = list.stream().allMatch( s->StringUtils.isEmpty(s));
//没有一个字符判断为空则为true
boolean noneMatch = list.stream().noneMatch( s->StringUtils.isEmpty(s));
可见,根据以上三种实现方式,可以在某种程度上优化if里判断条件过多的情况,那么,在哪种场景里比较合适利用其优化呢?
在日常实际开发当中,我们可能会看到过这样存在很多判断条件的代码:
if(StringUtils.isEmpty(str1) || StringUtils.isEmpty(str2) ||
StringUtils.isEmpty(str3) || StringUtils.isEmpty(str4) ||
StringUtils.isEmpty(str5) || StringUtils.isEmpty(str6)
){
.....
}
这时,就可以考虑到,使用stream流来优化,优化后的代码如下:
if(Stream.of(str1, str2, str3, str4,str5,str6).anyMatch(s->StringUtils.isEmpty(s))){
.....
}
这样优化后,是不是就比那堆if里堆积到一块的条件更为优雅了?
当然,这只是针对或条件的,若是遇到与条件时,同样可以用Stream来优化,例如:
if(StringUtils.isEmpty(str1) && StringUtils.isEmpty(str2) &&
StringUtils.isEmpty(str3) && StringUtils.isEmpty(str4) &&
StringUtils.isEmpty(str5) && StringUtils.isEmpty(str6)
){
.....
}
使用Stream优化后:
if(Stream.of(str1, str2, str3, str4,str5,str6).allMatch(s->StringUtils.isEmpty(s))){
.....
}
四、使用Map优化if-else
优化量比较多的面向过程的if-else语句,还可以考虑使用Map来优化,虽然在一定程度上,创建一个额外map会占用内存,但那丁点内存对于现阶段计算机而言,可以说不足挂齿。下面使用一个案例来介绍下————
在一些祖传老代码当中,可能遇到过类似这样又臭又冗余的if-else写法:
public String getDay(String day){
if("Monday".equals(day)){
return "今天上英语课";
}else if("Tuesday".equals(day)){
return "今天上语文课";
}else if("Wednesday".equals(day)){
return "今天上数学课";
}else if("Thursday".equals(day)){
return "今天上音乐课";
}else if("Sunday".equals(day)){
return "今天上编程课";
}else{
......
}
}
这时,可以根据具体场景,来考虑是否可以利用Map优化,使用Map优化的方式,是先在该类中定义一个static的map,类似这样:
public static final Map<String,String> dayMap= ImmutableMap.<String, String>builder()
.put("Monday","今天上英语课")
.put("Tuesday","今天上语文课")
.put("Wednesday","今天上数学课")
.put("Thursday","今天上音乐课")
.put("Sunday","今天上编程课")
.build();
定义完后,就直接在先前使用if-else的方法里,进行这样优化:
public String getDay(String day){
return dayMap.get(day);
}
这样优化后,业务方法里的判断获取值的处理,是不是就清爽了很多,当然,这只是针对量比较多的if-else而言,若是比较少的判断语句,再额外定义一个map来搞,隐约有画蛇添足的嫌疑。
细心的读者可能会发现, 我在定义map的时候,使用到了一个ImmutableMap的东西,这是Google Guava里的一个类,可生成一个不可变的Map对象,这就意味着,初始化定义后,后续就无法再put修改了,它的这个特性可以保证线程的安全。一般用来替换if-else的map,我们就是要求在初始化定义后,就不会再允许修改了,因此,这个ImmutableMap生成的map,可以很好地帮我们实现这一点。另外,最重要一点是,使用这个ImmutableMap,可以实现链式编程,就像上面定义的链式写法,若是用传统的map定义,就每次都要map.put()、map.put()地赋值。
关于ImmutableMap的原理,我专门写一篇文章来介绍:《Java源码分析:Guava之不可变集合ImmutableMap的源码分析》
五、使用枚举优化if-else
前面提到过可使用策略枚举来优化大批量的if-else,当然,若只是判断获不同条件来取值的代码,可以考虑直接使用枚举来优化,其效果与map的处理效果类似。
还是用前面判断课程的if-else为案例来优化。
首先,先在类中定义一个枚举:
public enum dayEnum {
Monday("今天上英语课"),
Tuesday("今天上语文课"),
Wednesday("今天上数学课"),
Thursday("今天上音乐课"),
Sunday("今天上编程课");
public String value;
dayEnum(String value){
this.value=value;
}
}
定义完后,就可以类似前面map的方式,直接将判断值去枚举里获取,然后直接返回获取到的值,这样写法是不是也比较优雅了。
public String getDay(String day){
return dayEnum.valueOf(day).value;
}
六、使用Optional类优化if-else
在实际工作中,我曾经遇到类似这样的代码,看起来像没什么问题,但如果其中某个属性值不幸为null,那么,恭喜你,你将会喜提一个NullPointerException异常。
String name=school.getGrades().getStuendt().getName();
若要处理这个可能出现的空指针异常,传统写法,可以写一堆if-else语句来处理,就像这样子——
String name=null;
if(school!=null){
Grades grade=school.getGrades();
if(grade!=null){
Student student=grade.getStuendt();
if(student!=null){
name = student.getName();
}
}
}
作为一个极度讨厌if-else的人士,怎么能容忍这一堆层层嵌套的代码存在呢!
在遇到这种层层嵌套的if-else判断时,可以考虑使用jdk1.8新特性Optional 类来优化,优化后的效果如下,顿时又优雅了很多。
String name = Optional.ofNullable(school)
.flatMap(School::getGrades)
.flatMap(Grades::getStuendt)
.map(Student::getName)
.orElse(null);
来源:https://www.cnblogs.com/zhujiqian/p/14918020.html


猜你喜欢
- 前言RabbitMQ 是使用 Erlang 语言开发的消息中间件, 其遵循了高级消息队列协议(Advanced Message Queuin
- 概述异常是在程序执行期间出现的问题。C# 中的异常是对程序运行时出现的特殊情况的一种响应,比如尝试除以零。异常提供了一种把程序控制权从某个部
- 大体思路如果发总金额为 m的 n 个红包,先用一个长度为 n的临时数组 a 存放 n个随机双精度小数 ,然后用 sum表示数组
- 今天给大家带来的是仅仅使用一个TextView实现一个 * 京东、淘宝、唯品会等各种电商APP的活动倒计时。最近公司一直加班也没来得及时间去整
- 目录创建线程管理线程销毁线程创建线程线程是通过扩展 Thread 类创建的。扩展的 Thread 类调用 Start() 方法来开
- 简介:本篇博客主要包括recyclerview添加多种布局以及添加头布局和尾布局,还有item点击事件思路:主要重写Recyclerview
- 这是一个android开屏布局的实例,可以用于加载广告图片和倒计时的布局。程序中设置的LayoutParams,划分额外空间比例为6分之5,
- SpringBoot-JPA删除不成功,只执行了查询语句今天使用JPA自定义了一个删除方法deleteByUserIdAndCommentI
- 案例:图书管理(SpringBoot+Thymeleaf+SpringData-JPA)添加图书:图书基本信息及封面图片的上传及入库图书详细
- 本文为大家分享了java实现工资管理简单程序的具体代码,供大家参考,具体内容如下程序总体说明(ReadMe):总体分为四部分:管理程序(st
- 前言: Java 8已经公布有一段时间了,种种迹象表明Java 8是一个有重大改变的发行版。在Java Code Geeks上已经有很多介绍
- 最近在开发即时通讯这个模块的时候使用到了自定义的相机,需求与微信一样,要求相机能长按和轻点,当时在网上找自定义相机的资源,很少,所以,我在这
- 23种设计模式第十二篇:java模版方法模式定义:定义一个操作中算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变算法的结构即可重定义
- 1.继承Thread类,重写run方法2.实现Runnable接口,重写run方法,实现Runnable接口的实现类的实例对象作为Threa
- 最近在折腾一些控制相关的软件设计,想起来状态机这个东西,对解决一些控制系统状态切换还是挺有用的。状态机(有限状态自动机)网上有很多介绍。简单
- Java线程池并发执行多个任务Java在语言层面提供了多线程的支持,线程池能够避免频繁的线程创建和销毁的开销,因此很多时候在项目当中我们是使
- 这篇文章主要介绍了JAVA基于SnakeYAML实现解析与序列化YAML,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考
- Android CalendarView,DatePicker,TimePicker,以及NumberPicker的使用简单复习
- 移除一段文字中的HTML标记,以消除其中包含的样式和段落等,最常用的办法可能就是正则表达式了。但是请注意,正则表达式并不能处理所有的HTML
- 首先使用PImage来实例化对象,再通过loadImage赋值,两层for循环遍历图片上的像素点,每隔5个像素点,画一个直径为3的圆。颜色通