Search code examples
javahamcrest

Duplicate Iterable and Collection Hamcrest matchers


I see that Hamcrest for Java defines some matchers for both Iterables and Collections that perform the same matching.

For example, iterableWithSize() in IsIterableWithSize and hasSize() in IsCollectionWithSize. To my knowledge, the latter isn't necessary since any collection can be passed to the Iterable version.

Is there any technical explanation to design an API such that Iterables and Collections are handled separately?


Solution

  • The Collection interface includes methods that speed up some matchers that would otherwise require iterating over all elements.

    The example you provide is one such method. Compare the two methods that determine the size of the actual value:

    protected Integer featureValueOf(Iterable<E> actual) {
      int size = 0;
      for (Iterator<E> iterator = actual.iterator(); iterator.hasNext(); iterator.next()) {
        size++;
      }
      return size;
    }
    

    versus

    protected Integer featureValueOf(Collection<? extends E> actual) {
      return actual.size();
    }
    

    As long as the implementation of size doesn't itself iterate over all the elements, the latter will be much faster.