最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java?ArrayList實現(xiàn)刪除指定位置的元素

 更新時間:2023年01月09日 09:16:33   作者:海棠路  
目標(biāo):list中有0到39共40個元素,刪除其中索引是10、20、30的元素。本文為大家整理了三個不同的方法,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

目標(biāo):list中有0到39共40個元素,刪除其中索引是10、20、30的元素

方案一:使用普通for循環(huán)從前往后遍歷再刪除

//初始化List列表
List<String> list = new ArrayList<>();
for (int i = 0; i < 40; i++) {
    list.add("element" + i);
}

首先當(dāng)我們刪除第10位元素時,List會將后面的元素向前補位,之后再查第10位元素就會輸出第11位元素

for (int i = 0; i < list.size(); i++) {
    if (i == 10) {
        list.remove(i);
    }
}
System.out.println(list.get(10));

輸出:

element11

那么刪除了一個元素以后,后面需要刪除的元素位置就向前提1位

/**
 * 如果明確需要刪除元素的位置
 * 那么可以這樣,每刪除一個元素后就把下一個要刪除元素的位置減1
 * 注意這么做有個需要注意的點,那就是每次刪除完節(jié)點后遍歷指針i需要減一,這樣在刪除兩個臨近節(jié)點時才不會出現(xiàn)問題
 * 比如要刪除10和11
 */
for (int i = 0; i < list.size(); i++) {
    if (i == 10) {
        list.remove(i);
        i--;
    }
    if (i == 19) {
        list.remove(i);
        i--;
    }
    if (i == 28) {
        list.remove(i);
        i--;
    }
}

System.out.println(list.contains("element10"));
System.out.println(list.contains("element20"));
System.out.println(list.contains("element30"));

輸出:

 false
 false
 false

當(dāng)然我們可以用一個數(shù)組或列表從小到大存儲需要刪除的位置,然后再for循環(huán)中進行運算和取值

方案二:使用普通for循環(huán)從后往前遍歷再刪除

從后向前遍歷的好處是我們不需要再像方案一一樣每刪除一個元素都需要去考慮后面元素向前補位的問題

for (int i = list.size() - 1; i >= 0; i--) {
    if (i == 30) {
        list.remove(i);
    }
    if (i == 20) {
        list.remove(i);
    }
    if (i == 10) {
        list.remove(i);
    }
}
System.out.println(list.contains("element10"));
System.out.println(list.contains("element20"));
System.out.println(list.contains("element30"));

輸出:

 false
 false
 false

從后向前,即使后面進行元素進行向前補位操作也不會影響前面需要刪除的元素

這里也可以用一個數(shù)組或列表存儲需要刪除的元素,從大到小排列,取出一個刪除一個

方案三:使用迭代器刪除

Iterator<String> iterator = list.iterator();
int i = 0;
while (iterator.hasNext()) {
    String next = iterator.next();
    if (i == 10) {
        iterator.remove();
    }
    i++;
}
System.out.println(list.get(10));
System.out.println(list.contains("element10"));

輸出:

element11
false

在迭代器中維護一個數(shù)字i標(biāo)識遍歷的位置

如果我們在迭代器中繼續(xù)刪除另外20和30位置元素

Iterator<String> iterator = list.iterator();
int i = 0;
while (iterator.hasNext()) {
    String next = iterator.next();
    if (i == 10) {
        iterator.remove();
    }
    if (i == 20) {
        iterator.remove();
    }
    if (i == 30) {
        iterator.remove();
    }
    i++;
}
System.out.println(list.get(10));
System.out.println(list.contains("element10"));
System.out.println(list.get(20));
System.out.println(list.contains("element20"));
System.out.println(list.get(30));
System.out.println(list.contains("element30"));

輸出:

element11
false
element22
false
element33
false

首先我們在迭代過程中指定的是刪除10、20、30三個位置的元素,可以看到輸出contains時都是false表示正確刪除,但是最終輸出列表的值發(fā)現(xiàn)對應(yīng)索引位置已經(jīng)進行了補位。

我們debug分析一下為什么

先簡單介紹一下Iterator和Iterable

Iterable是一個迭代接口,實現(xiàn)了這個接口代表該類可以迭代

可以看到我們的集合Collection接口就是它的子類

它有一個主要方法:

// 返回一個實現(xiàn)了Iterator接口的對象,我們也是用這個對象去進行迭代
Iterator<T> iterator();

Iterator,它主要有三個方法:

// 返回是否還有下一個元素
boolean hasNext();
// 返回下一個元素
E next();
// 刪除該元素
default void remove() {
    throw new UnsupportedOperationException("remove");
}

每個不同的集合類都會有不同的Iterator接口實現(xiàn),在ArrayList中使用了一個內(nèi)部類來實現(xiàn)

private class Itr implements Iterator<E> {
    int cursor;       // index of next element to return
    int lastRet = -1; // index of last element returned; -1 if no such
    int expectedModCount = modCount;

    Itr() {}
}

我們通過list.iterator()拿到的就是這個內(nèi)部類的對象實例,這個類中有兩個字段cursor和lastRet,這兩個字段就是我們能在迭代器中正確刪除對應(yīng)位置的元素的關(guān)鍵。

有關(guān)expectedModCount和modCount的問題后面會補充,我們先不用關(guān)注

cursor初始化是0 lastRet初始化是-1

分析next和remove方法的源碼

/**
* 可以先不關(guān)注這兩個Exception
* 每次調(diào)用next() cursor都會+1 而lastRet就會變成之前cursor的值
* cursor初始化是0
* lastRet初始化是-1
* 調(diào)用一次以后  cursor是1 lastRet變成0
**/
public E next() {
    checkForComodification();
    int i = cursor;
    if (i >= size)
        throw new NoSuchElementException();
    Object[] elementData = ArrayList.this.elementData;
    if (i >= elementData.length)
        throw new ConcurrentModificationException();
    cursor = i + 1;
    return (E) elementData[lastRet = i];
}

