1. 减少对变量的重复计算和对变量的定义
对于For循环,如果能通过Java8中的Stream流表达式解决那就最好了,如果非要使用For循环,应该尽量减少对变量的重复计算和减少对变量的定义。
public class OptimizingCode { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } System.out.println("----------------优化-----------------"); //优化为 for (int i = 0, length = list.size(); i < length; ++i) { System.out.println(list.get(i)); } } }
优化点有两个:
1)先算出length的大小,这样list.size()只会调用一次,减少性能消耗。
2)使用++i替换原来的i++,在For循环中++i和i++对结果是没有区别,两者不同的地方在于++i 占用的空间比 i++ 要小,i++是多定义一个变量的,看看运算符重载可以知道是怎么回事。
int i=1; int a = i++; int a = ++i;
这时才有区别,第一个a是1,第二个a是2。
2. 尽量采用懒加载的策略,即在需要的时候才创建
String str = "佛大Java程序员"; if (i == 1){ list.add(str); } //懒加载替换 if (i == 1){ String str = "佛大Java程序员"; list.add(str); }
3.循环内不要不断创建对象引用
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罢了,但是内存中只有一份,这样就大大节省了内存空间了。
4.不要在循环中使用try…catch…,应该把其放在最外层
//try catch放在了循环内 public void demo1() { while(true) { try{ Thread.sleep(30*60*1000); } catch (InterruptedException e){ e.printStackTrace(); } } } // try catch放在了循环外 public void demo2(){ try{ while(true){ Thread.sleep(30*60*1000); } } catch (InterruptedException e){ e.printStackTrace(); } }
demo1是将try catch放在了循环内,demo2是将try catch放在了循环个。二者的区别是如果test2中循环内容抛出异常的话,就直接跳出了循环,而demo1在执行中抛出异常会继续循环,至于二者选择哪种方式更好就要看你循环的内容了.
①如果是为了计算一个结果的话,其中一个遇到异常那么即使继续计算后面的,最后的结果也不会正确,那么我们就需要按demo2的方式编码;
②如果是一个服务器线程维持一直处理其它线程产生的数据,为了保证系统的稳定性,就必须按demo1的方式来编码。
另外有些人喜欢比较性能,我觉得没必要比较性能。如果需求是第②种情况没的选,如果是第①种情况,try catch写在外面,既美观,又易懂,性能肯定不比放在里面差。