删除Map的中某一项报错

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();
// 增强型for循环
for (String keyName : Keys) {
// 键名相等的话,删除掉, 导致程序报错了呀。 会报错
if(keyName == "b"){
// map.remove(keyName); 删除会报错的
map.put("n",11); // 新增也是会报错的
map.put(keyName, 200); // ok的,但是我们最好还是使用迭代器来操作
}
}
}
}

为啥这里要使用包装类型 Integer, 而不是int

因为: HashMap的键和值必须是对象类型,不能是基本数据类型。

Java 提供了自动装箱(int 转 Integer)和拆箱(Integer 转 int)的功能

int 类型自动装箱后就是 Integer

为哈会报错呢?

我们在循环中途的某一项的时候,不光是删除,新增也会报错的

因为:当你使用 for-each 循环遍历 HashMap 的键集合时

for-each 底层是通过 Iterator 实现的

Iterator 会检查集合是否被修改(通过一个 modCount 变量)来判断

如果发现集合被修改(例添加、删除元素),就会抛出 ConcurrentModificationException

为啥在遍历最后一项的时候删除就不会报错呢


package part;
import java.util.HashMap;
import java.util.Set; public class Java01 {
public static void main(String[] args) {
// HashMap的键和值必须是对象类型,不能是基本数据类型。 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();
// 增强型for循环
for (String keyName : Keys) {
// 当遍历最后一项的时候,删除就不会报错
if(keyName == "c"){
map.remove(keyName);
}
}
}
}

解释:为什么删除最后一项不会报错?

这个跟(ConcurrentModificationException)触发机制

(ConcurrentModificationException) 是通过 modCount 变量来检测集合是否被修改的。

在遍历集合时,Iterator 会检查 modCount 是否与预期值一致。如果不一致(即集合被修改),就会抛出异常。

当你删除最后一项时,Iterator 可能已经完成了遍历,因此不会触发 modCount 的检查。

因此也就不会报错哈

修改数据最好使用迭代器来处理

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方法用于办法是否存在下一条数据
while (it.hasNext()) {
// 获取下一条数据
String key = it.next();
// 删除键名是b这一项
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}

使用迭代器能够删除其他项吗?

就是说:我们在循环a这一项的时候,可以删除b这一项的数据吗?

不可以的。

因为:只能够删除当前循环的这一项的。再说一次:只能够删除当前循环的这一项的

将数组转化为字符串 Arrays.toString()


package part; import java.util.Arrays;
public class Java01 {
public static void main(String[] args) {
// 声明并初始化一个 int 数组
int[] is= {1, 2, 3, 4, 5};
// 转化为字符串 [1, 2, 3, 4, 5]
String str = Arrays.toString(is);
System.out.println(str);
// [I@28d93b30 是hashCode的内存地址
System.out.println(is);
}
}

将数组转化为集合以及升序

package part;

import java.util.Arrays;
import java.util.List; public class Java01 {
public static void main(String[] args) {
// 将数组转化为集合
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
int[] arr = {4,1,-3,10 };
// Arrays.sort 默认是升序的哈,会影响原始数组的哈,与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个数组项比较

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个数组是否相等,会一对一进行比较。 第2项的-3和第2项的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数组中,从0开始取,取前2个。 arr2, 0, 2表示从arr2数组中,从0开始取,取前2个
// 特别需要注意一点的是: 是在 JDK 9 中引入的。如果你使用的是 JDK 8 或更早版本,这个方法会报错。
System.out.println(Arrays.equals(arr1, 0, 2, arr2, 0, 2)); // 输出: true
}
}

ArrayList 集合默认时长度10,你设置容器大小必须大于等于0。如果是负数会报错


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 非法参数异常
}
}

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访问报错

package part;

import java.util.LinkedList;

public class Java01 {
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<String>();
//报错 IndexOutOfBoundsException
System.out.println(list.get(0));
// list的长度是0, 现在你获取第1项,这样的操作跟索引越界相似。同样也是会报错的
// java.util.NoSuchElementException
System.out.println(list.getFirst());
}
}

HashMap在循环的时候删除,新增数据会报错


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一旦开始循环,那么如果删除,新增数据,就会发生错误
for (Object key : map.keySet()) {
if(key.equals("b")){
// map.remove(key); 删除数据报错
// map.put("d",4); 新增数据报错
map.put(key,4); // 修改数据不会报错的哈
}
}
// 我们可以使用迭代器还解决这样的问题哈。
System.out.println(map);
}
}

尾声

准备开始学习java了。

今天学习的第五天,每天都会发文章,我要卷起来。

请小伙伴们监督我,奥利给

