001package com.identityworksllc.iiq.common.iterators; 002 003import java.util.Collections; 004import java.util.Iterator; 005import java.util.List; 006import java.util.concurrent.atomic.AtomicInteger; 007 008/** 009 * An indexing class for associating items in a list with their index in the list 010 * 011 * @param <T> The indexed type 012 */ 013public final class Index<T> { 014 /** 015 * Implements an equivalent to Javascript's eachWithIndex. This is a shortcut 016 * to {@link IndexingIterator}. If the input is null, a constant empty iterator 017 * is returned. 018 * 019 * @param iterator The input list to iterate over 020 * @param <In> The type of the values in the list 021 * @return An indexed iterator over the given child iterator 022 */ 023 public static <In> Iterator<Index<In>> with(Iterator<? extends In> iterator) { 024 if (iterator == null) { 025 return Collections.emptyIterator(); 026 } 027 028 return new IndexingIterator<>(iterator); 029 } 030 031 /** 032 * Implements an equivalent to Javascript's eachWithIndex. If the input is 033 * null or empty, a constant empty Iterable is returned. 034 * 035 * The output of this method is not itself a List. 036 * 037 * @param iterable The input list to iterate over 038 * @param <In> The type of the values in the list 039 * @return An indexed iterator over the given list 040 */ 041 public static <In> Iterable<Index<In>> with(List<? extends In> iterable) { 042 if (iterable == null || iterable.isEmpty()) { 043 // Why does this syntax work? It's because the compiler is just looking for 044 // something to substitute in as Iterable.iterator(), and this will 045 // do just fine. 046 return Collections::emptyIterator; 047 } 048 049 return () -> { 050 final Iterator<? extends In> wrappedIterator = iterable.iterator(); 051 return with(wrappedIterator); 052 }; 053 } 054 055 /** 056 * The integer index, starting with 0 057 */ 058 private final int index; 059 060 /** 061 * The value at this index 062 */ 063 private final T value; 064 065 /** 066 * Create a new indexed value 067 * 068 * @param value The value 069 * @param index The index 070 */ 071 public Index(T value, int index) { 072 this.value = value; 073 this.index = index; 074 } 075 076 /** 077 * Gets the integer index value 078 * 079 * @return The integer index value 080 */ 081 public int getIndex() { 082 return index; 083 } 084 085 /** 086 * The value at that position in the list 087 * 088 * @return The value at the list position 089 */ 090 public T getValue() { 091 return value; 092 } 093}