001package com.identityworksllc.iiq.common.iterators; 002 003import java.util.Iterator; 004import java.util.Objects; 005import java.util.concurrent.atomic.AtomicInteger; 006 007/** 008 * An iterator that keeps track of its index, allowing you to get the current 009 * element count. 010 * 011 * @param <In> The input iterator type 012 */ 013public class IndexingIterator<In> implements Iterator<Index<In>> { 014 /** 015 * The index counter 016 */ 017 private final AtomicInteger index; 018 019 /** 020 * The input iterator 021 */ 022 private final Iterator<? extends In> input; 023 024 /** 025 * Wrapper constructor 026 * @param input The input iterator 027 */ 028 public IndexingIterator(Iterator<? extends In> input) { 029 this.input = Objects.requireNonNull(input); 030 this.index = new AtomicInteger(-1); 031 } 032 033 /** 034 * @see Iterator#hasNext() 035 */ 036 @Override 037 public boolean hasNext() { 038 return input.hasNext(); 039 } 040 041 /** 042 * @see Iterator#next() 043 */ 044 @Override 045 public Index<In> next() { 046 return new Index<>(input.next(), index.incrementAndGet()); 047 } 048 049 /** 050 * Removes the current item from the list and decrements the index. The 051 * next item returned will have the same index as the previous one. If 052 * the wrapped iterator does not support removals, this method will throw 053 * an appropriate exception without decrementing the counter. 054 */ 055 @Override 056 public void remove() { 057 input.remove(); 058 index.decrementAndGet(); 059 } 060}