集合類別可以印出整齊元素的方法 toString

集合類別可以印出整齊元素的方法
AbstractCollection
public String toString() {
        Iterator<E> it = iterator();
        if (! it.hasNext())
            return "[]";

        StringBuilder sb = new StringBuilder();
        sb.append('[');
        for (;;) {
            E e = it.next();
            sb.append(e == this ? "(this Collection)" : e);
            if (! it.hasNext())
                return sb.append(']').toString();
            sb.append(',').append(' ');
        }
    }

AbstractCollect 源碼分析

AbstractCollection抽象類提供瞭Collection的骨架實現,Collection分析請看:
http://blog.csdn.net/treeroot/admin/Referrers.aspx?EntryID=99591
這裡直接看它的代碼是如何實現的.
public abstract Iterator iterator();
該方法沒有實現.
public abstract int size();
該方法沒有實現.
public boolean isEmpty() {
return size() == 0;
}
非常簡單,直接調用size()方法返回大小,如果是0就認為是空集合.
你不會覺得奇怪吧,size()方法沒有實現,怎麼可以調用呢?因為這個是抽象類,不可以實例化的,具體的時候調用的是子類中的實現.
public boolean contains(Object o) {
Iterator e = iterator();
if (o==null) {
while (e.hasNext())
if (e.next()==null)
return true;
} else {
while (e.hasNext())
if (o.equals(e.next()))
return true;
}
return false;
}
代碼不復雜,也是調用自己的方法iterator,遍歷集合,如果找到瞭就返回true,在沒找到的情況下是要遍歷整個集合的.對於null值的情況一定要放在if裡面,而不能放在else裡面.
public Object[] toArray() {
Object[] result = new Object[size()];
Iterator e = iterator();
for (int i=0; e.hasNext(); i++)
result[i] = e.next();
return result;
}
返回數組,先生成一個和集合一樣大小的數組,然後通過遍歷賦值.
public Object[] toArray(Object a[]) {
int size = size();
if (a.length < size)
a = (Object[])java.lang.reflect.Array.newInstance(
a.getClass().getComponentType(), size);

Iterator it=iterator();
for (int i=0; i
a[i] = it.next();

if (a.length > size)
a[size] = null;

return a;
}
這個方法如果在數組a比集合小的情況和上面是一樣的,這種情況下生成瞭一個新的數組,這裡用到瞭反射(從字面上就可以看出意思).為什麼不可以直接new呢?因為數組a中的元素是具有運行時類型的,而不僅僅是Object.可以看出當a可以容納整個集合時是不用重新分配空間的,而且如果a比集合大,會設置a[size]為null值,而且僅僅設置瞭這一個.如果集合允許null值的話,通過返回數組是無法判斷集合的大小的,因為可能集合的最後幾個都是null值.
public boolean add(Object o) {
throw new UnsupportedOperationException();
}
這個方法提供瞭實現,但是是直接拋出一個異常,和未實現的方法是有區別的,非抽象子類中可以不重寫這個方法,如果子類不想支持這個操作的話,而未實現的方法子類必須實現,否則編譯同不過.
public boolean remove(Object o) {
Iterator e = iterator();
if (o==null) {
while (e.hasNext()) {
if (e.next()==null) {
e.remove();
return true;
}
}
} else {
while (e.hasNext()) {
if (o.equals(e.next())) {
e.remove();
return true;
}
}
}
return false;
}
這個方法和contians方法基本一樣,多瞭一條e.remove語句而已.
public boolean containsAll(Collection c) {
Iterator e = c.iterator();
while (e.hasNext())
if(!contains(e.next()))
return false;

return true;
}
這個方法比較簡潔,但是時間復雜度是m*n,通過檢查沒一個元素是否在集合中,如果發現一個不在直接返回false.可以看出返回true的情況花的時間比返回false要多.
public boolean addAll(Collection c) {
boolean modified = false;
Iterator e = c.iterator();
while (e.hasNext()) {
if(add(e.next()))
modified = true;
}
return modified;
}
這裡是通過一個一個加入集合的,同樣這裡的add方法是沒有實現的,要註意的一點是,隻要加入瞭至少一個元素函數就返回true,表示原來的集合有變化.
public boolean removeAll(Collection c) {
boolean modified = false;
Iterator e = iterator();
while (e.hasNext()) {
if(c.contains(e.next())) {
e.remove();
modified = true;
}
}
return modified;
}
這個方法對集合中的每一個元素判斷,如果在集合c中就刪除,相同值的會被一並刪除,刪除至少一個元素就返回true.
public boolean retainAll(Collection c) {
boolean modified = false;
Iterator e = iterator();
while (e.hasNext()) {
if(!c.contains(e.next())) {
e.remove();
modified = true;
}
}
return modified;
}
這個方法和上面的幾乎一樣,多瞭一個非(!).
public void clear() {
Iterator e = iterator();
while (e.hasNext()) {
e.next();
e.remove();
}
}
這個方法把集合清空,不過這個方法效率顯得比較低,清空應該不需要遍歷集合,不過子類可以重寫整個方法.
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("[");

Iterator i = iterator();
boolean hasNext = i.hasNext();
while (hasNext) {
Object o = i.next();
buf.append(o == this ? "(this Collection)" : String.valueOf(o));
hasNext = i.hasNext();
if (hasNext)
buf.append(", ");
}

buf.append("]");
return buf.toString();
}
最後一個方法瞭,就是把所有的元素用[]括起來返回,元素間用", "分隔.這裡唯一註意的是集合可以包含自己,如果沒有判斷就成死循環瞭.

留言

這個網誌中的熱門文章

Use Case Description(描述使用案例)

列出不重複的隨機亂數

子類別建構子super觀念