java集合中的迭代器Iterator和數(shù)組內(nèi)置方法及常見的報(bào)錯解決方案
刪除Map的中某一項(xiàng)報(bào)錯
package part; import java.util.HashMap; import java.util.Set; public class Java01 { public static void main(String[] args) { // 為啥這里要使用包裝類型 Integer, 而不是int HashMap<String, Integer> map = new HashMap(); map.put("a", 1); map.put("b", 2); map.put("c", 3); // 獲取所有鍵名的集合,返回類型是 Set 類型 Set<String> Keys = map.keySet(); // 增強(qiáng)型for循環(huán) for (String keyName : Keys) { // 鍵名相等的話,刪除掉, 導(dǎo)致程序報(bào)錯了呀。 會報(bào)錯 if(keyName == "b"){ // map.remove(keyName); 刪除會報(bào)錯的 map.put("n",11); // 新增也是會報(bào)錯的 map.put(keyName, 200); // ok的,但是我們最好還是使用迭代器來操作 } } } }
為啥這里要使用包裝類型 Integer, 而不是int
因?yàn)? HashMap的鍵和值必須是對象類型,不能是基本數(shù)據(jù)類型。
Java 提供了自動裝箱(int 轉(zhuǎn) Integer)和拆箱(Integer 轉(zhuǎn) int)的功能
int 類型自動裝箱后就是 Integer
為哈會報(bào)錯呢?
我們在循環(huán)中途的某一項(xiàng)的時候,不光是刪除,新增也會報(bào)錯的
因?yàn)?當(dāng)你使用 for-each 循環(huán)遍歷 HashMap 的鍵集合時
for-each 底層是通過 Iterator 實(shí)現(xiàn)的
Iterator 會檢查集合是否被修改(通過一個 modCount 變量)來判斷
如果發(fā)現(xiàn)集合被修改(例添加、刪除元素),就會拋出 ConcurrentModificationException
為啥在遍歷最后一項(xiàng)的時候刪除就不會報(bào)錯呢
package part; import java.util.HashMap; import java.util.Set; public class Java01 { public static void main(String[] args) { // HashMap的鍵和值必須是對象類型,不能是基本數(shù)據(jù)類型。 int 類型自動裝箱后就是 Integer HashMap<String, Integer> map = new HashMap(); map.put("a", 1); map.put("b", 2); map.put("c", 3); // 獲取所有鍵名的集合,返回類型是 Set 類型 Set<String> Keys = map.keySet(); // 增強(qiáng)型for循環(huán) for (String keyName : Keys) { // 當(dāng)遍歷最后一項(xiàng)的時候,刪除就不會報(bào)錯 if(keyName == "c"){ map.remove(keyName); } } } }
解釋:為什么刪除最后一項(xiàng)不會報(bào)錯?
這個跟(ConcurrentModificationException)觸發(fā)機(jī)制
(ConcurrentModificationException) 是通過 modCount 變量來檢測集合是否被修改的。
在遍歷集合時,Iterator 會檢查 modCount 是否與預(yù)期值一致。如果不一致(即集合被修改),就會拋出異常。
當(dāng)你刪除最后一項(xiàng)時,Iterator 可能已經(jīng)完成了遍歷,因此不會觸發(fā) modCount 的檢查。
因此也就不會報(bào)錯哈
修改數(shù)據(jù)最好使用迭代器來處理
package part; import java.util.HashMap; import java.util.Iterator; import java.util.Set; public class Java01 { public static void main(String[] args) { // 為啥這里要使用包裝類型 Integer, 而不是int HashMap<String, Integer> map = new HashMap(); map.put("a", 1); map.put("b", 2); map.put("c", 3); Set<String> keys = map.keySet(); // 迭代器 Iterator<String> it =keys.iterator(); // hasNext方法用于辦法是否存在下一條數(shù)據(jù) while (it.hasNext()) { // 獲取下一條數(shù)據(jù) String key = it.next(); // 刪除鍵名是b這一項(xiàng) if("b".equals(key)){ it.remove(); } // 1 null 3 System.out.println(map.get(key)); } // {a=1, c=3} System.out.println(map); } }
使用 removeIf() 方法(Java 8+)迭代
HashMap<String, Integer> map = new HashMap<>(); map.put("a", 1); map.put("b", 2); map.put("c", 3); Set<String> keys = map.keySet(); keys.removeIf(keyName -> keyName.equals("c")); // 使用 removeIf System.out.println(map); // 輸出: {a=1, b=2}
使用迭代器能夠刪除其他項(xiàng)嗎?
就是說:我們在循環(huán)a這一項(xiàng)的時候,可以刪除b這一項(xiàng)的數(shù)據(jù)嗎?
不可以的。
因?yàn)?只能夠刪除當(dāng)前循環(huán)的這一項(xiàng)的。再說一次:只能夠刪除當(dāng)前循環(huán)的這一項(xiàng)的
將數(shù)組轉(zhuǎn)化為字符串 Arrays.toString()
package part; import java.util.Arrays; public class Java01 { public static void main(String[] args) { // 聲明并初始化一個 int 數(shù)組 int[] is= {1, 2, 3, 4, 5}; // 轉(zhuǎn)化為字符串 [1, 2, 3, 4, 5] String str = Arrays.toString(is); System.out.println(str); // [I@28d93b30 是hashCode的內(nèi)存地址 System.out.println(is); } }
將數(shù)組轉(zhuǎn)化為集合以及升序
package part; import java.util.Arrays; import java.util.List; public class Java01 { public static void main(String[] args) { // 將數(shù)組轉(zhuǎn)化為集合 List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); int[] arr = {4,1,-3,10 }; // Arrays.sort 默認(rèn)是升序的哈,會影響原始數(shù)組的哈,與js不同的 Arrays.sort(arr); // [-3, 1, 4, 10] System.out.println(Arrays.toString(arr)); } }
二分查找法,查找的是排序后的位置
package part; import java.util.Arrays; import java.util.List; public class Java01 { public static void main(String[] args) { int[] arr = {4,1,-3,10 }; Arrays.sort(arr); // [-3, 1, 4, 10] System.out.println(Arrays.toString(arr)); // 查詢4的位置 int index = Arrays.binarySearch(arr, 4); // 2 System.out.println(index); } }
2個數(shù)組項(xiàng)比較
package part; import java.util.Arrays; import java.util.List; public class Java01 { public static void main(String[] args) { int[] arr1 = {4,1,-3,10 }; int[] arr2 = {4,1,10, -3}; // 會比較2個數(shù)組是否相等,會一對一進(jìn)行比較。 第2項(xiàng)的-3和第2項(xiàng)的10不相等,返回flase System.out.println(Arrays.equals(arr1,arr2)); // false } }
package part; import java.util.Arrays; import java.util.List; public class Java01 { public static void main(String[] args) { int[] arr1 = {4, 1, -3, 10}; int[] arr2 = {4, 1, 10, -3}; //arr1, 0, 2表示從arr1數(shù)組中,從0開始取,取前2個。 arr2, 0, 2表示從arr2數(shù)組中,從0開始取,取前2個 // 特別需要注意一點(diǎn)的是: 是在 JDK 9 中引入的。如果你使用的是 JDK 8 或更早版本,這個方法會報(bào)錯。 System.out.println(Arrays.equals(arr1, 0, 2, arr2, 0, 2)); // 輸出: true } }
ArrayList 集合默認(rèn)時長度10,你設(shè)置容器大小必須大于等于0。如果是負(fù)數(shù)會報(bào)錯
package part; import java.util.ArrayList; public class Java01 { public static void main(String[] args) { ArrayList<String > list2 = new ArrayList<String>(0); System.out.println(list2); // [] ArrayList<String> list1 = new ArrayList<String>(-1); System.out.println(list1); // ava.lang.IllegalArgumentException 非法參數(shù)異常 } }
ArrayList的訪問范圍是[0,長度-1]
package part; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class Java01 { public static void main(String[] args) { ArrayList list = new ArrayList(); list.add("A"); list.add("B"); list.add("C"); // 訪問的范圍是[0,長度-1] System.out.println(list.get(2)); // IndexOutOfBoundsException 索引超出異常 System.out.println(list.get(3)); } }
LinkedList的長度是0,使用get(0)和getFirst訪問報(bào)錯
package part; import java.util.LinkedList; public class Java01 { public static void main(String[] args) { LinkedList<String> list = new LinkedList<String>(); //報(bào)錯 IndexOutOfBoundsException System.out.println(list.get(0)); // list的長度是0, 現(xiàn)在你獲取第1項(xiàng),這樣的操作跟索引越界相似。同樣也是會報(bào)錯的 // java.util.NoSuchElementException System.out.println(list.getFirst()); } }
JAVA 復(fù)制 全屏
HashMap在循環(huán)的時候刪除,新增數(shù)據(jù)會報(bào)錯
package part; import java.util.HashMap; import java.util.LinkedList; public class Java01 { public static void main(String[] args) { HashMap map = new HashMap(); map.put("a",1); map.put("b",2); map.put("c",3); // HashMap一旦開始循環(huán),那么如果刪除,新增數(shù)據(jù),就會發(fā)生錯誤 for (Object key : map.keySet()) { if(key.equals("b")){ // map.remove(key); 刪除數(shù)據(jù)報(bào)錯 // map.put("d",4); 新增數(shù)據(jù)報(bào)錯 map.put(key,4); // 修改數(shù)據(jù)不會報(bào)錯的哈 } } // 我們可以使用迭代器還解決這樣的問題哈。 System.out.println(map); } }
到此這篇關(guān)于java集合中的迭代器Iterator和數(shù)組內(nèi)置方法以及常見的報(bào)錯的文章就介紹到這了,更多相關(guān)java迭代器Iterator和數(shù)組內(nèi)置方法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java集合中的Iterator迭代器接口詳解
- 淺析Java迭代器Iterator和Iterable的區(qū)別
- Java中不得不知的Collection接口與Iterator迭代器
- Java中Iterator(迭代器)的用法詳解
- Java使用迭代器Iterator遍歷集合
- Java中Iterator迭代器的使用詳解
- Java集合框架迭代器Iterator實(shí)現(xiàn)原理解析
- Java如何使用Iterator迭代器刪除集合重復(fù)選項(xiàng)
- 如何實(shí)現(xiàn)java Iterator迭代器功能
- Java Iterator接口遍歷單列集合迭代器原理詳解
- Java使用Iterator迭代器遍歷集合數(shù)據(jù)的方法小結(jié)
相關(guān)文章
java使用servlet實(shí)現(xiàn)驗(yàn)證碼
這篇文章主要介紹了java使用servlet實(shí)現(xiàn)驗(yàn)證碼,簡單實(shí)用,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-01-01java實(shí)現(xiàn)點(diǎn)擊按鈕事件彈出子窗口
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)點(diǎn)擊按鈕事件彈出子窗口,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-07-07設(shè)計(jì)模式之構(gòu)建(Builder)模式 建造房子實(shí)例分析
構(gòu)建模式主要用來針對復(fù)雜產(chǎn)品生產(chǎn),分離部件構(gòu)建細(xì)節(jié),以達(dá)到良好的伸縮性,考慮到設(shè)計(jì)模式來源于建筑學(xué),因此舉一個建造房子的例子,需要的朋友可以參考下2012-12-12