Java之Collections.emptyList()、emptySet()、emptyMap()的作用和好處以及要注意的地方
https://blog.csdn.net/qq_27093465/article/details/65444622
先說明一下好處有哪些:
1,如果你想 new 一個空的 List ,而這個 List 以後也不會再新增元素(有大坑,看下面更新),
那麼就用 Collections.emptyList() 好了。
new ArrayList() 或者 new LinkedList() 在建立的時候有會有初始大小,多少會佔用一記憶體。
每次使用都new 一個空的list集合,浪費就積少成多,浪費就嚴重啦,就不好啦
2,為了編碼的方便。
比如說一個方法返回型別是List,當沒有任何結果的時候,返回null,有結果的時候,返回list集合列表。
那樣的話,呼叫這個方法的地方,就需要進行null判斷。使用emptyList這樣的方法,可以方便方法呼叫者。返回的就不會是null,省去重複程式碼。
注意的地方:
這個空的集合是不能呼叫.add(),新增元素的。因為直接報異常。因為原始碼就是這麼寫的:直接拋異常。
哦,Collections裡面沒這麼寫,但是EmptyList繼承了AbstractList這個抽象類,裡面簡單實現了部分集合框架的方法。
這裡面的add方法最後呼叫的方法體,就是直接拋異常。
throw new UnsupportedOperationException();
這麼解釋add報異常就對啦。
下面簡單看下這個原始碼:
/**
* Collections 類裡面的方法如下,一步步往下看就是啦
*/
public static final <T> List<T> emptyList() {
return (List<T>) EMPTY_LIST;
}
//。。。。。
/**
* Collections 類裡面的方法如下,一步步往下看就是啦
*/
public static final List EMPTY_LIST = new EmptyList<>();
//。。。。。
/**
* Collections裡面的一個靜態內部類
*/
private static class EmptyList<E> extends AbstractList<E> implements RandomAccess, Serializable {
private static final long serialVersionUID = 8842843931221139166L;
public Iterator<E> iterator() {
return emptyIterator();
}
public ListIterator<E> listIterator() {
return emptyListIterator();
}
public int size() {return 0;}
public boolean isEmpty() {return true;}
public boolean contains(Object obj) {return false;}
public boolean containsAll(Collection<?> c) { return c.isEmpty(); }
public Object[] toArray() { return new Object[0]; }
public <T> T[] toArray(T[] a) {
if (a.length > 0)
a[0] = null;
return a;
}
public E get(int index) {
throw new IndexOutOfBoundsException("Index: "+index);
}
public boolean equals(Object o) {
return (o instanceof List) && ((List<?>)o).isEmpty();
}
public int hashCode() { return 1; }
// Preserves singleton property
private Object readResolve() {
return EMPTY_LIST;
}
}
除了這個emptyList,之外,還有類似的,emptyMap,emptySet等等。具體看下圖,都是一個套路。
(2017/08/28 更新)
看下面的程式碼,咱先弄個empty出來,然後,可能有需求要繼續在這個空集合裡面新增內容。那麼,bug就來啦。
/**
* 測試這個空集合是某個Java bean 的某個屬性的時候的操作,也是不能add的
*/
private static void testModelEmptyField() {
Car car = new Car();
car.setBoys(Collections.emptyList());
car.getBoys().add("sss");
}
/**
* Collections.emptyMap() 返回的空集合是不能進行put的
*/
private static void testEmptyMap() {
Map<String,String> map = Collections.emptyMap();
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + ":"+ entry.getValue());
}
map.put("a","a");
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + ":"+ entry.getValue());
}
}
/**
* Collections.emptyList() 返回的空集合是不能進行add的
*/
private static void testEmptyList() {
List<String> list = Collections.emptyList();
for (String s : list) {
System.out.println(s);
}
//異常
list.add("1");
for (String s : list) {
System.out.println(s);
}
}
具體出的bug,看下面的截圖。
阿彌陀佛,算了 ,這個咱還是不用了吧。
很危險的,分分鐘程式碼就bug啦。這個不好,不好。。。不用啦,瞭解下就得啦。
---------------------
作者:李學凱
來源:CSDN
原文:https://blog.csdn.net/qq_27093465/article/details/65444622?utm_source=copy
版權宣告:本文為博主原創文章,轉載請附上博文連結!