Java ArrayList使用技巧 - 從第一個(gè)List中去除所有第二個(gè)List中與之重復(fù)的元素

需求:從 mAllList 中去除所有 mSubList 中與之重復(fù)的元素
測(cè)試數(shù)據(jù):mAllList 中包含100000個(gè)無(wú)序無(wú)重復(fù)字符串,mSubList 中包含50000個(gè)無(wú)序無(wú)重復(fù)字符串

方法一、ArrayList中提供的removeAll方法(效率最低)
mAllList.removeAll(mSubList);

某次測(cè)試耗時(shí):185665ms

方法二、雙重循環(huán)(比方法一效率高)

雙重循環(huán)分為內(nèi)外兩層循環(huán),經(jīng)過(guò)測(cè)試,將元素多的list放在外層循環(huán)效率更高(mSubList中的元素可能比mAllList多)(被刪除元素的列表mAllList放在外層循環(huán)和內(nèi)層循環(huán)的實(shí)現(xiàn)方式有些差別),這里的測(cè)試數(shù)據(jù)是mAllList中的元素多,實(shí)現(xiàn)如下:

int maxSize = mAllList.size();
for (int i = maxSize-1; i >=0; i--) {
    int size = mSubList.size();
    while (size > 0) {
        String s = mSubList.get(size-1);
        if (s.equals(mAllList.get(i))) {
            mSubList.remove(size-1);
            mAllList.remove(i);
            break;
        }
        size--;
    }
}

某次測(cè)試耗時(shí):101510ms

方法三、利用HashMap(效率最高)
//第一步:構(gòu)建mAllList的HashMap
//將mAllList中的元素作為鍵,如果不是String類,需要實(shí)現(xiàn)hashCode和equals方法
//將mAllList中的元素對(duì)應(yīng)的位置作為值
Map<String, Integer> map = new HashMap<>();
for (int i = 0; i < mAllList.size(); i++) {
    map.put(mAllList.get(i), i);
}
//第二步:利用map遍歷mSubList,查找重復(fù)元素
//把mAllList中所有查到的重復(fù)元素的位置置空
for (int i = 0; i < mSubList.size(); i++) {
    Integer pos = map.get(mSubList.get(i));
    if (pos==null) {
        continue;
    }
    mAllList.set(pos, null);
}
//第三步:把mAllList中所有的空元素移除
for (int i = mAllList.size()-1; i>=0; i--) {
    if (mAllList.get(i)==null) {
        mAllList.remove(i);
    }
}

某次測(cè)試耗時(shí):712ms

方法三的一些說(shuō)明
  1. 方法三中初始化HashMap的時(shí)候已經(jīng)知道了容量大小,理論上直接指定HashMap的大小避免擴(kuò)容可以提高效率,但是測(cè)試發(fā)現(xiàn)并沒(méi)有提高,100000條數(shù)據(jù)都是幾十毫秒
  2. 雖然方法三中HashMap存的值是整數(shù),但是不要使用int pos = map.get(mSubList.get(i));取值,會(huì)崩潰
  3. 第二步中,使用Integer pos = map.get(mSubList.get(i));取值,然后判斷 pos 是否是空來(lái)判斷map中是否包含鍵是mSubList.get(i)的值,比用map.containsKey(key)來(lái)判斷然后get取值少訪問(wèn)一次哈希表
  4. 第三步中,從mAllList尾部開(kāi)始遍歷移除

HashMap不了解的可以看下Java HashMap原理解析

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 34,734評(píng)論 18 399
  • 從法語(yǔ)小哥那學(xué)到的正宗用法奉上! 1、d’accord 這個(gè)詞簡(jiǎn)直可以說(shuō)高頻了!相當(dāng)于漢語(yǔ)的嗯英語(yǔ)的OK 還有一種...
    小朋是個(gè)寶寶閱讀 335評(píng)論 0 0
  • 自信是人的最大資本 你是否篤信你能變成更好的自己? 這句話瞬間觸動(dòng)我,細(xì)想一下,在參加讀書(shū)營(yíng)之前我好想一直不相信會(huì)...
    秋秋小Q閱讀 160評(píng)論 0 0

友情鏈接更多精彩內(nèi)容