老师,我这里使用老师的方法使用增强型for循环,但是出现了程序异常ConcurrentModificationException,请问这个是哪里导致的呢?
老师,我这里使用老师的方法使用增强型for循环,但是出现了程序异常ConcurrentModificationException,请问这个是哪里导致的呢?
package com.imooc.set;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class CatTest {
public static void main(String[] args){
//定义宠物猫对象
Cat huahua = new Cat("花花",12,"英国短毛猫");
Cat fanfan = new Cat("凡凡",3,"中华田园猫");
//Set类中使用泛型
Set <Cat> set = new HashSet<Cat>();//泛型实在javaSE5.0以后引入的概念,5.0之前没有泛型的概念,我们通过对类型Object的引用来实现参数的任意化,任意化带来的缺点是要做显示的强制类型转换
set.add(huahua);
set.add(fanfan);
//显示宠物猫信息,迭代器接口中使用泛型
Iterator <Cat> it = set.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
//我们如果不在宠物猫类中写入toString方法,那么迭代器返回的值就是内存地址,如果写入了toString,那么就会自动调用toString方法
//再添加一个与花花属性一样的猫
Cat huahua01 = new Cat("花花",12,"英国短毛猫");//重写hashCode方法和equals方法后,则重复值可以消失
set.add(huahua01);
System.out.println("*****************************");
System.out.println("添加重复数据后的宠物猫信息:");
it=set.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
System.out.println("*****************************");
//重新插入一个新的宠物猫
Cat huahua02 = new Cat("花花二代",2,"英国短毛猫");
set.add(huahua02);
System.out.println("添加花花二代后的宠物猫信息" );
it=set.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
System.out.println("*****************************");
//在集合中查找花花的信息并且输出:这里其实有多种查找方式,对象名?还是通过哪一个属性去查找这一条记录?
if(set.contains(huahua)){//contains方法可以用于判断集合中是否存在花花这个对象
System.out.println("花花找到了!");
System.out.println(huahua);
}else {
System.out.println("花花没找到!");
}
//如果我们不知道huahua这个对象,只知道“花花”这个名字,该如何查找
//还是需要遍历我们的集合,定义一个布尔变量来进行是否找到的判断
System.out.println("*****************************");
System.out.println("通过名字查找花花的信息");
boolean flag = false;
Cat c = null;
it = set.iterator();
while (it.hasNext()){//我们的思路就是遍历集合,从集合中取出Cat元素,把它的名字挨个与花花进行比较
c = it.next();//由于next方法得到的是object类型的对象,所以这里我们需要进行强制类型转换转换成我们所需要的Cat类型,这里有一个问题,就是我们必须知道next()方法取出的值一定是Cat类型的才能进行强转,否则有可能会报错。这里我们使用了泛型,所以无需使用强制类型转换
//假设我们把前后都加上String类型,那么就会产生类型转换异常,解决方式就是引入泛型,加入泛型之后就不需要进行强制转换了,泛型就限定了在集合中添加的数据必须是我们所需要的类型。泛型的语法格式,再类或接口后面写一个尖括号,在尖括号中写入需要往集合中添加的元素到底是什么类型进行限制
if (c.getName().equals("花花")){
flag = true;//这就说明找到了
break;
}
}
if (flag){
System.out.println("花花找到了");
System.out.println(c);
}else {
System.out.println("花花没找到");
}
//如何在hashset中删除元素,删除花花二代的信息并重新输出,引入泛型以后,我们除了迭代器以外,还可以使用增强型for循环来遍历集合
for (Cat cat:set){
if ("花花二代".equals(cat.getName())){
set.remove(cat);
}
}
System.out.println("*****************************");
System.out.println("删除花花二代后的数据");
for (Cat cat:set){
System.out.println(cat);
}
}
}
[姓名:花花, 年龄:12, 品种:英国短毛猫]
[姓名:凡凡, 年龄:3, 品种:中华田园猫]
*****************************
添加重复数据后的宠物猫信息:
[姓名:花花, 年龄:12, 品种:英国短毛猫]
[姓名:凡凡, 年龄:3, 品种:中华田园猫]
*****************************
添加花花二代后的宠物猫信息
[姓名:花花, 年龄:12, 品种:英国短毛猫]
[姓名:花花二代, 年龄:2, 品种:英国短毛猫]
[姓名:凡凡, 年龄:3, 品种:中华田园猫]
*****************************
花花找到了!
[姓名:花花, 年龄:12, 品种:英国短毛猫]
*****************************
通过名字查找花花的信息
花花找到了
[姓名:花花, 年龄:12, 品种:英国短毛猫]
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1442)
at java.util.HashMap$KeyIterator.next(HashMap.java:1466)
at com.imooc.set.CatTest.main(CatTest.java:70)
Cat类的编写如下:
package com.imooc.set;
import java.util.Objects;
public class Cat {
private String name;//名字
private int month;//年龄
private String species;//品种
public Cat(String name, int month, String species) {
super();
this.name = name;
this.month = month;
this.species = species;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public String getSpecies() {
return species;
}
public void setSpecies(String species) {
this.species = species;
}
@Override
public String toString() {
return "[姓名:" + name + ", 年龄:" + month + ", 品种:" + species + ']';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;//对象相等就不需要比较内容了
if (o == null || getClass() != o.getClass()) return false;//判断obj是否是Cat类的对象,如果不是或者对象为null则返回false
Cat cat = (Cat) o;//是的话,强制转换对象类型
//接下来逐一比较对象属性
if (month != cat.month) return false;
if (!name.equals(cat.name)) return false;
return species.equals(cat.species);
}
@Override
public int hashCode() {
int result = name.hashCode();
result = 31 * result + month;
result = 31 * result + species.hashCode();
return result;
}
}
11
收起
正在回答
1回答
同学你好,ConcurrentModificationException异常通常出现在使用增强for循环遍历集合的同时,对集合中的元素进行了删除导致的。这也是实际开发时非常容易出现的小错误,同学需要牢记,当需要遍历的同时对集合中的元素进行增加或者删除操作时,千万不要使用增强for循环。
实际上,使用迭代器Iterator不容易出现这个问题,所以可以选用Iterator,需要注意的是,移除元素时需要使用迭代器的移除方法,否则也会抛出异常。另外,使用一般for循环时,由于增和删的操作可能会导致元素下标的移位,所以也不是很适合。
一般遇到这样的问题,我们会选择另外一种处理方案:声明一个同类型的空集合,将满足条件的元素添加到新集合中,然后将新集合覆盖到原集合的变量中。这样相当于变相的完成了筛选删除的操作,并且不会触发任何异常或者错误。
祝学习愉快~
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星