在寫代碼的時候,有時候遇到for循環,寫到下面的時候有一點猶豫。
List<Data> dataList = ...;
for (Data d : dataList) {
if (d != null) { // 需要這個判斷嗎?
// ...
}
}
產生上述疑問,究其原因在於對List源碼不熟悉,雖然知道List接口有LinkedList(基於鏈表實現)、ArrayList(基於數組實現)等實現類,但其執行add方法的細節沒關注,就會產生如題的疑惑。本文先得出結論,最後再去分析其中的原因。
在本地寫test代碼,往List中add null對象,然後再做遍歷。
private void printList() {
List<Integer> dataList = new ArrayList<>();
dataList.add(1);
dataList.add(null);
dataList.add(null);
for (Integer d : dataList) {
System.out.println(d);
}
System.out.println("------------------------");
for (Integer d : dataList) {
if (d != null) { // 需要這個判斷嗎?
System.out.println(d);
}
}
}
測試函數輸出
1
null
null
------------------------
1
針對問題:List可以add(null)嗎?答案是肯定的,null對象是可以添加到列表中。這一點通過上述例子也很好理解。
理解此問題的關鍵點在於ArrayList底層的原理,針對本問題重點在於:
- List底層是數組即,Object[] elementData,數組對元素沒限制。這一點可以通過源碼解釋:
/**
* This helper method split out from add(E) to keep method
* bytecode size under 35 (the -XX:MaxInlineSize default value),
* which helps when add(E) is called in a C1-compiled loop.
*/
private void add(E e, Object[] elementData, int s) {
if (s == elementData.length)
elementData = grow();
elementData[s] = e;
size = s + 1;
}
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return {@code true} (as specified by {@link Collection#add})
*/
public boolean add(E e) {
modCount++;
add(e, elementData, size);
return true;
}
- 關於Java對象是否能處理null,不要與Hashmap和Hashtable混淆,HashMap可以接受爲null的鍵值(key)和值(value),而Hashtable則不行。這一點通過源碼解釋:
Hashmap底層是由數組、鏈表、紅黑色組成。數組的下標通過key值決定,
Node<K,V>[] table;
// key爲null時,哈希值爲0
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
// 數組下標計算方式
tab[i = (n - 1) & hash
Hashtable底層是由數組、鏈表組成。數組的下標通過key值決定,
public synchronized V put(K key, V value) {
// Make sure the value is not null
if (value == null) {
throw new NullPointerException();
}
// key爲null的話,key.hashCode()就會報NullPointerException
// Makes sure the key is not already in the hashtable.
Entry<?,?> tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry<K,V> entry = (Entry<K,V>)tab[index];
for(; entry != null ; entry = entry.next) {
if ((entry.hash == hash) && entry.key.equals(key)) {
V old = entry.value;
entry.value = value;
return old;
}
}
addEntry(hash, key, value, index);
return null;
}
參考
1、https://blog.csdn.net/krossford/article/details/83903851