java代码优化和规范

前言:

在日常开发中我们为什么要进行代码的代码优化。每个人写代码的习惯是不一样的但是持续的写一些效率低的代码持而久之会养成习惯。提升自己代码的质量、效率、可读性才会让自己的整体有更好的提升。

也许一两个的优化,对于提升代码的运行效率意义不大,但是只要处处都能注意代码的优化,对于项目的整体提升效率都是很有用的。

代码优化的目的:

  1. 减小代码的体积
  2. 提高代码的运行效率
  3. 增加代码的可读性
  4. 减少bug的出现

本文章的内容有些来自网络、有些来自工作中、和平常学习中积累下来的整合

代码优化

1、减少对变量的重复计算 - >for循环的优化

反例:

for(int i = 0; i < args.length(); i++)

正例:

for(int i = 0 , index = args.length(); i < index; i++;)

每次执行到ii++的时候都会重新调用一次args.length(),优化以后把值覆给一个变量防止重复调用

2、嵌套循环

嵌套循环应该遵循“外小内大”的原则虽然循环次数没变,但是耗时却长了很大。

3、for、foreach、stream效率比较

如果数据在1万以内的话,for循环效率高于foreach和stream;如果数据量在10万的时候,stream效率最高,其次是foreach,最后是for。另外需要注意的是如果数据达到100万的话,parallelStream异步并行处理效率最高,高于foreach和for。

4、应该使用Collection.isEmpty()检测是否为空

使用 Collection.size() 来检测空逻辑上没有问题,但是使用 Collection.isEmpty() 使得代码更易读,并且可以获得更好的性能。任何 Collection.isEmpty() 实现的时间复杂度都是 O(1) ,但是某些 Collection.size() 实现的时间复杂度可能是O(n)。

哈希算法就是典型的O(1)时间复杂度,无论数据规模多大,都可以在一次计算后找到目标(不考虑冲突的话)

如果还需要检测是否为null的情况可以使用

  • CollectionUtils.isEmpty(collection)
  • CollectionUtils.isNotEmpty(collection)

5、底层使用可变数据结构尽量指定长度

List<String> list = new ArrayList<>(10);
Map<String , String> map =  new HashMap<>(10);

集合大小也是有大小限制的。每次扩容的时候复杂度可能是O(n),所以经可能预支集合的大小,能减少集合的扩容次数。

6、String类尽量使用StringBuild、StringBuffer

一般字符串在编译期间java会进行优化,但是在循环中字符拼接,java编辑期无法做到优化,所以需要使用StringBuild 、 StringBuffer进行替换

注意:线程安全的情况下使用StringBuild 线程不安全的情况下使用StringBuffer

7、使用equals()方式时常量尽量写在前面

这样在equals判断时后面的值如何为null的情况下会为fale不会抛出空指针异常导出程序报错

8、.使用懒加载的策略 在需要的时候才去创建 避免创建的对象被JVM回收浪费性能

反例:

String str = "aaa";
if (result == 1)
{
  list.add(str);
}

正例:

if (result == 1)
{
	String str = "aaa";
  list.add(str);
}

9、频繁调用 Collection.contains 方法请使用 Set

在 java 集合类库中,List 的 contains 方法普遍时间复杂度是 O(n) ,如果在代码中需要频繁调用 contains 方法查找数据,可以先将 list 转换成 HashSet 实现,将 O(n) 的时间复杂度降为 O(1) 。

10、长整型常量后添加大写 L

在使用长整型常量值时,后面需要添加 L ,必须是大写的 L ,不能是小写的 l ,小写 l 容易跟数字 1 混淆而造成误解。

11、在数值运算时,遇到偶数乘、除偶数倍时,尽量使用位移运算

int a = 2;
int b = 16;
System.err.println(a<<5);//等同于  2*2*2*2*2*2   即2*32
System.err.println(b>>2);//等同于  16/2/2      即16/4

12、不要使用魔法值

当你编写一段代码时,使用魔法值可能看起来很明确,但在调试时它们却不显得那么明确了。这就是为什么需要把魔法值定义为可读取常量的原因。但是,-1、0 和 1 不被视为魔法值。

使用idea插件阿里规范手册可以提示代码的错误
在这里插入图片描述

13、慎重使用static静态

使用静态后,编译时会直接创建,而且直到程序结束,一般只会用在常量,公共方法上,因为需要保证随时随地使用,基于这一需求,它不太使用于对象的创建上,会浪费内存

14、不要使用集合实现来赋值静态成员变量

对于集合类型的静态成员变量,不要使用集合实现来赋值,应该使用静态代码块赋值。

15、常量优化

相信这个大家应该都很熟悉,常量名大写 用以和变量区分,而且加上static final修饰,保证使用的速度和不被外界力量所改变

16、 将变量转换成字符串时尽量使用to.string()方法

一般有3种方法

Integer s = 5;
 
s.toString();
 
String.valueOf(s);//源码显示调用了Integer.toString()方法,而且会在调用前做空判断
 
s+“”;//源码显示使用StringBuilder实现,先用append方法拼接,再用toString()方法对比而言,直接调用最底层的toString()方法无疑是效率最高的

17、注意String.split(String regex)

字符串 String 的 split 方法,传入的分隔字符串是正则表达式!部分关键字(比如.|等)需要转义

可以使用一些非反义字符来做分割

注意:如果用split切割一个空字符串返回的数组长度也会为1

18、尽量指定类、方法的final修饰符

为方法指定final修饰符可以让方法不可以被重写。如果指定了一个类为final,则该类所有的方法都是final的。Java编译器会寻找机会内联所有的final方法,内联对于提升Java运行效率作用重大。此举能够使性能平均提高50%。

19、尽可能使用局部变量

调用方法时传递的参数以及在调用中创建的临时变量都保存在栈中,速度较快,其他变量,如静态变量、实例变量等,都在堆中创建,速度较慢。另外,栈中创建的变量,随着方法的运行结束,这些内容就没了,不需要额外的垃圾回收。

20、及时关闭流

在使用完毕后,及时关闭以释放资源。因为对这些大对象的操作会造成系统大的开销,稍有不慎,将会导致严重的后果。

代码规范

1、结构规范

  1. controller层尽量不要做参数的校验和逻辑书写,它只负责请求的转发和响应,入参和出参
  2. Service层逻辑要清晰,尽量不要有if,for的出现,全部封装到公共方法去调用
  3. DAO层只提供持久层相关操作,如封装参数进map供持久层使用,尽量不要有逻辑在里面,所有的逻辑应都在service里完成

2、日志规范

  1. 重要的方法开始后、结束前书写日志
  2. 抓取异常时书写日志

3、可读性规范

  1. 类、方法必须要有注释
  2. 在一些比较大的逻辑前加上注释
  3. 一行代码代表一个逻辑,通篇下来可读性非常强

4、异常优化

  1. 异常应只用来进行错误处理,而不是逻辑处理(异常也是高开销的操作
  2. 善用多种异常,但是在service层应只有一个 try cath来抓取多个异常,并分别处理

不能保证每个地方写的都是对的有错误可以指出来
共同进步

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值