ArrayList中remove方法的陷阱,arraylistremove
ArrayList中remove方法的陷阱,arraylistremove
由于ArrayList集合底层存储结构是数组,所以ArrayList中的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;
}
通过上面我们可以看到在遍历中比较使用的是equals方法,看到这里,有的人应该已经明白了,我所说的陷阱是什么了。
Object类是所有类的超类,Object类中存在equals方法,但是,其比较的是对象地址。
说道这里有的人又有疑问了,因为大家或许看到过关于String类对象的比较“==”和equals的区别,那里明明说的是“==”比较的是对象地址,而equals方法比较的是对象实际存储的值,Object类是所有类的超类,那么他当然也是String类的超类了。
所以StrIng类调用Object当然equals方法的话,那不也是比较的是对象地址了,但是实际上String类调用equals方法比较的却是对象实际存储的值,是因为,String类的底层重写了Object的equals方法,这样Stringl类掉用的便是重写后的equals的方法,那样比较的自然不是对象地址了。
我们可以看下String类的equals源码部分:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
说道这里,有得朋友应该就明白了,在remove方法中比较所用的equals方法是Object中的equals方法,比较的是对象地址,那样便会造成当我们给remove方法传参数的时候,如果传入一new一个和集合中对象值相同的对象,那么便无法从集合删除,因为new的对象虽然对象值相同,但是地址不同,而Object类的equals方法比价的正是地址。
例如:
public static void main(String[] args) {
ArrayList<Student> array = new ArrayList<>();
Student str = new Student("张三", 10);
Student str1 = new Student("李四",10);
array.add(str);
array.add(str1);
System.out.println(array.size());
array.remove(new Student("张三", 10));
for (Object object : array) {
System.out.println(object.toString());
}
}
输出:
2
Student [name=张三, age=10]
Student [name=李四, age=10]
通过输出我们可以看到集合中的对象并没有被删除。
那么我们该怎么解决这个问题那,我们可以参考上String类的做法在对象类中重写equals方法便好了
例如
@Override
public boolean equals(Object obj) {
if(obj==null) {
return false;
}
if(obj instanceof Student) {
Student s = (Student) obj;
if(this.name.equals(s.name)&&this.age==s.age) {
return true;
}
}
return false;
}
上面便是我在Student类中重写的equals方法,这样remove中比较调用的便是我重写过的equals方法,比较是对象值了。
这样我们再去remove便可以删除了。
重写后
public static void main(String[] args) {
ArrayList<Student> array = new ArrayList<>();
Student str = new Student("张三", 10);
Student str1 = new Student("李四",10);
array.add(str);
array.add(str1);
System.out.println(array.size());
array.remove(new Student("张三", 10));
for (Object object : array) {
System.out.println(object.toString());
}
}
输出:
2
Student [name=李四, age=10]
以上便是我关于ArraylIst中remove方法的解析了,希望可以对大家有些帮助。
相关文章
- 暂无相关文章
用户点评