上次面试的时候,免面试官问我java代码优化,虽然平时在实际开发中也有注意这方面的问题,但当时就是没回来上来,都怪平时没注意总结,所以今天就在这里总结。这里我还要提醒下那些新手,想学好一门技能,总结非常重要。好记性不如烂笔头。好了废话不多说了。
1.尽量减少对变量的重复计算
使用带下标的for循环时,如下所示:
List<String> list = new ArrayList<>();
...
for(int i = 0; i < list.size(); i++) {
}
这种情况下,最好把对size的计算放到循环外,因为这样每次遍历都会计算一次,造成了不必要的浪费。改成如下:
List<String> list = new ArrayList<>();
...
int size;
for(int i = 0; i < size = list.size(); i++) {
}
获取方法参数的值时,对值的获取尽量只有一次(即,使用get()
方法获取)。这样做后你的参数引用只有一个,维护更加方便。
2. 如果事先知道容器的容量,初始化时尽量指定它的初始容量(initialCapacity)
例如Map可以这样指定
Map<String, Object> map = new HashMap<>(2);
3. 计算时尽量使用位运算
例如对一个数乘/除一个偶数,如下:
int a = 5;
int b = a * 4;
int c = a / 4;
改为:
int a = 5;
int b = a << 2; //右移两位
int c = a >> 2;//左移两位
4. int转String,尽量使用String.valueOf()
;不要使用+ ""
。+ ""
在底层会使用StringBuilder
的append()
方法,最后调用toString()
。这里贴上javap后的源码:
@Test
public void test1() {
int a = 5;
String s = a + "";
}
javap -c 后的源码:
public void test1();
Code:
0: iconst_5
1: istore_1
2: new #2 // class java/lang/StringBuilder
5: dup
6: invokespecial #3 // Method java/lang/StringBuilder."<init>":()V
9: iload_1
10: invokevirtual #4 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
13: ldc #5 // String
15: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
18: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
21: astore_2
22: return
还是做了很多操作的。接下来我们看看String.valueOf()
方法:
@Test
public void test1() {
int a = 5;
String s = String.valueOf(a);
}
javap -c 后的源码:
public void test1();
Code:
0: iconst_5
1: istore_1
2: iload_1
3: invokestatic #2 // Method java/lang/String.valueOf:(I)Ljava/lang/String;
6: astore_2
7: return
不多说了,很明显的变化。
所以尽量使用String.valueOf()
。
5. 对变量的声明尽量放到条件语句内(尽量采用懒加载的策略,即在需要的时候才创建)
public void printB(int a){
int b = 2;
if (a == 1) {
System.out.println(b);
}
}
这时的System.out.println(b);
在a
不等于1时,是不会被执行的,所以因该把b
变量的声明放到条件内部,如下:
public void printB(int a){
if (a == 1) {
int b = 2;
System.out.println(b);
}
}
这个也很容易做到。
6. 使用equals
比较时,常量尽量放在equals前,这样不容易出现NullPointException
7. 返回值位数组/列表时,没有值返回值,尽量不要返回null
,而是返回空数组
这样做的好处就是,调用方法不需要先判断是否返回nul
,代码更简洁,而且可以减少因为疏忽而引起的空指针异常。
8. 对流的尽量使用带资源的try
从jdk 1.7之后出现了带资源的try语句。只要实现了AutoCloseable
接口,都可以使用带资源的try。这样做的好处就是,不需要再显示的调用close
方法,也就不会出现因为忘记调用而引起的资源为释放。
9. 对变量的的声明放到循环外
10. 对字符串的操作使用StringBuilder/StringBuffer(线程安全)
例如字符串的连接,不要使用 + "" +
,使用加号连接,底层使用的是StringBuilder
,每使用一次加号连接赋值,都会重新new一个StringBuilder
。所以建议使用直接使用StringBuilder/StringBuffer(线程安全)。
网友评论