日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

Java|List.subList 踩坑小記

來源: 責編: 時間:2023-09-22 20:11:39 296觀看
導讀很久以前在使用 Java 的 List.subList 方法時踩過一個坑,當時記了一條待辦,要寫一寫這事,今天完成它。我們先來看一段代碼:// 初始化 list 為 { 1, 2, 3, 4, 5 }List<Integer> list = new ArrayList<>();for (int i = 1;

gZV28資訊網——每日最新資訊28at.com

很久以前在使用 Java 的 List.subList 方法時踩過一個坑,當時記了一條待辦,要寫一寫這事,今天完成它。gZV28資訊網——每日最新資訊28at.com

我們先來看一段代碼:gZV28資訊網——每日最新資訊28at.com

// 初始化 list 為 { 1, 2, 3, 4, 5 }List<Integer> list = new ArrayList<>();for (int i = 1; i <= 5; i++) {    list.add(i);}// 取前 3 個元素作為 subList,操作 subListList<Integer> subList = list.subList(0, 3);subList.add(6);System.out.println(list.size());

輸出是 5 還是 6?gZV28資訊網——每日最新資訊28at.com

沒踩過坑的我,會回答是 5,理由是:往一個 List 里加元素,關其它 List 什么事?gZV28資訊網——每日最新資訊28at.com

而掉過坑的我,口中直呼 666。gZV28資訊網——每日最新資訊28at.com

好了不繞彎子,我們直接看下 List.subList 方法的注釋文檔:gZV28資訊網——每日最新資訊28at.com

/** * Returns a view of the portion of this list between the specified * <tt>fromIndex</tt>, inclusive, and <tt>toIndex</tt>, exclusive.  (If * <tt>fromIndex</tt> and <tt>toIndex</tt> are equal, the returned list is * empty.)  The returned list is backed by this list, so non-structural * changes in the returned list are reflected in this list, and vice-versa. * The returned list supports all of the optional list operations supported * by this list.<p> * * This method eliminates the need for explicit range operations (of * the sort that commonly exist for arrays).  Any operation that expects * a list can be used as a range operation by passing a subList view * instead of a whole list.  For example, the following idiom * removes a range of elements from a list: * <pre>{@code *      list.subList(from, to).clear(); * }</pre> * Similar idioms may be constructed for <tt>indexOf</tt> and * <tt>lastIndexOf</tt>, and all of the algorithms in the * <tt>Collections</tt> class can be applied to a subList.<p> * * The semantics of the list returned by this method become undefined if * the backing list (i.e., this list) is <i>structurally modified</i> in * any way other than via the returned list.  (Structural modifications are * those that change the size of this list, or otherwise perturb it in such * a fashion that iterations in progress may yield incorrect results.) * * @param fromIndex low endpoint (inclusive) of the subList * @param toIndex high endpoint (exclusive) of the subList * @return a view of the specified range within this list * @throws IndexOutOfBoundsException for an illegal endpoint index value *         (<tt>fromIndex < 0 || toIndex > size || *         fromIndex > toIndex</tt>) */List<E> subList(int fromIndex, int toIndex);

這里面有幾個要點:gZV28資訊網——每日最新資訊28at.com

subList 返回的是原 List 的一個 視圖,而不是一個新的 List,所以對 subList 的操作會反映到原 List 上,反之亦然;gZV28資訊網——每日最新資訊28at.com

如果原 List 在 subList 操作期間發生了結構修改,那么 subList 的行為就是未定義的(實際表現為拋異常)。gZV28資訊網——每日最新資訊28at.com

第一點好理解,看到「視圖」這個詞相信大家就都能理解了。我們甚至可以結合 ArrayList 里的 SubList 子類源碼進一步看下:gZV28資訊網——每日最新資訊28at.com

