关于《effectivity Java》阅读笔记 01

关于《effectivity Java》阅读笔记

第八章 – 通用的程序设计


关于局部变量的初始化

  • 将局部变量最小化,可以增加代码的可读性和可维护性,并降低出错的可能性。

  • 要使局部变量的作用域最小化,最好的做法就是在第一次使用它的时候进行声明。
    如果变量在使用之前声明,会影响影响试图理解代码的读者,分散他们的注意力。耗费时间寻找变量声明的地方。

  • 几乎每个局部变量都应该包含一个初始化表达式,如果一个变量被一个方法初始化,而这个方法可能会抛出一个受检的异常,该变量就必须在try快内部进行初始化。


for循环的优劣

根据循环中循环变量的作用域和数目进行评价,因此 for循环优于while循环,foreach优于传统for。

下面是遍历的首先做法:

//适用与集合和数组
for(Element e: c){
    doSomething(e);
}

在java 1.5版本之前的首先做法如下:

// 遍历集合
for(Iterator i = c.iterator(); i.hasNext();){
    doSomething((Element) i.next());
}
// 遍历数组
for(int i = 0; i<a.length; i++){
    doSomething(a[i]);
}

下面是另一种局部变量作用域最小化的循环做法:

// expensiveComputation()方法用于获取n的数量,这样做 局部变量i,n作用域只在for循环内。
for(int i = 0, n = expensiveComputation(); i <n ; i++){
    doSomething(i);
}

有三种情况无法使用for-each循环

  • 1.过滤 —- 如果需要遍历集合,并删除选定的元素,就需要使用显示的迭代器,以便可以调用它的remove方法
  • 2.转换 —- 如果需要遍历列表或者数组,并替换它全部或者部分元素值,就需要列表迭代或者数组索引,以便设定元素的值
  • 3.平行迭代 —- 如果需要并行的遍历多个集合,就需要显示的控制迭代器或者索引变量,以便所有的迭代器或者索引变量都可以得到同步前移。

第49条:基本类型优于装箱基本类型

java 1.5版本增加了自动装箱和自动拆箱,他们之间主要有三个区别:

  • 基本类型只有值,装箱基本类型则具有与他们的值不同的同一性,换句话说,俩个装箱基本类型可以具有相同的值和不同的同一性。
  • 基本类型只有功能完备的值,而每个装箱基本类型除了他对应基本类型的所有功能值以外,还有一个非功能值: null。
  • 基本类型通常比装箱基本类型更节省时间和空间。

考虑下面这个程序有什么问题:

public static void main(String[] args){
    Long sun = 0L;
    for(long i = 0; i<100; i++){
        sum += i;
    }
    System.out.println(sum);
}

这段代码运行起来要比预想的慢很多,因为它不小心把局部变量sum声明为装箱基本类型Long。而不是基本类型long,这样程序编译起来没有错误或者警告,变量被反复的装箱和拆箱,导致明显的性能下降。


字符串的使用

如果其他类型更适合,要尽量避免使用字符串,字符串经常被错误的用来替代基本类型、枚举类型、聚集类型。

字符串连接操作符( + )适用于: 产生单独的一行输出,或者构造一个字符串来表示一个较小的、大小固定的对象。但是如果是连接n个字符串,频繁的使用字符串连接符,需要n的平方级的时间。这是因为字符串不可变,当俩个字符串连接在一起时,他们的内容都要被拷贝。


考虑下面这段代码:

public String statement(){
    String result = "";
    for(int i=0; i< numItems(); i++){
        result += lineForItem(i); //String concatenation 
    }
    return result;
}

如果项目数量巨大,这个方法的时间就难以估算。为了获得可以接受的性能,请使用StringBuilder代替String。(Java 1.5发行版本中增加了非同步StringBuilder类,代替现在过时的StringBuffer类)。

public String statement(){
    StringBuilder b = new StringBuilder(numItems()*LINE_WIDTH);
    for(int i = 0;i<numItems();i++){
        b.append(lineForItem(i));
    }
    return b.toString();
}

第二种做法比第一张大约快85倍左右。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章