/*
* 45 将局部变量的作用域最小化
* 局部变量的作用从它被声明的点开始,一直到外围块(block)的结束处。
* 几乎每个局部变量的声明都应该包含一个初始化表达式。
*
* 46 for-each循环优于传统的for循环
* for-each可遍历集合和数组以及任何实现Iterator接口的对象
* 在简洁性和预防bug方便具有极大优势
*
* 47 了解和使用类库
*
* 48 如果需要精确的答案,避免使用float和double
* float和double主要为了科学计算和工程计算而设计。
* 它们执行二进制浮点运算,是为了在广泛的数值范围上提供较为精确的快速近似计算而精心设计。
* 尤其不适用于货币计算,一个float或double型数据完全精确到0.1是几乎不可能的。 可使用long,int,Bigdecimal进行货币运算
* 如果数值范围没有超过9位十进制数字,可以使用int,18--long,超过18位,使用bigdecimal
*
* 49 基本类型优先于基本封装类型
* 1.基本类型只有值,而封装类型则具有与他们的值不同的同一性,即两个封装类型可以具有相同的值和不同的同一性
* 2.封装类型可以为null
* 3.基本类型比封装类型更加节省时间和空间
*
* 当程序用==操作符比较两个装箱基本类型时,它做了个同一性比较。
* 当涉及装箱和拆箱基本类型的混合运算时,会进行拆箱操作。
*
* 50 如果其它类型更合适 则避免使用字符串
*
* */
enum Suit {
CLUB, DIAMOND, HEART, SPADE
}
enum Rank {
ONE, TWO, THREE, FOUR
}
class Card {
Suit s;
Rank r;
public Card(Suit suit, Rank rank) {
s = suit;
r = rank;
}
@Override
public String toString() {
return "Card [s=" + s + ", r=" + r + "]";
}
}
public class Item45_50 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Collection<Suit> suits = Arrays.asList(Suit.values());
Collection<Rank> ranks = Arrays.asList(Rank.values());
List<Card> list = new ArrayList<Card>();
for (Iterator<Suit> is = suits.iterator(); is.hasNext();)
for (Iterator<Rank> ir = ranks.iterator(); ir.hasNext();)
list.add(new Card(is.next(), ir.next()));
System.out.println(list);
// [Card [s=CLUB, r=ONE], Card [s=DIAMOND, r=TWO], Card [s=HEART,
// r=THREE], Card [s=SPADE, r=FOUR]]
// 当suits个数与ranks个数不同报错
list.clear();
for (Suit s : suits)
for (Rank r : ranks)
list.add(new Card(s, r));
System.out.println(list);
// [Card [s=CLUB, r=ONE], Card [s=CLUB, r=TWO], Card [s=CLUB, r=THREE],
// Card [s=CLUB, r=FOUR],
// Card [s=DIAMOND, r=ONE], Card [s=DIAMOND, r=TWO], Card [s=DIAMOND,
// r=THREE], Card [s=DIAMOND, r=FOUR],
// 全部输出
}
}
class Item48 {
public static void main(String[] args) {
double d1 = 1.02;
double d2 = 0.22;
System.out.println(d1 - d2 * 10);// -1.1800000000000002
fun1();
fun2();
}
public static void fun1() {
double funds = 1.00;
int itemsBought = 0;
for (double price = 0.1; funds >= price; price += 0.1) {
funds -= price;
itemsBought++;
}
System.out.println(itemsBought);// 3
System.out.println(funds);// 0.3999999999999999
}
final static BigDecimal TEN_CENTS = new BigDecimal("0.10");
public static void fun2() {
BigDecimal funds = new BigDecimal("1.00");
int itemsBought = 0;
for (BigDecimal price = new BigDecimal("0.1"); funds.compareTo(price) >= 0; price = price.add(TEN_CENTS)) {
funds = funds.subtract(price);
itemsBought++;
}
System.out.println(itemsBought);// 4
System.out.println(funds);// 0.00
}
}
class Item49 {
static Integer i;
public static void main(String[] args) {
if(i==0){
System.out.println("i==0");
//java.lang.NullPointerException
//i=null 当基本类型与封装基本类型进行某操作时,封装类型自动拆箱。
}
//Long sum=0;
Long sum=0l;
for(long i = 0;i<1000;i++){
sum+=i;//自动装箱,降低速率
}
Comparator<Integer> comp = new Comparator<Integer>(){
@Override
public int compare(Integer t1, Integer t2) {
// TODO Auto-generated method stub
// return t1==t2?0:t1>t2?1:-1;
return t1<t2?-1:t1==t2?0:1;
}};
Comparator<Integer> comp1 = new Comparator<Integer>(){
@Override
public int compare(Integer t1, Integer t2) {
// TODO Auto-generated method stub
int int1 = t1;
int int2 = t2;
return int1==int2?0:int1>int2?1:-1;
}};
//原因:t1和t2表示同意个int值得不同Integer实例,这个比较结果或返回false
System.out.println(comp.compare(new Integer(1), new Integer(1)));//-1 或 1
System.out.println(comp1.compare(new Integer(1), new Integer(1)));//0
}
}
/*
* 51 当心字符串连接的性能
* String 不可变类
* StringBuffer 可变 大部分方法同步
* StringBuilder 可变 未同步 常用
*
* 52 通过接口引用对象
* 53 接口优于反射机制
*
* 54 慎用本地方法
* JNI(Java Native Interface)允许Java应用程序调用本地方法
* 本地方法:指用本地程序设计语言(c或者c++)来编写的特殊方法。本地方法在本地语言中可以执行任意的计算任务,并返回到java程序设计语言
* 用途:
* 1.提供了“访问特定于平台的机制”的能力,比如访问注册表、文件锁
* 2.访问遗留代码库的能力,从而访问遗留数据
* 3.可编写程序中注重性能的部分,提高系统性能
* 缺点:
* 1.本地语言不安全,不能再免受内存毁坏错误
* 2.本地语言平台相关,程序不再可自由移植
* 3.调试困难
*
* 55 慎用优化
* 56 遵守普遍接受的命名惯例
* */
public class Item51_56 {
public static void main(String[] args) {
// TODO Auto-generated method stub
String s="132"+"312"+"321";
//对静态字符串进行连接操作时,java会在编译时做彻底的优化,将多个连接操作的字符串在编译的时候合并为单个字符串
//一些简单清晰的String变量也如此 ....最好不用
StringBuilder sb = new StringBuilder();//默认提供16个字节容量
StringBuilder sb1 = new StringBuilder(20);
//在容量不够时,会进行扩容操作,先申请内存,然后将内容进行拷贝,若能预先评估大小,可大大提高性能。
//StringBuffer 差不多fd
sb.append(21).append(12).append("a").append('d').append(23.23).append(1f);
System.out.println(sb);//2112ad23.231.0
}
}