JDK源碼解析之java.util.AbstractCollection

AbstractCollection類提供了collection的實現類應該具有的基本方法,具有一定的普適性,可以從大局上了解collection實現類的主要功能。

java.util.AbstractCollection這個類提供了對接口Collection骨骼級的實現。

在這里插入圖片描述

一、源碼解析

1、iterator():返回一個迭代器對象

public abstract Iterator<E> iterator();

2、 size():返回集合大小

public abstract int size();

3、isEmpty():判斷是否為空

public boolean isEmpty() {return size() == 0;
}

4、contains(Object o):是否包含指定元素

    public boolean contains(Object o) {Iterator<E> it = iterator();if (o==null) {while (it.hasNext())if (it.next()==null)return true;} else {while (it.hasNext())if (o.equals(it.next()))return true;}return false;}

5、toArray()

在函數toArray()中,首先根據collection當前的大小初始化一個數組,并根據集合大小設定期望的元素個數。而后使用迭代器依次遍歷集合中的元素,如果發現集合的元素自第i個起均被刪除,則直接返回r中的前i個元素。
如果發現在開始轉化后,集合中插入了新的元素,則會進入:擴容+復制的循環。其中擴容部分將數組容量擴展到原來的1.5倍。當復制過程中,數組容量再次填滿時,則又進行擴容。最后返回數組中所有有效的元素。

注意:該算法的復制并不是100%準確的,其只能保證其數組中元素的個數與集合迭代器遍歷的元素個數相同,且順序相同,而不是保證該數組中元素與集合元素相同。

