在java类中等于实现,它实现了一个扩展Iterable的接口?

时间:2011-09-07 12:45:36

标签: java

如何在实现扩展Iterable的接口的java类中实现equals?

界面

public interface MyInterface extends Iterable<String> {
...
}

具体课程

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) {

我应该如何检查此实例和其他实例是否包含相同的字符串集?简单的方法是仅针对此实现检查等于而不是界面,但这听起来像是作弊。

    if (otherObject instanceof MyClass) { ... } // easy, just myStrings.equals(...)

    if (otherObject instanceof MyInterface) { ... } // compare two iterators?

或者我错过了什么?我必须实现hashCode,如果两个对象相同,那么它们的哈希码不应该是相同的,因此equals必须只检查MyClass来完成这个契约吗?!

  }

}

2 个答案:

答案 0 :(得分:2)

一种方法是使用Guava Iterables.elementsEqual方法。

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);
}

答案 1 :(得分:2)

比较集合时,即使集合(其超级接口)包含相同的对象,它也永远不会等于。

如果两个类相等,则它们必须具有相同的hashCode()。值得注意的是HashSet没有排序,两个具有相同元素的集合可以有不同的顺序。

因此,如果您只有Iterator,则必须先将所有元素添加到Set中,然后再进行比较。

作为一项实验,我制作了some combinations you can get with the same Set.