1

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.

6
  • 1
    What is the type of the objects you are storing in the lists? Commented May 16, 2011 at 15:47
  • 2
    What objects does the ArrayList contain? If it's custom object, it might be because you didn't override the equals() method? Commented May 16, 2011 at 15:47
  • 1
    Can you confirm that there really is still an object in A that should match B.get(i)? Commented May 16, 2011 at 15:48
  • 3
    @ryan: It looks like the OP isn't cloning the objects before adding to B; the default implementation of equals() should therefore return true if the two references match. Commented May 16, 2011 at 15:49
  • 2
    There is ABSOLUTELY no reason here to override equals(). The OP is looking to compare two references to the same object, not two objects. Commented May 16, 2011 at 21:39

8 Answers 8

2

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.

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

1 Comment

Homer Simpsonesque "Doh!". As you suspected I made a copy of A (not in the simplified code I wrote above). That's why they weren't "equaling" each other.
2

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

1

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

Would this help in anyway here or it's just a best practice outlined ? As the references in 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...
Where is attribute coming from?
attribute is primary key type of field(mostly id) for that Object
1

It 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

1

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

0

You need to make sure two things are happening here.

  1. Write your objects equals and hashcode functions correctly.
  2. Use .indexOf() instead

If you post some more code I am sure we can help more.

1 Comment

Can you please explain why overriding equals and hashCode and using indexOf() instead of lastIndexOf() would change anything here ?
0

Did you implement equals() and hashcode() in the class being added to the list?

Comments

0

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

Comments

Your Answer

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