成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

還在自己寫迭代器進行remove?快來看看新方法

數據庫 其他數據庫
如果我們這時候要把第一個userList 中的數據導入數據庫,而 userEnd 則是數據庫中的數據,這時候,我們要根據姓名來區分的話,是不是應該之導入王五才對,這時候我們得篩選出王五的數據來,然后做導入,這個時候 removeIf 就派上用場了。

我們都知道 List 中是不允許在循環的過程中去進行移除元素的,為什么呢?一般的新人可能會遇到這個問題,比如說會從 List 的遍歷的過程中去進行 remove 數據,但是干過幾年的開發的有經驗的工作人員,是肯定不會這么干的,很簡單,會報錯。

List 進行 remove

我們可以來看一段代碼:

public static void main(String[] args) {
List<String> list= new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");

for (String s: list) {
if (s.equals("1")) {
list.remove(s);
}
}

System.out.println(list);
}

上面這段代碼,一般都是初入開發行業的小伙伴可能會這么寫,但是當你去運行的時候,就會發現會報一個錯誤。

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
at java.util.ArrayList$Itr.next(ArrayList.java:859)
at com.example.fastdfs.Test.main(Test.java:22)

但是當我們把代碼改成刪除元素 2 的時候,發現又成功了!!!

是真的,成功了,我們看代碼和運行結果:

public static void main(String[] args) {
List<String> list= new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");

for (String s: list) {
if (s.equals("2")) {
list.remove(s);
}
}

System.out.println(list);
}

運行結果如下:

圖片

為什么會出現這種情況,我刪除第一個元素不行,刪除第二個元素好用,刪除第三個元素又不行了,到底是什么原因導致的呢?

這時候我們就得去看看他的源碼編譯出來是什么樣子的。源碼如下:

public static void main(String[] args) {
List<String> list = new ArrayList();
list.add("1");
list.add("2");
list.add("3");
Iterator var2 = list.iterator();

while(var2.hasNext()) {
String s = (String)var2.next();
if (s.equals("3")) {
list.remove(s);
}
}

System.out.println(list);
}

也就是說,foreach 的循環內部,就是采用的iteratior形式,使用的核心方法是hasnext()和next()。

既然都使用迭代器了,為啥還是不行呢?我們來看看迭代器的源碼,然后分析一下為啥不行.

其實我們可以從報錯都能看出點端倪,報錯信息是ArrayList.java:909 

checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}

源代碼在執行 remove 方法的時候后,也是調用的 list 當中的remove 方法,源代碼中,就是這段:

public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}

中間調用的 fastRemove 方法中,中間就看到了:

    private void fastRemove(int index) {
modCount++;
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
}

這里我們的modCount++了

而當我們再一次循環的時候,調用的是list內部類itr的next方法,

在我們調用的list的remove的時候,modCount++了,而我們的expectedModCount是等于最開始modCount值.

這時候二者的值不相等的時候,就出現異常了。

歸根結底,雖然這個地方使用的是迭代器的遍歷,但是remove 的方法可不是迭代器的方法呀。

那么我們使用迭代器遍歷然后移除是什么樣子的呢?

    public static void main(String[] args) {
List<String> list= new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");

Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
String next = iterator.next();
if ("3".equals(next)){
iterator.remove();
}
}

System.out.println(list);
}

這么寫是不是有點多,那么應該如何快速的寫完這段代碼呢?

其實一行代碼就能很快解決這個事情,我們先來看代碼怎么寫的:

list.removeIf(vo-> "3".equals(vo));

也不用管返回值了,只要是能滿足這個條件的 ,那么就會從集合中給移除掉。

話不多說,看結果:

圖片

這么一看,是不是發現非常簡單方便,而且還快捷,而且如果要是對于代碼量來說的話,那肯定是非常的少的,但凡滿足條件的,肯定可以。

removeIf 的進階玩法

阿粉為什么稱之為進階玩法,實際上也并不是完整的進階玩法,比如說如果我們有一個功能是這樣的,要求做一個導入的功能,然后導入的數據只有一個車牌號是唯一值,之前導入的數據,不做處理,新增的文件中,可能會包含所有的數據,要求數據庫中已經存在的數據,不處理,然后導入數據庫中不存在的數據。

如果字段少的話,那么實現思路可能會有幾種。

第一種:

mybatis 的 SelectKey 標簽,判斷是否存在,如果存在就不進行新增。

第二種:

