I have an arrayList called A, say, which is non-empty.
I create another arrayList, B, and put in some elements of A.
for(someobject obj : A){
if(some_condition_is_met)
B.add(obj);
}
Then I do some stuff with B (never modifying, shuffling, or deleting objects from it. I pick an element of B, say B.get(i).
Now, I want to find B.get(i)'s position in A.
I tried
for(someobject obj : A){
if(obj.equals(B.get(i))
return A.lastIndexOf(obj);
}
return null;
But this kept returning null. That is, "equals" doesn't match the objects.
SO in my frustration I tried:
return A.get(A.lastIndexOf(B.get(i));
which caused an ArrayINdexOutOfBounds exception.
Any ideas what I should do? I've got a feeling I'm missing something obvious. One more point - this is an incredibly simplified explanation of what I'm doing. In the above example creating B might seem pointless, but it is necessary.
ANSWERS TO QUESTIONS:
1)The objects are custom objects. Ah,... I didn't override equals. That might be it.
2) I can be sure any object in B mst B in A because on creating B, first I remove all from it, just in case, then I add only object from A and I do not tamper with the objects once in B.
8 Answers 8
The principle of what you are trying to do should work. I could make the quibble that there is little point in doing the FOR loop to search through A to find an instance of the object from B, and then doing a lastIndexOf on it. lastIndexOf will iterate through A anyway. You are searching for something, and then when you find it you are just leaving it where it lies and searching for it all over again. (Admittedly, your first search is from the beginning of A while lastIndexOf will search from the end. So this is like looking for your car keys starting in the basement and working up to the attic. Then when you find them, you leave them there, and then go to the attic and start the search again working your way down to the basement.)
I suspect that the problem is not in the concept, but in the details. You might show the actual code. If the code is too complex, try simplifying it down to the essentials and see if the error still occurs.
One possibility: Do you really add the object from A to B directly? Or are you creating a new object for B that is a copy of the object from A? If the latter, then unless you override equals() it's not going to work, because the default equals() for a user-defined object just checks if they are the same instance, not "equivalent" objects.
Where are you getting i from in your second code block, and are you checking it against the size of B? i.e.
for(someobject obj : A){
if(obj.equals(B.get(i))
return A.lastIndexOf(obj);
}
return null;
What was the value of i, the size of B when you did return A.get(A.lastIndexOf(B.get(i)); and got the ArrayIndexOutOfBounds?
Do this simple test after you populate A and B, to check that they have the expected values ...
for (Object o : B)
{
System.out.println(A.lastIndexOf(o));
}
If you have problems at this stage, you likely have some problem constructing your objects. Also make sure you're not swallowing exceptions anywhere.
Comments
Override equals() and hashcode() methods in your object
@Override
public boolean equals(Object o) {
boolean result = false;
if (o instanceof Someobject ) {
Someobject other = (Someobject ) o;
result = attribute.equalsIgnoreCase(other.attribute);
}
return result;
}
@Override
public int hashCode() {
return attribute.hashCode();
}
3 Comments
A are added to B, we're talking about references to the same objects, which should always pass the == test. Or am I missing something...attribute coming from?attribute is primary key type of field(mostly id) for that ObjectIt seems that B contains different objects from A. Are you sure, that equals method is correct in your objects? And you haven't modified objects in B (or A)?
Comments
Is it possible that some_condition_is_met is always false ? If so, this would perfectly explain the whole use case -- except for B.get(i) which would always return an IndexOutOfBoundsException no matter what i is.
So, after running the first loop, can you try a B.isEmpty() check ?
Comments
You need to make sure two things are happening here.
- Write your objects
equalsandhashcodefunctions correctly. - Use .
indexOf()instead
If you post some more code I am sure we can help more.
1 Comment
equals and hashCode and using indexOf() instead of lastIndexOf() would change anything here ?Did you implement equals() and hashcode() in the class being added to the list?
Comments
Sounds like the standard deep/shallow copy issue and exactly what are you comparing - addresses or values of the object in the ArrayList. Determine that and follow the advice of others about the equals and hashCode overrides
ArrayListcontain? If it's custom object, it might be because you didn't override theequals()method?Athat should matchB.get(i)?B; the default implementation ofequals()should therefore returntrueif the two references match.equals(). The OP is looking to compare two references to the same object, not two objects.