5.1、把集合轉成數組
    public Object[] toArray() {// Estimate size of array; be prepared to see more or fewer elementsObject[] r = new Object[size()];Iterator<E> it = iterator();for (int i = 0; i < r.length; i++) {if (! it.hasNext()) // fewer elements than expectedreturn Arrays.copyOf(r, i);r[i] = it.next();}return it.hasNext() ? finishToArray(r, it) : r;}
5.2、把集合轉換為指定數組
    public <T> T[] toArray(T[] a) {// Estimate size of array; be prepared to see more or fewer elementsint size = size();T[] r = a.length >= size ? a :(T[])java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size);Iterator<E> it = iterator();for (int i = 0; i < r.length; i++) {if (! it.hasNext()) { // fewer elements than expectedif (a == r) {r[i] = null; // null-terminate} else if (a.length < i) {return Arrays.copyOf(r, i);} else {System.arraycopy(r, 0, a, 0, i);if (a.length > i) {a[i] = null;}}return a;}r[i] = (T)it.next();}// more elements than expectedreturn it.hasNext() ? finishToArray(r, it) : r;}
5.3、擴容然后賦值的操作,下標i和數組長度r.length相等時,就進行一次擴容,最后返回數組元素數量大小的一個數組
    private static <T> T[] finishToArray(T[] r, Iterator<?> it) {int i = r.length;while (it.hasNext()) {int cap = r.length;if (i == cap) {int newCap = cap + (cap >> 1) + 1;// overflow-conscious codeif (newCap - MAX_ARRAY_SIZE > 0)newCap = hugeCapacity(cap + 1);r = Arrays.copyOf(r, newCap);}r[i++] = (T)it.next();}// trim if overallocatedreturn (i == r.length) ? r : Arrays.copyOf(r, i);}private static int hugeCapacity(int minCapacity) {if (minCapacity < 0) // overflowthrow new OutOfMemoryError("Required array size too large");return (minCapacity > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE :MAX_ARRAY_SIZE;}

6、add():子類如果可以添加元素,需要重寫add方法

public boolean add(E e) {throw new UnsupportedOperationException();}

7、remove(Object o):應用迭代器,移除某個元素

    public boolean remove(Object o) {Iterator<E> it = iterator();if (o==null) {while (it.hasNext()) {if (it.next()==null) {it.remove();return true;}}} else {while (it.hasNext()) {if (o.equals(it.next())) {it.remove();return true;}}}return false;}

8、containsAll(Collection<?> c):是否包含指定數組的所有元素

    public boolean containsAll(Collection<?> c) {for (Object e : c)if (!contains(e))return false;return true;}

9、addAll(Collection<? extends E> c):循環調用add方法

    public boolean addAll(Collection<? extends E> c) {boolean modified = false;for (E e : c)if (add(e))modified = true;return modified;}

10、removeAll(Collection<?> c):移除與入參集合相同的元素

    public boolean removeAll(Collection<?> c) {Objects.requireNonNull(c);boolean modified = false;Iterator<?> it = iterator();while (it.hasNext()) {if (c.contains(it.next())) {it.remove();modified = true;}}return modified;}

11、retainAll(Collection<?> c):保留與入參集合中元素相同的元素

    public boolean retainAll(Collection<?> c) {Objects.requireNonNull(c);boolean modified = false;Iterator<E> it = iterator();while (it.hasNext()) {if (!c.contains(it.next())) {it.remove();modified = true;}}return modified;}

12、clear()清空集合所有元素

    public void clear() {Iterator<E> it = iterator();while (it.hasNext()) {it.next();it.remove();}}

13、toString():重寫了toString方法

    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(' ');}}

二、拓展

1、AbstractCollection的protected構造函數

抽象類AbstractCollection居然有protected構造函數

protected AbstractCollection() {}

關于抽象類的protected構造方法:

  • 首先,抽象類不能實例化是絕對正確的,因此抽象類中并不能包含public的構造方法;

  • 抽象類protected構造方法會被隱性調用,因此并不一定在其子類的構造方法中顯示調用super(),雖然對于AbstractCollection而言是建議這么做;

  • 抽象類的protected構造方法可以用于初始化類中的某些屬性,避免一場信息的出現。

2、只讀集合、可修改集合

AbstractCollection將其實現類分成兩種,一種為只讀集合,另一種為可修改集合。

在只讀集合中,只需要實現AbstractCollection中的iterator函數和size函數即可,其它的函數可以維持不變(在對性能沒要求的前提下),這保證了實現類只需要少量的工作,便可以將集合的功能基本實現。

而對于可修改集合,AbstractCollection要求不僅需要實現其中的兩個抽象方法,還需要實現add方法,并保證iterator函數返回的迭代器中實現了remove方法。

對于非抽象算法,AbstractCollection的建議為:如果有更加高效的實現方法,子類可以將其重寫(override)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/535634.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/535634.shtml
英文地址,請注明出處:http://en.pswp.cn/news/535634.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

溝通linux與windows的wine

據Netcraft網站調查&#xff0c;現在互聯網上的主機有75&#xff05;以上采用Linux作為操作系統。作為服務器操作系統&#xff0c;Linux已經站穩了腳步&#xff0c;可是在桌面 操作系統上&#xff0c;還是微軟的“瘟到死”一支獨秀。這倒不是說Linux不好&#xff0c;很大原因我…

備份spfil、控制文件等

delete backup&#xff1b; delete backupset delete noprompt backup backup keep forver database 永久保存恢復目錄中支持此命令 show parameter control 備份spfile backup spfile backup current contrlfile configure controlfile autoback …

日常問題——阿里云服務器ssh經常一段時間就斷掉解決辦法

#vim /etc/ssh/sshd_config 找到下面兩行 #ClientAliveInterval 0 #ClientAliveCountMax 3 去掉注釋&#xff0c;改成 ClientAliveInterval 30 ClientAliveCountMax 86400 這兩行的意思分別是 1、客戶端每隔多少秒向服務發送一個心跳數據 2、客戶端多少秒沒有相應&#…

在Ubuntu 8.04 LTS(hardy)下安裝配置nginx和fastcgi方式的php

最近我們(瑞豪開源Xen VPS: http://www.RasHost.com)的一個客戶要求在他的Ubuntu 8.04 VPS上安裝一個高性能的nginx&#xff0c;下面是我的安裝記錄。 由于Ubuntu 804已經包含了nginx&#xff0c;所以根本不要編譯&#xff0c;安裝超簡單&#xff01; 在VPS上修改/etc/apt/so…

apt-get包管理詳解

apt-get使用source.list文件進行軟件包管理。如果您想了解關于如何編輯和更新source.list中的條目的信息&#xff0c;請參閱SourcesList“起初GNU/Linux系統中只有.tar.gz。用戶必須自己編譯他們想使用的每一個程序。在Debian出現之後&#xff0c;人們認為有必要在系統中添 加一…

awk命令

awk是一個強大的文本分析工具&#xff0c;相對于grep的查找&#xff0c;sed的編輯&#xff0c;awk在其對數據分析并生成報告時&#xff0c;顯得尤為強大。簡單來說awk就是把文件逐行的讀入&#xff0c;以空格為默認分隔符將每行切片&#xff0c;切開的部分再進行各種分析處理。…

ubuntu安裝字符集

sudo locale-gen zh_CN.GBK sudo locale-gen zh_CN

正則表達式和grep

正則表達式(regular expression, RE)是一種字符模式&#xff0c;用于在查找過程中匹配指定的字符。 在大多數程序里&#xff0c;正則表達式都被置于兩個正斜杠之間;例如/lv[o0]e/就是由正斜杠界定的正則表達式&#xff0c;它將匹配被查找的行中任何位置出現的相同模式。在正則表…

GC 垃圾回收

垃圾回收機制是由垃圾收集器Garbage Collection GC來實現的&#xff0c;GC是后臺的守護進程。它的特別之處是它是一個低優先級進程&#xff0c;但是可以根據內存的使用情況動態的調整他的優先級。因此&#xff0c;它是在內存中低到一定限度時才會自動運行&#xff0c;從而實現對…

如何讓你變得魅力十足

我們每個人都希望自己在某些方面對他人來說是有用的。我們渴望那種被人需要的感覺&#xff0c;覺得自己是有能力的&#xff0c;就像我們在某方面很與眾不同&#xff0c;很獨特一樣。 有些人非常有吸引力。他們是那些每當需要幫助便會被想起的人。他們是那些另你覺得非常有幫助…

日志linux

syslog日志系統&#xff1a; syslogd 系統&#xff0c;非內核產生的信息 man 2 syslog klogd 內核&#xff0c;專門負責內核產生的信息 man 3 syslog /var/log/messages 系統標準錯誤日志信息&#xff0c;非內核 syslogd /var/log/dmesg klogd 共同配置文件etc/…

sysbench的安裝和做性能測試

sysbench是一個模塊化的、跨平臺、多線程基準測試工具&#xff0c;主要用于評估測試各種不同系統參數下的數據庫負載情況。關于這個項目的詳細介紹請看&#xff1a;http://sysbench.sourceforge.net。它主要包括以下幾種方式的測試&#xff1a;1、cpu性能2、磁盤io性能3、調度程…

加密解密

PKI public key Infrastructure 公鑰基礎設施 CRl 證書吊銷列表 CA證書頒發機構 Certificate Authority x509 證書 包括公鑰、過期時間、證書的合法擁有者、證書如何被使用 CA的信息 CA的校驗碼等等 Pki實現方式 TLS/ssl:x509 opengpg ssl安全的套接字層…

高性能MySQL(1)——MYSQL架構

MySQL最重要、最與眾不同的特性是它的存儲引擎架構&#xff0c;這種架構將查詢處理與數據的存儲/提取相分離&#xff0c;使得可以在使用時根據不同的需求來選擇數據存儲的方式。 一、Mysql邏輯架構 如果能在頭腦中構建出一幅MySQL各組件之間如何協同工作的架構圖&#xff0c;就…

數據庫設計中的14個關鍵技巧

1. 原始單據與實體之間的關系  可以是一對一、一對多、多對多的關系。在一般情況下&#xff0c;它們是一對一的關系&#xff1a;即一張原始單據對應且只對應一個實體。在特殊情況下&#xff0c;它們可能是一對多或多對一的關系&#xff0c;即一張原始單證對應多個實體&#xf…

高性能MySQL(2)——Schema與數據類型的優化

良好的邏輯設計和物理設計是高性能的基石&#xff0c;應該根據系統將要執行的查詢語句來設計 schema,這往往需要權衡各種因素。 一、選擇優化的數據類型 MySQL支持的數據類型非常多&#xff0c;選擇正確的數據類型對于獲得高性能至關重要。不管 存儲哪種類型的數據&#xff0c…

用戶權限sudo、suid、sgid以及facl等

su 切換用戶或以指定用戶運行命令。 使用su可以指定運行命令的身份(user/group/uid/gid)。 為了向后兼容&#xff0c;su默認不會改變當前目錄&#xff0c;且僅設置HOME和SHELL這兩個環境變量(若目標用戶非root&#xff0c;則還設置USER和LOGNAME環境變量)。推薦使用--login選項…

MySQL 服務器調優

關于 MySQL 調優 有 3 種方法可以加快 MySQL 服務器的運行速度&#xff0c;效率從低到高依次為&#xff1a; 替換有問題的硬件。 對 MySQL 進程的設置進行調優。 對查詢進行優化。 替換有問題的硬件通常是我們的第一考慮&#xff0c;主要原因是數據庫會占用大量資源。不過這…

通過腳本啟動批量服務

/app/all_start_script/wwyt/此目錄服務如下&#xff1a;apigateway.sh auth.sh config.sh register.sh zipkin.sh /app/all_start_script/other/此目錄服務如下&#xff1a; tomcat.sh wwyt_base.sh wwyt_cache.sh wwyt_flow.sh wwyt_risk_login.sh ww…

高性能MySQL(3)——創建高性能索引

索引對于良好的性能非常關鍵。尤其是當表中的數據量越來越大時&#xff0c;索引對性能的影響愈發重要。 一、索引的類型 在MySQL中&#xff0c;索引是在存儲引擎層而不是服務器層實現的。所以沒用統一的索引標準&#xff0c;不同存儲引擎的索引工作方式并不相同。 1.1、B-Tre…