成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java中如何優(yōu)雅地刪除List中的元素

kelvinlee / 649人閱讀

摘要:刪除元素后,立即跳出,則正常退出,但不能向后繼續(xù)循環(huán)了刪除后立馬終端循環(huán),會正常跳出,但代價是不能繼續(xù)向后循環(huán)了使用迭代器使用迭代器可,正確無誤的刪除,代碼簡潔優(yōu)雅,推薦使用使用迭代器可,正確無誤的刪除注意這里時而不是

在工作中的許多場景下,我們都會使用到List這個數(shù)據(jù)結(jié)構(gòu),那么同樣的有很多場景下需要刪除List中的某一個元素或某幾個元素,那么我們該如何正確無誤地刪除List中的元素的,今天我來教大家三種方式。

前提知識準(zhǔn)備 for循環(huán)的執(zhí)行順序

這里借用百度百科的一張圖,簡明扼要的介紹一下

Iterator介紹

迭代器:迭代其實(shí)我們可以簡單地理解為遍歷,是一個標(biāo)準(zhǔn)化遍歷各類容器里面的所有對象的方法類,它是一個很典型的設(shè)計模式。Iterator 模式是用于遍歷集合類的標(biāo)準(zhǔn)訪問方法。它可以把訪問邏輯從不同類型的集合類中抽象出來,從而避免向每次遍歷前都需要知道要遍歷集合的內(nèi)部結(jié)構(gòu)。

// 遍歷list
List list = new ArrayList();
list.add(1);
list.add(2);
for (int i = 0; i < list.size(); i++) {
    Object object = list.get(i);
    // do something
}

// 遍歷map
Map map = new HashMap<>();
map.put("1","first");
map.put("2","second");
for (Map.Entry entry : map.entrySet()){
    String key = entry.getKey();
    String value = entry.getValue();
    // do something
}

對于這兩種方式,我們總是都事先知道集合的內(nèi)部結(jié)構(gòu),訪問代碼和集合本身是緊密耦合的,無法將訪問邏輯從集合類和遍歷方法中分離出來。同時每一種集合對應(yīng)一種遍歷方法,代碼無法復(fù)用。
為了解決以上問題, Iterator 模式騰空出世,它總是用同一種邏輯來遍歷集合。使得需要遍歷集合的人,在遍歷的時候不需要了解集合的內(nèi)部結(jié)構(gòu),所有的內(nèi)部狀態(tài)都由 Iterator 來維護(hù)。遍歷集合的方法不直接和集合類打交道,它總是控制 Iterator,向它發(fā)送”向前”,”向后”,”取當(dāng)前元素”的命令,就可以間接遍歷整個集合。

兩種錯誤的方式 for循環(huán)順序遍歷

直接使用簡單for循環(huán),以for (int i = 0; i < list.size(); i++) 進(jìn)行遍歷,這種方式可能會在遍歷的過程中漏掉部分元素,從而出現(xiàn)少刪的情況。

/**
 * 通過簡單的遍歷方式,在遍歷的過程中有可能會漏掉元素
 * 取第二個元素i=1時,滿足條件被刪掉,原有的數(shù)組的第三個元素,變成了新數(shù)組的第二個元素
 * i++后i=2,但i=2指向的是新數(shù)組中的第三個元素,那么原數(shù)組中的第三個元素就被漏掉了
 *
 * @param list
 * @param element
 * @return
 */
public static List forRemove(List list, Object element) {
    for (int i = 0; i < list.size(); i++) {
        if (element.equals(list.get(i))) {
            list.remove(i);
        }
    }
    return list;
}
增強(qiáng)for循環(huán),刪除后不退出

使用增強(qiáng)for循環(huán)是,如果刪除后繼續(xù)向下循環(huán)則會報java.util.ConcurrentModificationException

/**
 * 使用增強(qiáng)for循環(huán)是,如果刪除后繼續(xù)向下循環(huán)則會報
 * java.util.ConcurrentModificationException
 *
 * @param list
 * @param element
 * @return
 */
public static List forceForRemove(List list, Object element) {
    for (Object item : list) {
        if (item.equals(element)) {
            list.remove(item);
        }
    }
    return list;
}

異常如下:

Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
    at java.util.ArrayList$Itr.next(ArrayList.java:851)
    at com.lingyejun.leetcode.RemoveListElement.forceForRemove(RemoveListElement.java:57)
    at com.lingyejun.leetcode.RemoveListElement.main(RemoveListElement.java:112)
三種正確方式 逆向循環(huán)遍歷

我們使用逆向遍歷的方式可以得到正確的結(jié)果

