In Python, the enumerate function allows you to iterate over a sequence of (index, value) pairs. For example:
>>> numbers = [\"zero\", \"one\", \"tw
According to the Python docs (here), this is the closest you can get with Java, and it's no more verbose:
String[] numbers = {"zero", "one", "two"}
for (int i = 0; i < numbers.length; i++) // Note that length is a property of an array, not a function (hence the lack of () )
System.out.println(i + " " + numbers[i]);
}
If you need to use the List
class...
List<String> numbers = Arrays.asList("zero", "one", "two");
for (int i = 0; i < numbers.size(); i++) {
System.out.println(i + " " + numbers.get(i));
}
*NOTE: if you need to modify the list as you're traversing it, you'll need to use the Iterator object, as it has the ability to modify the list without raising a ConcurrentModificationException
.
I find this to be the most similar to the python approach.
public static void main(String [] args) {
List<String> strings = Arrays.asList("zero", "one", "two");
for(EnumeratedItem<String> stringItem : ListUtils.enumerate(strings)) {
System.out.println(stringItem.index + " " + stringItem.item);
}
System.out.println();
for(EnumeratedItem<String> stringItem : ListUtils.enumerate(strings, 3)) {
System.out.println(stringItem.index + " " + stringItem.item);
}
}
0 zero
1 one
2 two
3 zero
4 one
5 two
import java.util.Iterator;
public class ListUtils {
public static class EnumeratedItem<T> {
public T item;
public int index;
private EnumeratedItem(T item, int index) {
this.item = item;
this.index = index;
}
}
private static class ListEnumerator<T> implements Iterable<EnumeratedItem<T>> {
private Iterable<T> target;
private int start;
public ListEnumerator(Iterable<T> target, int start) {
this.target = target;
this.start = start;
}
@Override
public Iterator<EnumeratedItem<T>> iterator() {
final Iterator<T> targetIterator = target.iterator();
return new Iterator<EnumeratedItem<T>>() {
int index = start;
@Override
public boolean hasNext() {
return targetIterator.hasNext();
}
@Override
public EnumeratedItem<T> next() {
EnumeratedItem<T> nextIndexedItem = new EnumeratedItem<T>(targetIterator.next(), index);
index++;
return nextIndexedItem;
}
};
}
}
public static <T> Iterable<EnumeratedItem<T>> enumerate(Iterable<T> iterable, int start) {
return new ListEnumerator<T>(iterable, start);
}
public static <T> Iterable<EnumeratedItem<T>> enumerate(Iterable<T> iterable) {
return enumerate(iterable, 0);
}
}
List<String> list = { "foo", "bar", "foobar"};
int i = 0;
for (String str : list){
System.out.println(i++ + str );
}
Pretty much the same syntax using Java8 Streams
ArrayList<String> numbers = new ArrayList<String>();
numbers.add("one");
numbers.add("two");
numbers.add("three");
numbers.stream().forEach(num ->
{
System.out.println(numbers.indexOf(num) + " " + num);
});
Now with Java 8s Stream API together with the small ProtonPack library providing StreamUtils
it can be achieved easily.
The first example uses the same for-each notation as in the question:
Stream<String> numbers = Arrays.stream("zero one two".split(" "));
List<Indexed<String>> indexedNumbers = StreamUtils.zipWithIndex(numbers)
.collect(Collectors.toList());
for (Indexed<String> indexed : indexedNumbers) {
System.out.println(indexed.getIndex() + " " + indexed.getValue());
}
Above although does not provide the lazy evaluation as in Python.
For that you must use the forEach()
Stream API method:
Stream<String> numbers = Arrays.stream("zero one two".split(" "));
StreamUtils.zipWithIndex(numbers)
.forEach(n -> System.out.println(n.getIndex() + " " + n.getValue()));
The lazy evaluation can be verified with the following infinite stream:
Stream<Integer> infStream = Stream.iterate(0, i -> i++);
StreamUtils.zipWithIndex(infStream)
.limit(196)
.forEach(n -> System.out.println(n.getIndex() + " " + n.getValue()));