简体   繁体   English

Vector.indexOf不适用于我的班级

[英]Vector.indexOf won't work for my class

I'm building simple phonebook. 我正在构建简单的电话簿。 Thus a have created a class "Person": 因此创建了一个类“ 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). 在程序的其他部分中,我正在创建一个Vector,在其中填充“ Person”对象,但是当我尝试使用vctPerson.indexOf("John")名称搜索某人时,我总是得到-1作为结果(未找到) )。 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... 我已经实现了应该与字符串一起使用的自定义“等于”,并且根据文档,“ indexOf”正在使用“等于”来比较对象...

EDIT: I KNOW, I SHOULD SEARCH AFTER PHONE NUMBER, NOT NAME BUT IT's IRRELEVANT FOR THIS EXAMPLE 编辑:我知道,我应该在电话号码之后进行搜索,而不是名称,但是对于本示例来说这无关紧要

you called vctPerson.indexOf("John") . 您调用了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. 在这种情况下, Vector"John".equals( vctPerson.get( indexValue )随着等于String被调用时,字符串的比较等于“约翰”和Person的对象。

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. 但是由于当目标对象不是String的实例时String的equals()不会返回true,因此"John".equals( vctPerson.get( indexValue )始终返回false,因此结果始终为-1。

So, you can't use vctPerson.indexOf("John") . 因此,您不能使用vctPerson.indexOf("John") If you want to use vector, you need to traverse vector manually. 如果要使用向量,则需要手动遍历向量。

What Vector does in indexOf : VectorindexOf

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

where o would be "John" . o将是"John" So you would have to override Sting.equals to do the right comparison (just kidding). 因此,您必须重写Sting.equals才能进行正确的比较(只是在开玩笑)。 Or you could use 或者你可以使用

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

which will call your equals . 这将称为您的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. 但是从长远来看,您不应为此使用Vector ,因为每个indexOf调用都会在列表中进行迭代-这不是很有效。

A better way is a Map like HashMap where you can store key-value pairs. 更好的方法是像HashMap这样的Map ,您可以在其中存储键值对。 Lookup using the key is much cheaper than Vector.indexOf if here are a couple of entries. 如果有几个条目,使用键进行查找比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());

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. 您的等式已损坏:您的对象可能等于String (这就是您要利用的对象),但是没有String可能等于您的对象。 Breaking symmetry of equals breaks everything. 打破equals对称性会破坏一切。

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 1) Map<String,Person>建立一个人和他的名字之间的关系
2) Make your own class that extends java.util.Vector and overrides its indexOf method 2)制作自己的类,该类扩展java.util.Vector并覆盖其indexOf方法
3) place a breakpoint in your equals method and see what's going on when indexOf gets called. 3)在equals方法中放置一个断点,看看indexOf被调用时发生了什么。
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 :) 不过,无论发生什么情况,最好不要依赖JDK文档中指定的indexOf的当前实现,因为它可能会在下一版JDK发行时被更改:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM