FilteredIterable implements Iterable<X> { @Override public Iterator<X> iterator() { return new FilteredIterator(this.wrappedIterable.iterator(), this.getFilteredIndices()); } FilteredIterable(final Iterable<X> wrappedIterable, final List<Integer> filteredIndices); @Override Iterator<X> iterator(); List<Integer> getFilteredIndices();  }
@Test public void testCorrectElementsIterated() { for (int numElements = 1; numElements <= ORIGINAL_LIST.size(); numElements++) { for (int shuffleSeed = 0; shuffleSeed < NUM_RESHUFFLES; shuffleSeed++) { List<String> listCopy = new LinkedList<>(ORIGINAL_LIST); Collections.shuffle(listCopy); List<Integer> filteredIndices = new LinkedList<>(); for (int i = 0; i < numElements; i++) { filteredIndices.add(ORIGINAL_LIST.indexOf(listCopy.get(i))); } FilteredIterable<String> filteredIterable = new FilteredIterable<>(ORIGINAL_LIST, filteredIndices); List<Integer> sortedCopyOfFilteredIndices = new LinkedList<>(filteredIndices); Collections.sort(sortedCopyOfFilteredIndices); StringBuilder expected = new StringBuilder(); StringBuilder actual = new StringBuilder(); Iterator<String> filteredIterator = filteredIterable.iterator(); for (Integer correctNextIndex : sortedCopyOfFilteredIndices) { actual.append(filteredIterator.next() + " "); expected.append(ORIGINAL_LIST.get(correctNextIndex) + " "); } assertEquals("The elements returned by the FilteredIterable are not correct.", expected.toString(), actual.toString()); } } }