public void remove() {
    if (lastRet < 0)
        throw new IllegalStateException();
    checkForComodification();

    try {
        // 調(diào)用本身的remove方法
        ArrayList.this.remove(lastRet);
        cursor = lastRet;
        lastRet = -1;
        expectedModCount = modCount;
    } catch (IndexOutOfBoundsException ex) {
        throw new ConcurrentModificationException();
    }
}

關(guān)鍵是這個remove方法對cursor和lastRet的修改

假如正在刪除第10個元素

執(zhí)行remove方法前cursor應(yīng)該是11,lastRet是10

執(zhí)行了以后lastRet變成了-1,cursor變成了10

下次執(zhí)行next()方法返回的元素其實還是elementData[10]也就是List補位后正確的下一個元素,cursor變成了11,lastRet是10

總結(jié):使用迭代器遍歷時ArrayList會用lastRet和cursor兩個變量來維護當(dāng)前遍歷的元素索引和下一次需要遍歷元素的索引,通過這兩個變量就可以實現(xiàn)迭代中正確的刪除某個位置的元素。

到此這篇關(guān)于Java ArrayList實現(xiàn)刪除指定位置的元素的文章就介紹到這了,更多相關(guān)Java ArrayList刪除指定位置元素內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Spring中@Autowired注解是如何實現(xiàn)的

    詳解Spring中@Autowired注解是如何實現(xiàn)的

    在使用java?config的過程當(dāng)中,我們不可避免地會有各種各樣的注解打交道,其中,我們使用最多的注解應(yīng)該就是@Autowired注解了,這篇文章就來和大家聊聊它到底怎么實現(xiàn)的吧
    2023-07-07
  • 更改Maven軟件源為阿里云源的方法詳解

    更改Maven軟件源為阿里云源的方法詳解

    這篇文章主要介紹了更改Maven軟件源為阿里云源的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • Spring Integration 實現(xiàn)消息驅(qū)動的詳細(xì)步驟

    Spring Integration 實現(xiàn)消息驅(qū)動的詳細(xì)步驟

    Spring Integration是一個用于構(gòu)建消息驅(qū)動的中間件輕量級框架,它提供了一種模型和工具,用于在Spring應(yīng)用程序中實現(xiàn)企業(yè)集成模式,這篇文章主要介紹了Spring Integration 實現(xiàn)消息驅(qū)動,需要的朋友可以參考下
    2024-05-05
  • Java無限級樹(遞歸)超實用案例

    Java無限級樹(遞歸)超實用案例

    下面小編就為大家?guī)硪黄狫ava無限級樹(遞歸)超實用案例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-11-11
  • java多線程之wait(),notify(),notifyAll()的詳解分析

    java多線程之wait(),notify(),notifyAll()的詳解分析

    本篇文章是對java多線程 wait(),notify(),notifyAll()進行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • java 轉(zhuǎn)發(fā)和重定向區(qū)別及實例代碼

    java 轉(zhuǎn)發(fā)和重定向區(qū)別及實例代碼

    這篇文章主要介紹了java 轉(zhuǎn)發(fā)和重定向區(qū)別及實例代碼的相關(guān)資料,需要的朋友可以參考下
    2016-11-11
  • Springboot+ElementUi實現(xiàn)評論、回復(fù)、點贊功能

    Springboot+ElementUi實現(xiàn)評論、回復(fù)、點贊功能

    這篇文章主要介紹了通過Springboot ElementUi實現(xiàn)評論、回復(fù)、點贊功能。如果是自己評論的還可以刪除,刪除的規(guī)則是如果該評論下還有回復(fù),也一并刪除。需要的可以參考一下
    2022-01-01
  • 用Maven插件生成Mybatis代碼的實現(xiàn)方法

    用Maven插件生成Mybatis代碼的實現(xiàn)方法

    本文主要介紹 Maven插件生成Mybatis代碼,現(xiàn)在做開發(fā)的朋友有好多用Maven 來管理代碼,這里給大家舉個例子,有需要的同學(xué)可以看下
    2016-07-07
  • SpringBoot中整合RabbitMQ(測試+部署上線最新完整)的過程

    SpringBoot中整合RabbitMQ(測試+部署上線最新完整)的過程

    本文詳細(xì)介紹了如何在虛擬機和寶塔面板中安裝RabbitMQ,并使用Java代碼實現(xiàn)消息的發(fā)送和接收,通過異步通訊,可以優(yōu)化性能,感興趣的朋友一起看看吧
    2025-02-02
  • Java中URL傳中文時亂碼的解決方法

    Java中URL傳中文時亂碼的解決方法

    為什么說亂碼是中國程序員無法避免的話題呢?這個主要是編碼機制上的原因,大家都知道中文和英文的編碼格式不一樣,解碼自然也不一樣!這篇文章就給大家分享了Java中URL傳中文時亂碼的解決方法,有需要的朋友們可以參考借鑒。
    2016-10-10

最新評論

新乐市| 娄底市| 武鸣县| 定陶县| 宁德市| 报价| 伊吾县| 芜湖县| 铜川市| 延吉市| 常德市| 泾川县| 中宁县| 天水市| 遵义市| 古交市| 双流县| 淳化县| 苍梧县| 菏泽市| 惠水县| 博客| 封开县| 宜都市| 馆陶县| 常宁市| 青田县| 乐都县| 南部县| 宁蒗| 赣州市| 合水县| 平谷区| 阿勒泰市| 辉南县| 蓬莱市| 和硕县| 锡林郭勒盟| 五原县| 商城县| 汶上县|