Find indexOf of an object in custom list using one attribute
Asked Answered
M

3

7

So, I have a custom class, and an arraylist of that class type. Now, I want to retrieve the index of an object in this arraylist using only an ID that is available to me among the other attributes that make up an object of that class.

Saw a few examples online, but I'm kinda confused, they're overriding hashCode() and equals(), and in equals() they're checking all the attributes, I just want to check with the ID value, since for every object ID is unique.

public class MyClass {
    private String ID;
    private String name;
    private String userName;
    private String position;

    // Constructors and getters and setters
}

So, what I want is, for say this piece of code:

List<MyClass> list=new ArrayList<>();
//Values are populated into list
int i=list.indexOf(someObjectsID); //Where someObjectsID is a String and not a MyClass object

int i will have the indexOf of the MyClass object in list that has ID equal to someObjectsID

Miniaturize answered 28/6, 2019 at 17:7 Comment(7)
Can you not just create a method with: list.stream().filter(myClass -> myClass.getID().equals(someObjectsID)) that returns MyClass, then call list.indexOf() of the result?Harbaugh
That would definitely work, but then again, don't I have to override hashCode() and equals() since that seems to be the norm for using indexOf with custom object lists? Plus, won't this two step process cause a lag in longer lists ?Miniaturize
Hardly. You do need to make the list traversal twice. But unless you're doing Google Code Jam questions I don't think you'll notice any time complexity difference.Harbaugh
Possible duplicate of Java List.contains(Object with field value equal to x)Harbaugh
Not a duplicate. I am sending the String object, instead of the MyClass object as the parameter of indexOf() and I'm looking for the position too. The purpose behind my question is to see if indexOf can be used with custom lists to retrieve an object if I have one of the unique values (here, ID) that constitute the object.Miniaturize
There is no way to get an index of an object inside any array or list without traversing, when the search key is inside the object itself. You have to traverse each object and match the search key with the object field and return the index of the object on which it was found. To avoid lags in longer list you have to do some indexing by mapping your string ID with indexes using HashMap or HashTable which in turn will require you to override hashCode and equal method for your MyClassUnboned
Yes, @SyedAhmedJamil thanks for clarifying that. If you have any possible solutions to my problem statement with the HashMap/HashMap approach, please feel free to add an answer. Thanks !Miniaturize
S
1

There is one absolutely guaranteed, efficient solution to this problem. Nothing else will work nearly so simply or efficiently.

That solution is to just write the loop and not try to get fancy.

for(int i = 0; i < list.size(); i++){
  if (list.get(i).getId().equals(id)) {
    return i;
  }
}
return -1;

No need to mess with hashCode or equals. No need to force indexes into streams not designed for them.

Siu answered 28/6, 2019 at 17:38 Comment(2)
Disagree on the "no need to get into streams", using .filter() on the stream for a given field is a great use case.Harbaugh
@Harbaugh Not if you need the index in the original list, which it looks like the OP does.Siu
B
1

If you're open to using a third party library, you can use detectIndex from Eclipse Collections.

int index = ListIterate.detectIndex(list, each -> each.getID().equals(someObjectsID));

If the list is of type MutableList, the detectIndex method is available directly on the list.

MutableList<MyClass> list = Lists.mutable.empty();
int index = list.detectIndex(each -> each.getID().equals(someObjectsID));

Note: I am a committer for Eclipse Collections

Breadroot answered 28/6, 2019 at 18:56 Comment(1)
Thanks for your answer @DonaldRaab I might not use the third-party library, but this definitely seems like a very useful tool because of its sheer simplicity and ease of use.Miniaturize
V
-1

Override hashCode & equals in your custom object, then indexOf will Just Work (tm).

Vickyvico answered 28/6, 2019 at 17:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.