浅析ArrayList的remove方法
一、实现remove方法对list集合中数据的删除
1、在Test类中创建一个List集合并添加对象
ArrayList<Person> list = new ArrayList<Person>();
Person p1 = new Person();
Person p2 = new Person();
list.add(p1);
list.add(p2);
System.out.println(list.size());//2
String name = list.remove(0);
System.out.println(list.size());//1
2、创建一个Person类重写Object类的equals()方法
public String id;
public Person(String id) {
this.id = id;
}
//重写Object类中的equals()方法
@Override
public boolean equals(Object obj) {
System.out.println(id);
return super.equals(obj);
}
二、关于remove底层代码
1、在底层代码中,ArrayList的remove()方法调用了传入对象的equals()方法
//ArrayList底层代码
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;
}
从这段代码可以看出,"Object o"代表的是remove方法的对象,elementData[index]代表的是list中的对象。如果调用了ArraryList中的remove(Object obj)方法,实质上是将remove的对象与list中的对象进行比较,比较的方法是调用Object类中的equals方法,比较两对象的内存地址是否相同。
2、比较Person类中的内容,需要重写equals方法,对上转型对象下转型
若要删除一个Person对象,我们就创建一个和原来Person对象内容完全一样的对象,但很显然这样是不能删除掉的,因为调用remove方法的时候其实是调用Person中的equals方法,因为Person类并没有重写Object中的equals方法,所以调用的还是Object中的equals方法,本质上是比较两个对象的内存地址,显然是不一样的。那么我们如果想要比较Person类中的内容该如何做呢?这时,我们就要在Person类中重写Object中的equals方法。方法如下:
@Override
public boolean equals(Object obj) {
Person person = (Person) obj;
return this.id.equals(person.id);
}
三、remove(Object obj)方法中的细节补充
数据类型转换错误及解决方法
ArrayList<Object> list = new ArrayList<>();
list.add(new Person());
list.add(new Dog());
System.out.println(list.size());//2
boolean b = list.remove(new Person());
System.out.println(b);//true
System.out.println(list.size());//1
此处出错是由于Object是所有类的直接或者间接父类,所以Person类中的equals方法可以传入任何类型的参数,但是在执行Person person = (Person) obj;语句时,无法将Dog类强制转为Person,所以出现数据类型转换错误。这个问题可以在Person类中的equals方法中加入健壮性判断得到解决,方法如下:
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Person)) {
throw new ClassCastException("类型转换错误");
}
Person person = (Person) obj;
return this.id.equals(person.id);
}