/**
 * 逆向循環(huán),是正確的
 * 1-->2-->3-->4
 * 逆向循環(huán)時,倒數(shù)第一個元素滿足條件被刪除時,i--后,原數(shù)組的倒數(shù)第二個變成了新數(shù)組的倒數(shù)第一個元素
 * i = size-2指向新數(shù)組的最后一個元素,沒有漏掉。
 * 同理倒數(shù)第二個元素滿足條件被刪除時,i--后,原數(shù)組的倒數(shù)第三個變成了新數(shù)組的倒數(shù)第二個元素
 * i= size-3指向新數(shù)組的倒數(shù)第二個元素,也沒有漏掉
 *
 * @param list
 * @param element
 * @return
 */
public static List reverseorRemove(List list, Object element) {
    for (int i = list.size() - 1; i >= 0; i--) {
        if (element.equals(list.get(i))) {
            list.remove(i);
        }
    }
    return list;
}
增強(qiáng)for循環(huán)刪除元素后break

使用增強(qiáng)for循環(huán),刪除元素后,立即跳出,則正常退出,但缺點(diǎn)是不能向后繼續(xù)循環(huán)了。

/**
 * 刪除元素后,立即跳出,則正常退出,但不能向后繼續(xù)循環(huán)了
 *
 * @param list
 * @param element
 * @return
 */
public static List forceForRemove1(List list, Object element) {
    for (Object item : list) {
        if (item.equals(element)) {
            // 刪除后立馬終端循環(huán),會正常跳出,但代價是不能繼續(xù)向后循環(huán)了
            list.remove(item);
            break;
        }
    }
    return list;
}
使用Iterator迭代器

使用迭代器可,正確無誤的刪除,代碼簡潔優(yōu)雅,推薦使用!

/**
 * 使用迭代器可,正確無誤的刪除
 * 
 * @param list
 * @param element
 * @return
 */
public static List iteratorRemove(List list, Object element) {
    Iterator iterator = list.iterator();
    while (iterator.hasNext()) {
        Object cur = iterator.next();
        if (cur.equals(element)) {
            // 注意!??!這里時Iterator.remove()!!!而不是list.remove()!!!
            iterator.remove();
        }
    }
    return list;
}

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/72514.html

相關(guān)文章

  • 超強(qiáng)匯總:學(xué)習(xí)Python列表,只需這篇文章就夠了

    摘要:用方法,刪除指定值的元素第一個匹配項。注意這些值都可以大于列表長度,不會報越界。列表生成式,以內(nèi)整數(shù)的倍數(shù)生成器表達(dá)式結(jié)果結(jié)果結(jié)果結(jié)果結(jié)果本文原創(chuàng)并首發(fā)于微信公眾號貓,后臺回復(fù)愛學(xué)習(xí),免費(fèi)獲得本精選電子書。 千里之行,始于足下。要練成一雙洞悉一切的眼睛,還是得先把基本功扎扎實(shí)實(shí)地學(xué)好。今天,本喵帶大家仔細(xì)溫習(xí)一下Python的列表。溫故而知新,不亦說乎。 當(dāng)然,溫習(xí)的同時也要發(fā)散思考,...

    G9YH 評論0 收藏0
  • python 歷險記——一個 Java 程序員的告白(一)

    摘要:元組也支持內(nèi)置函數(shù)的參數(shù)必須是一個序列字符串列表元組元組有什么用既然中有這么個數(shù)據(jù)結(jié)構(gòu),自然就有它的用武之地。 引言 想學(xué)爬蟲還是 python 專業(yè)啊,之前一直在用 java, 現(xiàn)在決定嘗嘗鮮,使用 python及爬蟲框架來完成網(wǎng)絡(luò)數(shù)據(jù)采集。編程語言之間都是相通的,比如都需要模塊化,引入其他文件來實(shí)現(xiàn)功能,使用列表等容器來處理數(shù)據(jù),都要使用 json 或 xml 來解析和傳輸數(shù)據(jù)。你...

    leejan97 評論0 收藏0
  • python 歷險記——一個 Java 程序員的告白(一)

    摘要:元組也支持內(nèi)置函數(shù)的參數(shù)必須是一個序列字符串列表元組元組有什么用既然中有這么個數(shù)據(jù)結(jié)構(gòu),自然就有它的用武之地。 引言 想學(xué)爬蟲還是 python 專業(yè)啊,之前一直在用 java, 現(xiàn)在決定嘗嘗鮮,使用 python及爬蟲框架來完成網(wǎng)絡(luò)數(shù)據(jù)采集。編程語言之間都是相通的,比如都需要模塊化,引入其他文件來實(shí)現(xiàn)功能,使用列表等容器來處理數(shù)據(jù),都要使用 json 或 xml 來解析和傳輸數(shù)據(jù)。你...

    newtrek 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<