4

I tried to detect if an ArrayList contains the same coppies of an object with no success. Here is my code;

public class Foo{
    int id;
    int name;

    @Override
    public boolean equals(Object o){
        Foo f = (Foo)o;
        return f.id==this.id;
    }

}

//in another class
ArrayList<Foo> foos;
...
boolean ifFoosListContainsMultipleFoo(Foo f){
    return foos.indexOf(f)!=foos.lastIndexOf(f);
}
//but this method always returns `false` even the `foos` list
//contains multiple object with the same `id`;

So, what am I doing wrong and is there a more optimal way of doing this?

Thanks in advance.

EDIT: I saw that I need to override hash method of the Foo class, then why equals function is not enough;

EDIT 2: Sorry for wasting your time but it was my mistake. There is no problem with my code, I used ifFoosListContainsMultipleFoo as !ifFoosListContainsMultipleFoo so this was result of false response.

Apologize me.

11
  • why not using foos.contains(object) ??? Commented Sep 2, 2015 at 6:55
  • 5
    I'm not sure but don't you have to override hashCode method as well? Commented Sep 2, 2015 at 6:55
  • no I didn't override hashCode Commented Sep 2, 2015 at 6:56
  • 2
    @wawek He is using an ArrayList and the implementation of the indexOf method does never use hashCode, only equals. Commented Sep 2, 2015 at 6:59
  • 1
    @ismail whether you really need to override hashcode or not depends on what kind of collection you are working with. But it's best practice to always implement equals if you implement hashCode, and the other way around too. Commented Sep 2, 2015 at 7:07

2 Answers 2

4

Your code should work as it is, except in the case where f is not present in the list at all..

So you can do something like,

boolean ifFoosListContainsMultipleFoo(Foo f){
    return (foos.indexOf(f) != -1) && (foos.indexOf(f)!=foos.lastIndexOf(f));
}
Sign up to request clarification or add additional context in comments.

5 Comments

Maybe store the first indexOf in a variable to spare one iteration through the list.
Both methods will return -1 if the element is not present, so I think this is unnecessary.
In this state if the element is present the first index is computed twice.
ohh @WilQu I didn't look it carefully but you are right in this query there is no need to check if list contains the element.
@WilQu, yes... you are right... I am wondering why it's not working for the OP in that case...
2

You can use a HashSet<Foo> to do this. You should override hashCode as well because HashSet uses hashes internally.

Set<Foo> set = new HashSet<Foo>(foos);
// check for duplicates
set.size() == foos.size();

You can also use the set manually which should let you retain the duplicates and can let you end the check sooner (instead of adding everything):

Set<Foo> set = new HashSet<Foo>();
// check for duplicates
for (Foo foo : foos){
    if (!set.contains(foo)){
        set.add(foo);
    } else {
        // do something with foo, which is a duplicate.
        // possibly end check for duplicates or store in a list
    }
}

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.