Java List移除相應(yīng)元素的超簡(jiǎn)潔寫(xiě)法分享
List移除相應(yīng)元素的超簡(jiǎn)潔寫(xiě)法
最近遇到了一個(gè)需求(好吧以前也遇到過(guò)),就是將一個(gè)List中的部分元素去除,如把string中帶數(shù)字的元素去除,以前是各種遍歷各種不爽,今天發(fā)現(xiàn)用Java8中的lambda寫(xiě),只需三行。
好了上代碼
List<String> list = new ArrayList<String>(){
{
// 為list添加數(shù)據(jù)
addAll(Arrays.asList("wangzhen456liupei123".split("")));
add("1521"); // 純數(shù)字?jǐn)?shù)據(jù)
add("wanghzen123") // 數(shù)字+字符數(shù)據(jù)
add("wangzhen"); // 純字符串
}
};
System.out.println("初始數(shù)據(jù):" + list);
Pattern pattern = Pattern.compile("\\d");//匹配數(shù)字
Predicate<String> filter = s -> pattern.matcher(s).find();
list.removeIf(filter);//移除
System.out.println(list);
輸出如下:
初始數(shù)據(jù):[w, a, n, g, z, h, e, n, 4, 5, 6, l, i, u, p, e, i, 1, 2, 3, 1521, wangzhen] [w, a, n, g, z, h, e, n, l, i, u, p, e, i, wangzhen]
其實(shí)有機(jī)智的朋友可能已經(jīng)發(fā)現(xiàn)了,不要說(shuō)三行了,一行都可以:
list.removeIf(s -> Pattern.compile("\\d").matcher(s).find());
雖說(shuō)如果你想這樣寫(xiě)也沒(méi)人能攔著你(同時(shí)你也要確定三個(gè)月之后依然能看懂)。但是從代碼的可讀性和可維護(hù)性角度來(lái)講,倒是不如前面三行的那個(gè)寫(xiě)法。
總結(jié):越精簡(jiǎn)的代碼就越應(yīng)該有注釋,不然哪天手一抽就Ctrl+/了 XD
Java List 刪除元素
在Java中,使用List時(shí)想要?jiǎng)h除某個(gè)特定個(gè)元素怎么辦?很好辦!因?yàn)長(zhǎng)ist接口有remove()這個(gè)方法,我們只需要調(diào)用remove()方法,就可以刪除list中的某個(gè)元素。但是list自帶的有一些坑,在相鄰有相同元素時(shí)會(huì)掉坑:
使用list.remove()刪除:

我們看到有兩個(gè)“a”元素相鄰,但是刪除時(shí)卻只刪除了一個(gè),這是為何呢?因?yàn)閯h除時(shí),每刪除一個(gè)元素,后邊的元素都會(huì)左移一位,也就是下標(biāo)會(huì)減1,在for循環(huán)中,刪除第一個(gè)“a”時(shí),i(下標(biāo))為0,此時(shí)list重排,后邊的元素全部左移1位,也就是說(shuō)第二個(gè)“a”元素的下標(biāo)從1變?yōu)榱?,而此時(shí)for循環(huán)進(jìn)行已經(jīng)第二次循環(huán)了,執(zhí)行了i++,i的值為1,對(duì)應(yīng)為“b”元素,然后向后循環(huán),再也找不到“a”元素了。所以相鄰元素有重復(fù)的話,只能刪除一個(gè)。這明顯不符合我們的需求。
那解決辦法是什么呢?
1.刪除后元素后,i-1

刪除一個(gè)元素后,后邊的元素左移1位,此時(shí)i-1,保證了下次循環(huán)能訪問(wèn)到左移了1位的元素。
2.反向刪除
我們先從后邊的元素開(kāi)始循環(huán),一個(gè)一個(gè)的往前面循環(huán),找出特定元素刪除

這樣,就算刪除了倒數(shù)第一個(gè)"a"元素,list重排,也只是把后邊的元素左移1位,此時(shí)倒數(shù)第一個(gè)“a”元素(下標(biāo)為1)被刪除,接著b替代了a成為了下標(biāo)為1的元素,但前邊的元素不變,i-- = 0 后依然能夠找到其相鄰的a元素。
3.使用迭代器刪除(iterator)(推薦)

Iterator.remove() 方法會(huì)在刪除當(dāng)前迭代對(duì)象的同時(shí),會(huì)保留原來(lái)元素的索引。所以用迭代刪除元素是最保險(xiǎn)的方法,建議大家使用List過(guò)程,這其實(shí)和上面第一中方法類似,只不過(guò)iterator內(nèi)部幫我們做了類似i-1的操作。推薦使用這種做法,因?yàn)槲覀儾槐WC每次都記得手動(dòng)把下標(biāo)減去1。
4.賦值給新的list

其實(shí)我們可以轉(zhuǎn)換思維,可以過(guò)濾掉不需要的元素后賦值給新的list對(duì)象,利用java8的lambda表達(dá)式和強(qiáng)大的stream流形式進(jìn)行內(nèi)部迭代來(lái)過(guò)濾掉特定元素,我們只需一行代碼就可以實(shí)現(xiàn)。雖然這種方式比較簡(jiǎn)潔,但是定義了新變量,舊的list就只能等待漫長(zhǎng)的gc了。
注意:在進(jìn)行普通for循環(huán)刪除時(shí),不要把list.size()抽離出去賦值給變量,然后用此變量做為for條件, 因?yàn)閯h除時(shí),list.size()的值是會(huì)改變的,要把list.size作為for條件。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
使用Java實(shí)現(xiàn)6種常見(jiàn)負(fù)載均衡算法
Java負(fù)載均衡算法也是分布式系統(tǒng)中的重要組成部分,用于將來(lái)自客戶端的請(qǐng)求分配到不同的后端服務(wù)器上,本文將介紹常見(jiàn)的Java負(fù)載均衡算法,輪詢法、加權(quán)隨機(jī)法……一次性讓你了解?6?種常見(jiàn)負(fù)載均衡算法2023-06-06
MyBatis基于pagehelper實(shí)現(xiàn)分頁(yè)原理及代碼實(shí)例
這篇文章主要介紹了MyBatis基于pagehelper實(shí)現(xiàn)分頁(yè)原理及代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06
SpringBoot混合使用StringRedisTemplate和RedisTemplate的坑及解決
這篇文章主要介紹了SpringBoot混合使用StringRedisTemplate和RedisTemplate的坑及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12
Java實(shí)現(xiàn)的質(zhì)因數(shù)分解操作示例【基于遞歸算法】
這篇文章主要介紹了Java實(shí)現(xiàn)的質(zhì)因數(shù)分解操作,結(jié)合實(shí)例形式較為詳細(xì)的分析了Java基于遞歸算法實(shí)現(xiàn)針對(duì)整數(shù)的質(zhì)因數(shù)分解相關(guān)操作技巧,需要的朋友可以參考下2018-03-03
JAVA實(shí)現(xiàn)圖書(shū)管理系統(tǒng)項(xiàng)目
相信每一個(gè)學(xué)生學(xué)編程的時(shí)候,應(yīng)該都會(huì)寫(xiě)一個(gè)小項(xiàng)目——圖書(shū)管理系統(tǒng)。為什么這么說(shuō)呢?我認(rèn)為一個(gè)學(xué)校的氛圍很大一部分可以從圖書(shū)館的氛圍看出來(lái),而圖書(shū)管理系統(tǒng)這個(gè)不大不小的項(xiàng)目,接觸的多,也比較熟悉,不會(huì)有陌生感,能夠練手,又有些難度,所以我的小項(xiàng)目也來(lái)了2021-10-10

