开发者

Vector.indexOf won't work for my class

I'm buildin开发者_运维百科g simple phonebook. Thus a have created a class "Person":

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();
} }

In some other part of the program i'm creating a Vector, populate it with "Person" objects but when i try to search a person BY NAME using vctPerson.indexOf("John") I always get -1 as result (not found). What's wrong with my code? I have implemented custom "equals" that should work with strings, and according to docs, "indexOf" is using "equals" to compare objects...

EDIT: I KNOW, I SHOULD SEARCH AFTER PHONE NUMBER, NOT NAME BUT IT's IRRELEVANT FOR THIS EXAMPLE


What Vector does in indexOf:

if (o.equals(elementData[i]))

where o would be "John". So you would have to override Sting.equals to do the right comparison (just kidding). Or you could use

vector.indexOf(new Person("John", null));

which will call your equals. Strictly speaking that will solve your question.

But in the long run you should not use Vector for that, because every indexOf call will iterate through the list - this is not very efficient.

A better way is a Map like HashMap where you can store key-value pairs. Lookup using the key is much cheaper than Vector.indexOf if here are a couple of entries.

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());


you called vctPerson.indexOf("John") . In this case, Vector call "John".equals( vctPerson.get( indexValue ) . As equals of String is called, String's equals compare "John" and Person object.

But as String's equals() does not return true when target object is not an instance of String, "John".equals( vctPerson.get( indexValue ) always return false. So result is always -1.

So, you can't use vctPerson.indexOf("John"). If you want to use vector, you need to traverse vector manually.


Your equals is broken: You objects may equal to a String (and that's what you're trying to exploit), but no String may ever equal to you object. Breaking symmetry of equals breaks everything.


Well, to be on the safe side you can always use
1) Map<String,Person> to make the relation between a person and his name
2) Make your own class that extends java.util.Vector and overrides its indexOf method
3) place a breakpoint in your equals method and see what's going on when indexOf gets called.
Whatever's going on, though, it's better that you don't rely on the current implementation of indexOf that's specified in the JDK documentation since it may get changed upon the release of a next version of the JDK :)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