我觉得严谨对于每个程序员来说都至关重要,而写出优雅而又高效的代码是我们毕生所求。
前言
可能是处女座的原因,我对代码要求很高,我组内几位开发的代码提交前我都会review一次,过去,我pass掉了很多不满意的代码片段,有实习生写的,也有多年开发经验的同事写的。今天,突然心血来潮和大家分享一些代码片段,希望能给大家带来一些启发和灵感。
主题
受限于我们定式思维的影响,我们写出的代码,很多情况没有别人提醒,自己很难发现一些不妥的地方。
对map掌握不牢
Student student=new Student("邵磊");
Map<String, Object> map3 = new HashMap<String, Object>();
map3.put("k", "学院");
map3.put("v", student.getCollogeName());
resultlist.add( map3);
Map<String, Object> map4 = new HashMap<String, Object>();
map4.put("k", "专业");
map4.put("v", student.getMajorName());
resultlist.add( map4);
Map<String, Object> map5 = new HashMap<String, Object>();
map5.put("k", "班级");
map5.put("v", student.getBjmc());
resultlist.add(map5);
上述代码,一看就知道,这位开发很可能刚开始只是用一个map,发现list.add后所有的map都是最后一个。
起初代码大概如下
Student student=new Student("邵磊");
Map<String, Object> map = new HashMap<String, Object>();
map.put("k", "学院");
map.put("v", student.getCollogeName());
resultlist.add( map3);
map.put("k", "专业");
map.put("v", student.getMajorName());
resultlist.add( map);
这样的代码会导致map被覆盖,因为key相同导致。
那改为他的代码有什么问题吗?
主要是变量名的问题,比如按这样逻辑,你下次还需要map6,map7,map8吧,这种变量维护几次之后,删除,增加都是不优雅的,不妨改为:
Student student=new Student("邵磊");
Map<String, Object> map = new HashMap<String, Object>();
map.put("k", "学院");
map.put("v", student.getCollogeName());
resultlist.add( map3);
map = new HashMap<String, Object>();
map.put("k", "专业");
map.put("v", student.getMajorName());
resultlist.add( map);
这样,每次new 了一个hashmap,就可以省去起名不优雅的问题了。
再想想,觉得map里加k,v两个key键有些不优雅,索性改为实体类。
Student student=new Student("邵磊");
resultlist.add( new MapKV("学院",student.getCollogeName()) );
resultlist.add( new MapKV("专业",student.getMajorName()) );
而这个MapKV就不用介绍了,只有2个String k v。
对mybatis掌握不牢
public interface QuestionDao {
List<Question> getQuestionList();
}
对应的map文件QuestionMapper.xml
List<Question> questionList = QuestionDao.findBy(params);
if (mexamQuestionList == null) {
//抛异常
}
而mybatis的dao层返回的list不可能为null,即使size()=0只会返回一个new List,所以无需判断list为null
对equals不熟
if (user.get("sl").equals("邵磊")) {
//一大堆代码
}
很多人说,这个错误怎么可能有,如果前面为null会报错,但是,我全局搜索过之前的项目,难免能发现一两个,毕竟有历史遗留问题,实习生问题等。因为我们知道null不能.equals,改为:
if ("邵磊".equals(user.get("sl"))) {
//一大堆代码
}
滥用toString
user.get("sl").toString();
而一旦前面为null就报错,null不能有任何方法。
对return不熟
public String getResult() {
if ("条件") {
//一大堆代码
return "结果";
}else {
//一大堆代码
return "结果";
}
}
既然有return了确定以下代码不走,就可以放心大胆放出来
public String getResult() {
if ("条件") {
//一大堆代码
return "结果";
}
//一大堆代码
return "结果";
}
不会使用continue,break、if过长
比如查找某个list中某个姓名,当查找到了,要及时的break,来节约cpu。
for (int i = list.size() - 1; i >= 0; i--) {
if ("邵磊".equals(list.get(i).getName())) {
user=list.get(i);
}
}
改为
for (int i = list.size() - 1; i >= 0; i--) {
if ("邵磊".equals(list.get(i).getName())) {
user=list.get(i);
break;
}
}
假设除某个姓名的人,不执行某些操作,代码如下:
for (int i = list.size() - 1; i >= 0; i--) {
if ("邵磊".equals(list.get(i).getName())) {
//这里只有2件事。
user=list.get(i);
}else{
//这里做很多事情
}
}
这时,我们可以去掉if,并使用continue
for (int i = list.size() - 1; i >= 0; i--) {
if ("邵磊".equals(list.get(i).getName())) {
//这里只有2件事。
user=list.get(i);
continue;
}
//这里做很多事情
}
continue:跳出本次循环继续下一次循环
break: 跳出循环体,继续执行循环外的函数体
return: 跳出整个函数体,函数体后面的部分不再执行
对for循环不熟
if (list.size()==0) {
for (int i = list.size() - 1; i >= 0; i--) {
//做事情
}
}
而我们知道即使list.size()==0也不会影响代码,不如直接
for (int i = list.size() - 1; i >= 0; i--) {
//做事情
}
错用try catch
try catch包裹一大块
try {
//这段代码可能异常
//下面代码不会异常
//此处代码不会异常
//此处代码不会异常
} catch (Exception e) {
//报错
}
不如改为
try {
//这段代码可能异常
} catch (Exception e) {
//报错
}
//下面代码不会异常
//此处代码不会异常
//此处代码不会异常
这样可读性更高,更优雅,当然了,也可以使用throws来捕获异常。
try catch写在for循环里
for (int i = list.size() - 1; i >= 0; i--) {
try {
//这段代码可能异常
} catch (Exception e) {
//报错
}
//下面代码不会异常
}
我们知道try catch 会把整段代码包裹起来执行,这是需要耗费资源的,频繁的trycatch,除特殊情况,否则可抽取出方法,把方法包裹起来即可。
重复代码片段
比如一个方法,在某个类里,多次调用,而只有部分变量不同,可以抽取出方法及变量,来使代码简洁
不使用case
if(type==1){
}else if(type==2){
}else if(type==3){
}else if(type==4){
}
…………
这样写下去会写很长的if,而我们知道使用case也可以解决string匹配问题,在java 7及以上,支持case 字符串。
switch(参数) {
case 常量表达式1: break;
case 常量表达式2: break;
...
default: break;
}
未采用懒加载
如
String str = "邵磊";
if (i == 1){
list.add(str);
}
可改为
if (i == 1){
String str = "邵磊";
list.add(str);
}
不断创建对象引用
for (int i = 1; i <= 100; i++)
{
Object obj = new Object();
//其他代码
}
这样做,只会在内存里开辟很多Object对象的引用,可改为
Object obj;
for (int i = 1; i <= 100; i++)
{
obj = new Object();
//其他代码
}
总结
我们解决问题,可能有很多种思路,也能写出很多种代码来,但是把代码写的优雅却是一个技术活,当然了,本次先介绍部分,关注度高的话,我继续更新。
最后,我想补充一句,其实我不是处女座,只是别人会这么说我,所以我认了。
觉得好的话,记得关注我哦!
掘金:
https://juejin.im/user/57cd55218ac247006459c40c