第8章 通用程序设计
第45条:讲局部变量的作用域最小化
要使局部变量的作用域最小化,最有力的方法就是在第一次使用它的地方声明。
如果在循环终止之后不再需要循环变量的内容,for循环优先于while循环。
for循环比while循环更简短,从而增强了可读性。
第46条:for-each循环优先于传统的for循环
private static void doSomething(String str){
System.out.println(str);
}
public static void main(String[] args) {
List<String> c= new ArrayList<String>();
c.add("1");
c.add("2");
c.add("3");
c.add("4");
c.add("5");
//Iterator used to collection!
for(Iterator<String> i = c.iterator(); i.hasNext();){
doSomething((String)i.next());
}
String[] a = {"a", "b", "c", "d", "e"};
//for used for array!
for(int i = 0; i< a.length; i++){
doSomething(a[i]);
}
//for-each used for collection and array!
for(String i : c){
doSomething(i);
}
for(String i : a){
doSomething(i);
}
}
for-each循环不会有性能损失,甚至用于数组也一样。
以下三种情况不能使用for-each循环:
1. 过滤——如果需要遍历集合,并删除选定的元素,就需要使用显式的迭代器,以便可以调用它的remove方法。
2. 转换——如果需要遍历列表或者数组,并取代它部分或者全部的元素值,就需要列表迭代器或者数组索引,以便设定元素的值。
3. 平行迭代——如果需要并行地遍历多个集合,就需要显式地控制迭代器或者索引遍历,以便所有迭代器或者索引变量都可以同步前移。
第47条:了解和使用类库
每个程序员都应该熟悉java.lang、java.util,最好还有java.io的内容。
第48条:如果需要精确的答案,请避免使用float和double
float和double执行二进制浮点运算,它们并没有提供完全精确的结果,所以不应该被用于需要精确结果的场合。float和double类型尤其不适合用于货币计算,因为要让一个float或者double精确地表示0.1是不可能的。解决计算货币问题,使用BigDecimal、int或者long进行货币计算。
如果数值范围没有超过9位十进制数字,就可以使用int,如果不超过18位数字,就可以使用long,如果可能超过18位数字,就必须使用BigDecimal。
第49条:基本类型优先于装箱基本类型
java中的同一性:两个引用指向同一个对象;java的等同性:两个引用指向的对象,在逻辑上相等。
java有基本类型和引用类型两种,每个基本类型都有一个对应的引用类型,称作装箱基本类型。
基本类型和装箱基本类型的三个主要区别。第一,基本类型只有值,而装箱基本类型则具有与它们的值不同的同一性。第二,基本类型只有功能完备的值,而每个装箱基本类型除了它对应基本类型的所有功能之外,还有个非功能值:null。最后一点区别是,基本类型通常比装箱基本类型要节省时间和空间。
第50条:如果其他类型更适合,则尽量避免使用字符串
字符串不适合代替其他的值类型;字符串不适合代替枚举类型;字符串不适合代替聚集类型;字符串也不适合代替能力表。
第51条:当心字符串连接的性能
为连接n个字符串而重复地使用字符串连接操作符,需要n的平方级的时间。当两个字符串被连接在一起时,它们的内容都要被拷贝。为了获得可以接受的性能,请使用StringBuilder代替String。
第52条:通过接口引用对象
第53条:接口优先于反射机制
第54条:谨慎地使用本地方法
第55条:谨慎地进行优化
第56条:遵守普遍接受的命名惯例