java集合中的迭代器Iterator和数组内置方法以及常见的报错的更多相关文章

  1. 0513JS数组内置方法、数学函数、时间函数

    |数组中常用的内置方法|-push()与pop()|--push()是往数组的尾部添加,同时返回新数组的长度 var attr = [1,2,3,4,5];var attr2 = [6,7,8,9,0 ...

  2. JAVA集合中的迭代器的遍历

    JAVA中的迭代器,迭代实质上就是遍历,在JAVA中使用iterator()方法进行迭代.需要注意的是,iterator()方法的返回值是Iterator对象.Iterator对象有三个方法,hasN ...

  3. 【Python】Java程序员学习Python(四)— 内置方法和内置变量

    <假如爱有天意> 当天边那颗星出现,你可知我又开始想念,有多少爱恋只能遥遥相望,就像月光洒向海面,年少的我们曾以为,相爱的人就能到永远,当我们相信情到深处在一起,听不见风中的叹息,谁知道爱 ...

  4. js中数组内置方法

    var arr = ['A','B','C','D']; length 计算数组的长度 arr.length//4 indexOf() 搜索一个指定的元素的位置 arr.indexOf('C');// ...

  5. js数组内置方法

    var arr = ['A','B','C','D']; length 计算数组的长度 arr.length//4   indexOf() 搜索一个指定的元素的位置 arr.indexOf('C'); ...

  6. 自己封装函数,实现数组的内置方法indexOf的功能

    在学习或开发过程中,经常会有朋友需要使用到一个数组方法-indexOf,这里我们先来谈谈它的功能:返回指定数据所在的索引,如果没有则返回-1. 那么我们在使用时通常是直接使用它这个数组内置方法 今天这 ...

  7. 用JAVA编写浏览器内核之实现javascript的document对象与内置方法

    原创文章.转载请注明. 阅读本文之前,您须要对浏览器怎样载入javascript有一定了解. 当然,对java与javascript本身也须要了解. 本文首先介绍浏览器载入并执行javascript的 ...

  8. 牛客网Java刷题知识点之Java 集合框架的构成、集合框架中的迭代器Iterator、集合框架中的集合接口Collection(List和Set)、集合框架中的Map集合

    不多说,直接上干货! 集合框架中包含了大量集合接口.这些接口的实现类和操作它们的算法. 集合容器因为内部的数据结构不同,有多种具体容器. 不断的向上抽取,就形成了集合框架. Map是一次添加一对元素. ...

  9. Java集合中迭代器的常用用法

    该例子展示了一个Java集合中迭代器的常用用法public class LinkedListTest { public static void main(String[] args) { List&l ...

  10. Java集合中Set的常见问题及用法

    在这里演示的案例是衔接Java集合中的List(点击查看)那篇博文的,本节我们学习的Set的用法. Set是Collection的一个重要的子接口,Set中的元素是无序排列的,并且元素不可以重复,被称 ...

随机推荐

  1. JAVA并发编程学习笔记之CLH队列锁

    NUMA与SMP SMP(Symmetric Multi-Processor),即对称多处理器结构,指服务器中多个CPU对称工作,每个CPU访问内存地址所需时间相同.其主要特征是共享,包含对CPU,内 ...

  2. 2023-05 多校联合训练 ZJNU站 正式赛

    Scarlett的三元组 有一个长度为 \(n\) 的序列 \(a_1,a_2,\cdots,a_n\),试问有多少个三元组 \((a_i,a_j,a_k)\) 满足: \(1 \le i \lt j ...

  3. Mybatis【11】-- Mybatis Mapper动态代理怎么写?

    目录 1.回顾Mybatis执行sql的流程 2.mapper动态代理怎么写? 3.mapper动态代理怎么做的? 1.回顾Mybatis执行sql的流程 在之前的代码中我们的运行过程再梳理一下,首先 ...

  4. PythonDay2Base

    PythonDay2Base 前文见上一篇文章 数据类型详解 字符串 str 补充 startswith 判断字符串是否以某个小字符串开头 s1 = "shujia数加科技学习study&q ...

  5. MySQL底层概述—10.InnoDB锁机制

    大纲 1.锁概述 2.锁分类 3.锁实战之全局锁 4.锁实战之表级锁(偏读) 5.锁实战之行级锁(偏写)-行级锁升级表级锁 6.锁实战之行级锁(偏写)-间隙锁 7.锁实战之行级锁(偏写)-临键锁 8. ...

  6. 树莓派4B 微雪7寸触摸屏 双屏 触摸屏校正

    树莓派4B+微雪7寸触摸屏+PC显示器,以触摸屏位主显示,PC显示器扩展,这时会有触摸不准的情况. 通过观察可以发现触摸被放大到了整个屏幕,即触摸屏+PC显示器. 1. 通过查看2个屏幕分辨率和位置, ...

  7. CVE-2023-0461 漏洞分析与利用

    PS: 文章首发于补天社区 漏洞分析 tcp_set_ulp里面会分配和设置 icsk->icsk_ulp_data,其类型为 tls_context tcp_setsockopt do_tcp ...

  8. 【Amadeus原创】IPAD忘记密码重置恢复出厂设置

    打开iTunes,确保您的 iPad 没有连接到电脑. 按住顶部按钮,直到出现关机滑块.拖移这个滑块以将 iPad 关机. 在按住主屏幕按钮的同时,将 iPad 连接到电脑.继续按住主屏幕按钮,直到看 ...

  9. 鸿蒙应用开发从入门到入行 - 篇4:层叠布局、自定义组件、ForEach

    第四篇 - 层叠布局.自定义组件.ForEach循环生成组件 导读:在本篇文章里,您将掌握层叠布局.自定义组件的用法,特别是自定义组件将来的开发中必然会用,其中应该特别关注自定义组件的一些规范与装饰器 ...

  10. Debian 12 (bookworm) 安装方法及其国内软件源

    摘要: Debian 12 (bookworm) 已经于2023年6月份正式发布.以下为原来信息: Debian 12 (bookworm) 预计于2023年中期发布,但是目前(2023年4月)已经处 ...