private class SubList extends AbstractList<E> implements RandomAccess {    private final AbstractList<E> parent;    // ...    SubList(AbstractList<E> parent,            int offset, int fromIndex, int toIndex) {        this.parent = parent;        // ...        this.modCount = ArrayList.this.modCount;    }    public E set(int index, E e) {        // ...        checkForComodification();        // ...        ArrayList.this.elementData[offset + index] = e;        // ...    }    public E get(int index) {        // ...        checkForComodification();        return ArrayList.this.elementData(offset + index);    }    public void add(int index, E e) {        // ...        checkForComodification();        parent.add(parentOffset + index, e);        this.modCount = parent.modCount;        // ...    }    public E remove(int index) {        // ...        checkForComodification();        E result = parent.remove(parentOffset + index);        this.modCount = parent.modCount;        // ...    }    private void checkForComodification() {        if (ArrayList.this.modCount != this.modCount)            throw new ConcurrentModificationException();    }    // ...}

可以看到幾乎所有的讀寫操作都是映射到 ArrayList.this、或者 parent(即原 List)上的,包括 size、add、remove、set、get、removeRange、addAll 等等。gZV28資訊網——每日最新資訊28at.com

第二點,我們在文首的示例代碼里加上兩句代碼看現象:gZV28資訊網——每日最新資訊28at.com

list.add(0, 0);System.out.println(subList);

System.out.println 會拋出異常 java.util.ConcurrentModificationException。gZV28資訊網——每日最新資訊28at.com

我們還可以試下,在聲明 subList 后,如果對原 List 進行元素增刪操作,然后再讀寫 subList,基本都會拋出此異常。gZV28資訊網——每日最新資訊28at.com

因為 subList 里的所有讀寫操作里都調用了 checkForComodification(),這個方法里檢驗了 subList 和 List 的 modCount 字段值是否相等,如果不相等則拋出異常。gZV28資訊網——每日最新資訊28at.com

modCount 字段定義在 AbstractList 中,記錄所屬 List 發生 結構修改 的次數。結構修改 包括修改 List 大小(如 add、remove 等)、或者會使正在進行的迭代器操作出錯的修改(如 sort、replaceAll 等)。gZV28資訊網——每日最新資訊28at.com

好了小結一下,這其實不算是坑,只是 不應該僅憑印象和猜測,就開始使用一個方法,至少花一分鐘認真讀完它的官方注釋文檔。gZV28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-11204-0.htmlJava|List.subList 踩坑小記

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 基于Python+Flask實現一個簡易網頁驗證碼登錄系統案例

下一篇: 網絡安全:滲透測試工程師必備的十種技能

標簽:
  • 熱門焦點
  • Rust中的高吞吐量流處理

    作者 | Noz編譯 | 王瑞平本篇文章主要介紹了Rust中流處理的概念、方法和優化。作者不僅介紹了流處理的基本概念以及Rust中常用的流處理庫,還使用這些庫實現了一個流處理程序
  • K8S | Service服務發現

    一、背景在微服務架構中,這里以開發環境「Dev」為基礎來描述,在K8S集群中通常會開放:路由網關、注冊中心、配置中心等相關服務,可以被集群外部訪問;圖片對于測試「Tes」環境或者
  • 分享六款相見恨晚的PPT模版網站, 祝你做出精美的PPT!

    1、OfficePLUSOfficePLUS網站旨在為全球Office用戶提供豐富的高品質原創PPT模板、實用文檔、數據圖表及個性化定制服務。優點:OfficePLUS是微軟官方網站,囊括PPT模板、Word模
  • 每天一道面試題-CPU偽共享

    前言:了不起:又到了每天一到面試題的時候了!學弟,最近學習的怎么樣啊 了不起學弟:最近學習的還不錯,每天都在學習,每天都在進步! 了不起:那你最近學習的什么呢? 了不起學弟:最近在學習C
  • 10天營收超1億美元,《星鐵》比《原神》差在哪?

    來源:伯虎財經作者:陳平安即便你沒玩過《原神》,你一定聽說過的它的大名。恨它的人把《原神》開服那天稱作是中國游戲史上最黑暗的一天,有粉絲因為索尼在PS平臺上線《原神》,怒而
  • 重估百度丨大模型,能撐起百度的“今天”嗎?

    自象限原創 作者|程心 羅輯2023年之前,對于自己的&ldquo;今天&rdquo;,百度也很迷茫。&ldquo;新業務到 2022 年底還是 0,希望 2023 年出來一個 1。&rdquo;這是2022年底,李彥宏
  • 朋友圈可以修改可見范圍了 蘋果用戶可率先體驗

    近日,iOS用戶迎來微信8.0.27正式版更新,除了可更換二維碼背景外,還新增了多項實用功能。在新版微信中,朋友圈終于可以修改可見范圍,簡單來說就是已發布的朋友圈
  • 電博會與軟博會實現"線下+云端"的雙線融合

    在本次“電博會”與“軟博會”雙展會利好條件的加持下,既可以發揮展會拉動人流、信息流、資金流實現快速交互流動的作用,繼而推動區域經濟良性發展;又可以聚
  • 榮耀Magic4 至臻版 首創智慧隱私通話 強勁影音系統

    2022年第一季度臨近尾聲,在該季度內,許多品牌陸續發布自己的最新產品,讓大家從全新的角度來了解當今的手機技術。手機是電子設備中,更新迭代十分迅速的一款產品,基
Top 主站蜘蛛池模板: 高雄市| 沙坪坝区| 九龙坡区| 荣昌县| 长宁县| 台东市| 绥宁县| 本溪| 平南县| 乌审旗| 黄平县| 赤城县| 攀枝花市| 嘉峪关市| 当阳市| 水富县| 罗甸县| 兴安县| 镇雄县| 色达县| 山东| 酉阳| 黑山县| 烟台市| 湖北省| 茂名市| 碌曲县| 永新县| 凉城县| 百色市| 常宁市| 望城县| 叶城县| 东乡县| 甘南县| 广元市| 大连市| 堆龙德庆县| 增城市| 澜沧| 大埔区|