Equals implementation in a java-class which implements an interface that extends Iterable?
How would one implement equals in a java-class which implements an interface that extends Iterable?
The interface
public interface MyInterface extends Iterable<String> {
...
}
The concrete class
public class MyClass implements MyInterface {
private Set<String> myStrings = new HashSet<String>();
@Override
public Iterator<String> iterator() {
return myStrings.iterator();
}
@Override
public boolean equals(Object otherObject) {
How should I check that both this instance and the other instances contains the same set of strings? The easy way would to only check equals against this implementation and not the interface, but that sounds like cheating.
if (otherObject instanceof MyClass) { ... } // easy, just myStrings.equals(...)
but
if (otherObject instanceof MyInterface) { ... } // compare two iterators?
Or am I missing something? I must implement hashCode aswell, and if two objects are equal should not their hashcodes be identical hence equals must only check against MyClass t开发者_运维百科o fullfil this contract?!
}
}
One way would be to use Guava Iterables.elementsEqual method.
http://docs.guava-libraries.googlecode.com/git-history/release09/javadoc/com/google/common/collect/Iterables.html#elementsEqual(java.lang.Iterable, java.lang.Iterable)
/**
* Returns true if all elements in <code>searchFor</code> exist in
* <code>searchIn</code>, otherwise returns false.
*
* @param searchIn
* the collection in which to search for each element in
* <code>searchFor</code>
* @param searchFor
* the collection of element to search for
*/
public static boolean containsAll(@Nonnull Iterable<?> searchIn, @Nonnull Iterable<?> searchFor) {
for (Object o : searchFor) {
if (!Iterables.contains(searchIn, o)) {
return false;
}
}
return true;
}
/**
* Returns true if all elements in <code>searchFor</code> exist in
* <code>searchIn</code> and no other elements exist in
* <code>searchIn</code>, otherwise returns false.
*
* @param searchIn
* the collection in which to search for each element in
* <code>searchFor</code>
* @param searchFor
* the collection of element to search for
*/
public static boolean containsAllAndOnly(@Nonnull Iterable<?> searchIn,
@Nonnull Iterable<?> searchFor) {
if (Iterables.size(searchIn) != Iterables.size(searchFor)) {
return false;
}
return containsAll(searchIn, searchFor);
}
When comparing Sets, a Collection (its super-interface) will never be equals even if it contains the same objects.
If two classes are equal, they must have the same hashCode(). Its is worth noting that HashSet is not ordered and two sets with the same elements can be in different orders.
So if you have only an Iterator, you have to add all the elements to a Set, before you do the comparison in any case.
As an experiment I generated some combinations you can get with the same Set.
精彩评论