In Python, the enumerate function allows you to iterate over a sequence of (index, value) pairs. For example:
>>> numbers = [\"zero\", \"one\", \"tw
By combining generics with anonymous interfaces, you can essentially create a factory method for handing enumeration. The Enumerator callback hides the messiness of the iterator underneath.
import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;
public class ListUtils2 {
public static interface Enumerator {
void execute(int index, T value);
};
public static final void enumerate(final List list,
final Enumerator enumerator) {
for (ListIterator it = list.listIterator(); it.hasNext();) {
enumerator.execute(it.nextIndex(), it.next());
}
}
public static final void enumerate(final String[] arr,
final Enumerator enumerator) {
enumerate(Arrays.asList(arr), enumerator);
}
public static void main(String[] args) {
String[] names = { "John", "Paul", "George", "Ringo" };
enumerate(names, new Enumerator() {
@Override
public void execute(int index, String value) {
System.out.printf("[%d] %s%n", index, value);
}
});
}
}
[0] John
[1] Paul
[2] George
[3] Ringo
I have taken this a step further and created map, reduce, and filter functions based on this concept.
Both Google's Guava and Apache common-collections dependencies include similar functionality. You can check them out as you wish.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;
public class ListUtils {
// =========================================================================
// Enumerate
// =========================================================================
public static abstract interface Enumerator {
void execute(int index, T value, List list);
};
public static final void enumerate(final List list,
final Enumerator enumerator) {
for (ListIterator it = list.listIterator(); it.hasNext();) {
enumerator.execute(it.nextIndex(), it.next(), list);
}
}
// =========================================================================
// Map
// =========================================================================
public static interface Transformer {
U execute(int index, T value, List list);
};
public static final List transform(final List list,
final Transformer transformer) {
List result = new ArrayList();
for (ListIterator it = list.listIterator(); it.hasNext();) {
result.add(transformer.execute(it.nextIndex(), it.next(), list));
}
return result;
}
// =========================================================================
// Reduce
// =========================================================================
public static interface Reducer {
U execute(int index, T value, U result, List list);
};
public static final U reduce(final List list,
final Reducer enumerator, U result) {
for (ListIterator it = list.listIterator(); it.hasNext();) {
result = enumerator.execute(it.nextIndex(), it.next(), result, list);
}
return result;
}
// =========================================================================
// Filter
// =========================================================================
public static interface Predicate {
boolean execute(int index, T value, List list);
};
public static final List filter(final List list,
final Predicate predicate) {
List result = new ArrayList();
for (ListIterator it = list.listIterator(); it.hasNext();) {
int index = it.nextIndex();
T value = it.next();
if (predicate.execute(index, value, list)) {
result.add(value);
}
}
return result;
}
// =========================================================================
// Predefined Methods
// =========================================================================
// Enumerate
public static String printTuples(List list) {
StringBuffer buff = new StringBuffer();
enumerate(list, new Enumerator() {
@Override
public void execute(int index, T value, List list) {
buff.append('(').append(index).append(", ")
.append(value).append(')');
if (index < list.size() - 1) {
buff.append(", ");
}
}
});
return buff.toString();
}
// Map
public static List intToHex(List list) {
return transform(list, new Transformer() {
@Override
public String execute(int index, Integer value, List list) {
return String.format("0x%02X", value);
}
});
}
// Reduce
public static Integer sum(List list) {
return reduce(list, new Reducer() {
@Override
public Integer execute(int index, Integer value, Integer result,
List list) {
return result + value;
}
}, 0);
}
// Filter
public static List evenNumbers(List list) {
return filter(list, new Predicate() {
@Override
public boolean execute(int index, Integer value, List list) {
return value % 2 == 0;
}
});
}
// =========================================================================
// Driver
// =========================================================================
public static void main(String[] args) {
List numbers = Arrays.asList(8, 6, 7, 5, 3, 0, 9);
// Enumerate
System.out.printf("%-10s: %s%n", "Enumerate", printTuples(numbers));
// Map
System.out.printf("%-10s: %s%n", "Map", intToHex(numbers));
// Reduce
System.out.printf("%-10s: %d%n", "Reduce", sum(numbers));
// Filter
System.out.printf("%-10s: %s%n", "Filter", evenNumbers(numbers));
}
}