導入之前,查詢數據庫數據,比對數據,然后直接進行remove,最后不存在的數據導入

這兩種方法實際上都能實現,但是他們的適用情況就不太一樣了,如果字段非常多呢?

自己寫sql 的話,那么代價實在是有點大,如果你們使用的還是 Mybatis-plus 的話,那么肯定第一種方式好像就沒辦法使用了,只能使用第二種了。

那么我們的 removeIf 應該怎么來寫呢?

  //創建第一個UserList
List<User> userList = new ArrayList<>();
User user = new User();
user.setId(UUID.randomUUID().toString());
user.setName("張三");
user.setAge(20);
user.setDept("開發部");
userList.add(user);

User user1 = new User();
user1.setId(UUID.randomUUID().toString());
user1.setName("李四");
user1.setAge(22);
user1.setDept("測試部");
userList.add(user1);

User user2 = new User();
user2.setId(UUID.randomUUID().toString());
user2.setName("王五");
user2.setAge(27);
user2.setDept("財務部");
userList.add(user2);

//創建第二個UserList

List<User> userEnd= new ArrayList<>();
User user3= new User();
user3.setId(UUID.randomUUID().toString());
user3.setName("張三");
user3.setAge(20);
user3.setDept("開發部");
userEnd.add(user3);

User user4= new User();
user4.setId(UUID.randomUUID().toString());
user4.setName("李四");
user4.setAge(22);
user4.setDept("測試部");
userEnd.add(user4);

如果我們這時候要把第一個userList 中的數據導入數據庫,而 userEnd 則是數據庫中的數據,這時候,我們要根據姓名來區分的話,是不是應該之導入王五才對,這時候我們得篩選出王五的數據來,然后做導入,這個時候 removeIf 就派上用場了。

        userList.removeIf(us1-> userEnd.stream().anyMatch(u ->us1.getName().equals(u.getName())));

System.out.println(Arrays.toString(userList.toArray()));

我們最后來看看結果:

[User(id=029b0b0f-ad42-4c15-8341-a3bb401be6d6, name=王五, age=27, dept=財務部)]

是不是已經做到了呢?

你學會了么?

責任編輯:武曉燕 來源: Java極客技術
相關推薦

2024-06-03 00:00:06

高性能數據傳輸應用程序

2022-02-23 14:18:53

If-Else入參接口

2021-09-27 10:12:42

欺騙防御rMTD網絡攻擊

2018-03-06 09:54:48

數據庫備份恢復

2018-05-02 15:41:27

JavaScript人臉檢測圖像識別

2010-05-06 15:55:40

2010-04-01 09:30:57

2015-08-21 09:14:40

大數據

2019-07-12 13:50:36

物聯網大數據安全

2022-07-07 10:47:16

IngressKubernetes

2018-01-30 17:54:37

數據庫MySQLSQL Server

2018-03-12 10:35:01

LinuxBash快捷鍵

2021-04-19 09:23:26

數字化

2020-04-16 09:35:53

數據科學機器學習數據分析

2018-04-18 17:08:45

2020-11-04 08:40:23

C++多元組Tuple

2018-10-07 07:00:59

2022-05-12 15:17:09

GPU微軟神經網絡

2024-01-23 17:33:36

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 一区二区三区欧美大片 | a级黄色网 | 免费特级黄毛片 | 一区二区中文 | 操久久 | 干干干操操操 | 日韩一区二区在线播放 | 91正在播放| 我要看黄色录像一级片 | 97色在线视频 | 欧美成人h版在线观看 | 国产精品久久久av | 国产欧美在线视频 | 亚洲电影免费 | 久久a久久| 久久精品91久久久久久再现 | 久久久新视频 | 欧美日韩综合 | 日本又色又爽又黄的大片 | 日韩精品一区二区三区高清免费 | 国产精品精品3d动漫 | 亚洲视频中文字幕 | 96久久久久久 | 成人一区二区三区 | 青青草一区 | 国产清纯白嫩初高生在线播放视频 | 99久久国产综合精品麻豆 | 夜夜操av | 色吧综合 | 亚洲精品自在在线观看 | 亚洲天天干 | 免费观看一级特黄欧美大片 | 精品久久精品 | 欧美 视频 | 91精品久久 | 国产大毛片 | 91精品国产综合久久久久久 | 欧美成人在线网站 | 欧美精品乱码99久久影院 | 亚洲精品一区在线 | 国产美女视频一区 |