减少对变量的重复计算
明确一个概念,对方法的调用,即使方法中只有一句语句,也是有消耗的,包括创建栈帧、调用方法时保护现场、调用方法完毕时恢复现场等。所以例如下面的操作:
for (int i = 0; i < list.size(); i++)
{…}
替换为:
for (int i = 0, length = list.size(); i < length; i++)
{…}
这样,在list.size()很大的时候,就减少了很多的消耗
乘法和除法尽量使用移位操作
基于效率和类型检查的考虑,应该尽可能使用array,无法确定数组大小时才使用ArrayList 。
19. 实现RandomAccess接口的集合比如ArrayList,应当使用最普通的for循环而不是foreach循环来遍历
这是JDK推荐给用户的。
JDK API对于RandomAccess接口的解释是:实现RandomAccess接口用来表明其支持快速随机访问,此接口的主要目的是允许一般的算法更改其行为,从而将其应用到随机或连续访问列表时能提供良好的性能。
实际经验表明,实现RandomAccess接口的类实例,假如是随机访问的,使用普通for循环效率将高于使用foreach循环;反过来,如果是顺序访问的,则使用Iterator会效率更高。可以使用类似如下的代码作判断:
if (list instanceof RandomAccess)
{
for (int i = 0; i < list.size(); i++){}
}
else
{
Iterator<?> iterator = list.iterable();
while (iterator.hasNext()){iterator.next()}
}
foreach循环的底层实现原理就是迭代器Iterator,参见 Java语法糖1:可变长度参数以及foreach循环原理。所以后半句”反过来,如果是顺序访问的,则使用Iterator会效率更高”的意思就是顺序访问的那些类实例,使用foreach循环去遍历。
12. 循环内不要不断创建对象引用
例如:
for (int i = 1; i <= count; i++)
{
Object obj = new Object();
}
这种做法会导致内存中有count份Object对象引用存在,count很大的话,就耗费内存了,建议为改为:
Object obj = null;
for (int i = 0; i <= count; i++)
{
obj = new Object();
}
这样的话,内存中只有一份Object对象引用,每次new Object()的时候,Object对象引用指向不同的Object罢了,但是内存中只有一份,这样就大大节省了内存空间了。
20. 使用同步代码块替代同步方法
除非能确定一整个方法都是需要进行同步的,否则尽量使用同步代码块,避免对那些不需要进行同步的代码也进行了同步,影响了代码执行效率。
28. 字符串变量和字符串常量equals的时候将字符串常量写在前面
这是一个比较常见的小技巧了,如果有以下代码:
String str = “123”;
if (str.equals(“123”))
{
…
}
建议修改为:
String str = “123”;
if (“123”.equals(str))
{
…
}
这么做主要是可以避免空指针异常。
推荐以后写并发的时候在复习一遍