1.String 相等
稍微有點經驗的程式員都會用equals比較而不是用 ==,但用equals就真的安全了嗎,看下面的代碼
user.getName().equals("xiaoming");
有經驗的老司機很快就能看到問題,如果user.getName()為null,就會抛出空指針異常,是以下面的寫法更為穩妥
"xiaoming".equals(user.getName());
當然這種寫法并不是萬能的,如果比對的兩邊都是未知變量,如下
user.getName().equals(user1.getName());//user.getName() 和 user1.getName()都有可能為null
是以更為穩妥的方法可以采用jdk Objects類中的equals方法,左右兩邊都可以避免空指針異常
Objects.equals(user.getName(), user1.getName());
需要注意的是Objects類在jdk1.7才支援,如果是jdk1.6,可以采用guava中的Objects類代替
2.Integer 比較
Integer a = 127;
Integer b = 127;
Integer c = 128;
Integer d = 128;
System.out.println(a == b);// 結果為:true
System.out.println(c == d);// 結果為:false
令人驚訝的是結果并不是預料中的全是true,而是一個為true,一個為false
至于原因還需要從源碼中探究
首先通過源碼來看一下,當通過 = 對Integer指派時,實際調用了Integer.valueOf()方法
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
可以看到當 i >= IntegerCache.low && i <= IntegerCache.high 時,是從一個緩存類中取,其它情況會new一個對象。IntegerCache.low預設為-128,high預設為127(可調整)。
這樣a=b就很好解釋了,因為==比較的是記憶體位址,a,b都是從這個緩存類中取的同一個對象,是以傳回結果為true。b,c則都是new的新對象,記憶體位址自然不同,是以傳回false
既然看到了這個緩存類,就有必要一睹它的廬山真面目了
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
}
private IntegerCache() {}
}
IntegerCache 是Integer類中一個靜态内部類,high值可通過JVM 的啟動參數設定
3.Arrays.asList(array)
String [] array= {"a","b","c"};
// 傳回的List執行個體為:java.util.Arrays.ArrayList
List<String> list = Arrays.asList(array);
list.remove(0);
Arrays.asList是一種很常見的建立List的方式,但該方法傳回的List執行個體不是平時常用的List執行個體,而是Arrays的一個靜态内部類,該類繼承自AbstractList類,并為提供List的完整的實作,例如remove方法就未實作,當然,如果隻是用做周遊,則完全是沒問題的
類似的情況還有不少,使用時要注意,例如:
- ArrayList的subList方法,傳回的是ArrayList中的一個内部類
java.util.ArrayList.SubList
- HashMap的values方法,傳回的是HashMap中的一個内部類:
java.util.HashMap.Values
4.list.toArray
List<String> list = new ArrayList<String>();
String[] array=(String[]) list.toArray();
上面的寫法乍一看似乎沒有什麼問題,但list.toArray()傳回的是一個object數組,強轉會抛異常。其實是可以指定傳回數組的類型的,如下
String[] array=list.toArray(new String[list.size()]);
5.foreach remove
List<String> list =new ArrayList<String>();
list.add("java");
list.add("c");
list.add("js");
for(String str:list){
list.remove(0);
}
在周遊時删除元素也是比較常用的操作,但foreach時删除元素有可能抛異常,這種不好控制的寫法還是不用為好,可以用疊代器去代替
for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
String str = iterator.next();
iterator.remove();
}
6. String getBytes
String str="韋德";
byte[] bytes = str.getBytes();
String的getBytes()方法用的是目前項目的預設編碼,如果不指定編碼,在不同的運作環境很容易被坑,是以還是根據自己的需要指定對應的編碼比較靠譜
String str="韋德";
byte[] bytes = str.getBytes("utf-8");
作者:zhaoguhong(趙孤鴻)
出處:http://www.cnblogs.com/zhaoguhong/
個人部落格:http://www.zhaoguhong.com
本文版權歸作者和部落格園共有,轉載請注明出處