将 IndexOf 与 arrayList 中的 customObject 一起使用

Using IndexOf with a customObject in an arrayList

我希望能够使用 indexOf 方法 return 对象的位置,但只想传递联系人的姓名来搜索它,有什么办法可以做到这一点完成了吗?

我目前有这个方法:

private static ArrayList<Contacts> contactList = new ArrayList<Contacts>();

public class Contacts {
private String name;
private String number;


public Contacts(String name, String number) {
    this.name = name;
    this.number = number;
}

public String getName() {
    return name;
}

public String getNumber() {
    return number;
}

public void setName(String name) {
    this.name = name;
}

public void setNumber(String number) {
    this.number = number;
}



public int findItem(String name) {

    return contactList.indexOf(name);
}

这是一个无需遍历整个列表即可实现此功能的函数,我认为复杂度小于 O(n):

public int findItem(String name)
    {
        int max = contactList.size();

        //you might have to subtract this by one 
        //I'm not sure off the top
        int descCnt = max;


        for(int cnt = 0; cnt <= max/2; cnt++)
        {
            if(contactList.get(cnt).getName().equals(name)) return cnt;
            if(contactList.get(descCnt).getName().equals(name)) return descCnt;
            --descCnt;
        }

    }

你问的不在List#indexOf(Object)的合同中,所以不,你不应该试图让清单那样工作。

相反,您可以编写自己的方法来相对轻松地完成您想要的操作。只需遍历您的列表并找到与指定名称匹配的联系人。

/**
 * Returns the List index of the Contact with the specified name. If no such
 * Contact is found, -1 will be returned.
 */
public int findItem(String name) {
    for (int i = 0; i < contactList.size(); i++) {
        Contact contact = contactList.get(i);
        if (null == contact) continue;
        if (java.lang.Objects.equals(name, contact.getName())) return i;
    }
    return -1;
}

补充一下,我已经可以这样做了:

public void searchItem(String name) {
    for(int i = 0; i < contactList.size(); i++) {
        if(name.equals(contactList.get(i).getName())) {
            System.out.println("Found " + name);
            break;
        }
        else {
            System.out.println("Could not find name!");
        }
    }
}

但是,如果我有一个更大的列表,这不是相当低效吗?有更有效的方法吗?

如果您要按名称对 Contacts 进行大量查找,则可以将实例放入 Map<String, Contacts>Map 的具体类型取决于您的要求;一个 HashMap 可能就足够了。

代替contactList.add(contacts),您可以使用:

contactMap.put(contacts.getName(), contacts);

然后使用以下方法在地图中查找项目:

contactMap.get(someName);

这将比每次扫描列表更快地进行查找:与列表相比,O(n)O(n) 相比,HashMap 的每次查找都是 O(1)。但是,它会占用更多内存。


顺便说一下,您的 Contacts class 看起来像是代表一个联系人,因此应该将其命名为单数:Contact.

此外,您的 find 方法当前声明为实例方法:

public int findItem(String name) {

意味着您实际上需要 Contacts 的实例才能找到 Contacts 的另一个实例。相反,声明它 static:

public static int findItem(String name) {

那么你可以在没有实例的情况下调用它:

Contacts found = Contacts.find("name");

如果你有兴趣。更好的方法是覆盖对象中的 equals() 和 hashcode()。并以正确的方式使用 indexOf。

您的 equals 可以根据名称确定相等性,因此删除所有额外和不必要的代码。