今天做项目的时候碰到一个功能需要使用ArrayList的indexOf方法,ArrayList中存放的是一组自定义的Notice对象,需要知道当前的一个Notice对象(此对象通过另外一个方法查询出)在这个ArrayList中的位置,查了API,用indexOf方法,可是debug的时候却发现返回值是-1,而这个Notice对象确实存在list中并且两个对象内容完全相同。于是写了一个demo来验证这个问题。
测试类1:TestClass。2个String类型的属性name,id
class TestClass {测试代码:
public TestClass(String name, String id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
String name;
String id;
}
package test.test;
import java.util.ArrayList;
import java.util.List;
public class TestIndexof {
public static void main(String[] args) {
List<TestClass> list = new ArrayList<TestClass>();
TestClass c1 = new TestClass("first", "1");
list.add(c1);
TestClass c2 = new TestClass("second", "2");
list.add(c2);
TestClass c3 = new TestClass("third", "3");
list.add(c3);
TestClass c4 = new TestClass("third", "3");
System.out.println("Index:"+list.indexOf(c3));
System.out.println("Index:"+list.indexOf(c4));
}
}
class TestClass {
public TestClass(String name, String id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
String name;
String id;
}
输出结果:
Index:2
Index:-1
C3对象返回索引是2,C4为-1,而这2个对象的内容都是一样的。注意到C3是通过add方法加入list的对象,而c4是new出来的。看下indexOf的源码:
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
由于TestClass类没有重写euqals方法,这里使用了Object的equals方法,由于传入的C3的内存地址和list中的C3内存地址是一样的,所以返回正确的结果,而C4是new出来的,内存中的地址和list中的C3已经不一样了,尽管他们的内容是完全一样的,所以返回-1。
要解决这个问题可以重写传入indexOf的对象的equals方法。由于TestClass对象id是不重复的,所以用比较id的方法来重写equals方法:
class TestClass {
public TestClass(String name, String id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof TestClass) {
if (this.getId().equals(((TestClass) obj).getId())) {
return true;
}
else {
return false;
}
}
return false;
}
String name;
String id;
}
改写TestClass类后,再次运行测试代码,结果如下:
Index:2
Index:2