3

I'm wanting to be able to return the position of an object using the indexOf method, but only want to pass the name of the contact to search for this, is there any way for this to be done?

I currently have this method:

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

5 Answers 5

3

Heres a function that will achieve this without going through the whole list, I think the complexity is less than 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;
        }

    }
Sign up to request clarification or add additional context in comments.

8 Comments

Nope, it's still O(n). This sort of "optimization" is likely to make things slower, because getting items from either end of the list may cause more cache fetches.
The complexity is O(n). You may be doing half as many iterations in your for-loop, but you're still inspecting every element. This is no better than iterating over the whole thing one-by-one.
I see. Thank you for the clarification. I feel like this on average will get you to the answer faster? @AndyTurner
@SamOrozco if you have n items, you can do no better in the worst case than checking all n of them. You can do better if you can pre-process the list: if the list is already sorted, you can do it in O(log n). If you can put the items in a HashMap of name to item, you can do it in O(1).
"I'm not sure off the top" You would. If descCnt == contactList.size(), then contactList.get(descCnt) would throw an IndexOutOfBoundsException. Note that you can declare and modify descCnt in the for loop declaration: for (int cnt = 0, descCnt = max - 1; cnt <= descCnt; cnt++, descCnt--).
|
2

If you are doing a lot of lookups of Contacts by name, you can put the instances into a Map<String, Contacts>. The specific type of Map depends upon your requirements; a HashMap might suffice.

Instead of contactList.add(contacts), you can use:

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

and then look up an item in the map using:

contactMap.get(someName);

This will be faster to do the lookups than scanning through a list each time: each lookup will be O(1) for a HashMap, compared to O(n) for a list. However, it uses more memory.


Incidentally, your Contacts class looks like it represents a single contact, so it should be named as a singular: Contact.

Also, your find method is currently declared as an instance method:

public int findItem(String name) {

meaning you actually need an instance of Contacts to find another instance of Contacts. Instead, declare it static:

public static int findItem(String name) {

then you can invoke it without an instance:

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

Comments

0

Just to add guys, I've been able to do it this way:

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!");
        }
    }
}

However, is this not fairly inefficient if I were to have a larger list? Is there a more efficient way of doing this?

2 Comments

Inefficient? Are you experiencing such performance problems in your application that you need to worry about optimizing what you've written? Remember: premature optimization is the root of all evil. What you have written here is a fine way of searching through your list.
contactList is an ArrayList, so this would be reasonably efficient (except for printing Could not find name on every iteration until you find the item). If you changed it to a LinkedList (for example), it would be less efficient, because list retrieval is O(n) in a linked list (vs O(1) in a RandomAccess list like ArrayList).
0

What you ask is not in the contract of List#indexOf(Object), so no, you should not try to make the list work that way.

Instead, you can write your own method that will accomplish what you want relatively easily. Simply iterate over your list and find the Contact that matches the specified name.

/**
 * 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;
}

2 Comments

@SamOrozco So? The question makes no mention about performance concerns. Even so, this method is as good as it gets for an arbitrary ArrayList. Now, if the array is sorted by name, we can do some fancier searches and reduce the complexity to O(ln(n)), but again, the question makes no mention of complexity requirements nor sortability.
Sorry about my earlier comment I was confused .
0

If you are interested. A better way is to override equals() and hashcode() in your object. And use the indexOf the proper way.

Your equals could determine the equality based on the name, therefore removing all that extra and unnecessary code.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.