So this question came up in a job interview not too long ago:
Implement a method that takes as a parameter a varargs of Iterables and returns a unified Iterator (without merging the the passed in Iterables into some collection)
Creating a custom Iterator and/or Iterable is pretty basic stuff but admittedly I can’t remember the last time I’ve done it. While I know that implementing Iterator requires at least implementing the hasNext and next method and I kinda forgot what the purpose of Iterable basically just means that you are providing the iterator() method, duh. Anyway, I obviously need some refreshers but in the mean time here’s my future white boarding solution
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; public class IteratorExample { static List<String> l1 = Arrays.asList("l1", "l1b"); static List<String> l2 = Arrays.asList("l2", "l2b"); static List<String> l3 = Arrays.asList("l3", "l3b"); static List<String> l4 = Arrays.asList("l4", "l4b"); // Exercise: create a method that takes an number of iterables and returns a single unified iterator. static Iterator<String> getIterator(Iterable<String> ... iterables){ return new MyIterator(iterables); } public static void main (String [] args) { Iterator<String> custIterator = getIterator(l1, l2, l3, l4); while (custIterator.hasNext()){ System.out.println(custIterator.next()); } } } class MyIterator implements Iterator<String>{ private int curItIndex = -1; private Iterator<String> curIt; private Iterable<String>[] iterables; MyIterator(Iterable<String>[] iterables){ this.iterables = iterables; if (this.iterables != null && this.iterables.length > 0) { this.curItIndex = 0; this.curIt = this.iterables[curItIndex].iterator(); } } @Override public boolean hasNext() { // no iterables provided if (curItIndex == -1) return false; if (curIt.hasNext()) { return true; } else { curItIndex++; } // basically, if the current iterator has run dry try the next one while (curItIndex < iterables.length) { curIt = iterables[curItIndex].iterator(); if(curIt.hasNext()) return true; else curItIndex++; } return false; } @Override public String next() { if (hasNext()) { return curIt.next(); } else { throw new NoSuchElementException(); } } } |