我正在构建简单的电话簿。因此,创建了一个“人”类:
public class Person implements Comparable<Person> {
String Name;
String number;
public Person(String name,String Num) {
Name=name;
number=Num;
}
public String getNumber() {
return number;
}
public String getName() {
return Name;
}
@Override
public int compareTo(Person another) {
return Name.compareTo(another.getName());
}
@Override
public String toString() {
return Name;
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof Person) && !(obj instanceof String))
{
return false;
}
else
{
if(obj instanceof Person)
return Name.toLowerCase().equals(((Person)obj).getName().toLowerCase());
else
return Name.toLowerCase().equals(((String)obj).toLowerCase());
}
}
@Override
public int hashCode() {
return Name.hashCode();
} }
在程序的其他部分我正在创建一个Vector,用“Person”对象填充它,但是当我尝试使用vctPerson.indexOf("John")
搜索一个人时,我总是得到-1作为结果(找不到) )。我的代码出了什么问题?我已经实现了应该使用字符串的自定义“equals”,根据文档,“indexOf”使用“equals”来比较对象......
答案 0 :(得分:2)
vctPerson.indexOf("John")
。在这种情况下,Vector
致电"John".equals( vctPerson.get( indexValue )
。当调用String
的等于时,String's等于比较“John”和Person
对象。
但是当目标对象不是String的实例时,String的equals()
不返回true,"John".equals( vctPerson.get( indexValue )
总是返回false。所以结果总是-1。
因此,您无法使用vctPerson.indexOf("John")
。如果要使用矢量,则需要手动遍历矢量。
答案 1 :(得分:2)
Vector
在indexOf
中的作用:
if (o.equals(elementData[i]))
其中o
为"John"
。因此,您必须覆盖Sting.equals
才能进行正确的比较(只是开玩笑)。或者你可以使用
vector.indexOf(new Person("John", null));
会调用您的equals
。严格来说,这将解决您的问题。
但是从长远来看,你不应该使用Vector
,因为每个indexOf
调用都会遍历列表 - 这不是很有效。
更好的方法是Map
,例如HashMap
,您可以在其中存储键值对。如果有几个条目,使用密钥查找要比Vector.indexOf
便宜得多。
Map<String, Person> map = new HashMap<String, Person>();
Person p = new Person("John", "1234");
map.put(p.getName().toLowerCase(), p);
// loopup
Person john = map.get("John".toLowerCase());
答案 2 :(得分:1)
你的等于被破坏:你的对象可能等于String
(这就是你想要利用的东西),但没有String
可能等于你的对象。打破equals
的对称性会破坏一切。
答案 3 :(得分:0)
嗯,为了安全起见,你可以随时使用
1)Map<String,Person>
来建立一个人和他的名字之间的关系
2)创建自己的类,扩展java.util.Vector并覆盖其indexOf方法
3)在你的equals方法中放置一个断点,看看当调用indexOf时会发生什么。
无论发生了什么,最好不要依赖JDK文档中指定的indexOf的当前实现,因为它可能会在下一版本的JDK发布时被更改:)