With Java 8, I use these to loop in the sexy way:
//parallel loop public static <A, B> void loop(Collection<A> a, Collection<B> b, IntPredicate intPredicate, BiConsumer<A, B> biConsumer) { Iterator<A> ait = a.iterator(); Iterator<B> bit = b.iterator(); if (ait.hasNext() && bit.hasNext()) { for (int i = 0; intPredicate.test(i); i++) { if (!ait.hasNext()) { ait = a.iterator(); } if (!bit.hasNext()) { bit = b.iterator(); } biConsumer.accept(ait.next(), bit.next()); } } } //nest loop public static <A, B> void loopNest(Collection<A> a, Collection<B> b, BiConsumer<A, B> biConsumer) { for (A ai : a) { for (B bi : b) { biConsumer.accept(ai, bi); } } }
Some example, with these 2 lists:
List<Integer> a = Arrays.asList(1, 2, 3); List<String> b = Arrays.asList("a", "b", "c", "d");
Loop within min size of a and b:
loop(a, b, i -> i < Math.min(a.size(), b.size()), (x, y) -> { System.out.println(x + " -> " + y); });
Output:
1 -> a 2 -> b 3 -> c
Loop within max size of a and b (elements in shorter list will be cycled):
loop(a, b, i -> i < Math.max(a.size(), b.size()), (x, y) -> { System.out.println(x + " -> " + y); });
Output:
1 -> a 2 -> b 3 -> c 1 -> d
Loop n times ((elements will be cycled if n is bigger than sizes of lists)):
loop(a, b, i -> i < 5, (x, y) -> { System.out.println(x + " -> " + y); });
Output:
1 -> a 2 -> b 3 -> c 1 -> d 2 -> a
Loop forever:
loop(a, b, i -> true, (x, y) -> { System.out.println(x + " -> " + y); });
Apply to your situation:
loop(list1, list2, i -> i < Math.min(a.size(), b.size()), (e1, e2) -> { doStuff(e1); doStuff(e2); });
(i < list1.length) && (i < list2.length)) or if you know the lists will be unmodified during iteration you could check right before the loop to see iflist1andlist2have equal lengths, in which case you can get away with not checking the bounds of both during iteration with a clear conscience.list2but notlist1, then I'm screwed.