这道题让咱们实现一个环形数组类CircularArray,因为环形数组须要调用rotate(int shiftRight)函数,在这里,咱们并不会真的去旋转数组,由于这样十分不高效。咱们采用另外一种实现方法,用一个变量head来记录环形数组的起始 位置,那么调用rotate实际上就是改变head的位置而已。请参见以下代码:java
public static class CircularArray<T> implements Iterable<T> { private T[] items; private int head = 0; public CircularArray(int size) { items = (T[]) new Object[size]; } private int convert(int idx) { if (idx < 0) { idx += items.length; } return (head + idx) % items.length; } public void rotate(int shiftRight) { head = convert(shiftRight); } public T get(int i) { if (i < 0 || i >= items.length) { throw new java.lang.IndexOutOfBoundsException("..."); } return items[convert(i)]; } public void set(int i, T item) { items[convert(i)] = item; } public Iterator<T> iterator() { return new CircularArrayIterator<T> (this); } private class CircularArrayIterator<TI> implements Iterator<TI> { private int _current = -1; private TI[] _items; public CircularArrayIterator(CircularArray<TI> array) { _items = array.items; } @Override public boolean hasNext() { return _current < items.length - 1; } @Override public TI next() { ++_current; TI item = (TI) _items[convert(_current)]; return item; } @Override public void remove() { throw new UnsupportedOperationException("..."); } } }
上述代码中主要有两部分:数组
1. 实现CircularArray类ide
实现的过程当中容易犯一些错误,好比:函数
- 咱们不能新建一个泛类的数组,咱们必须cast数组或者定义类型为List<T>.this
- 取余操做符%对于负数运算后会获得负数,这和数学家们定义的取余运算不一样,因此咱们须要给负数序列加上items.length,时期变为正数再作运算。spa
- 咱们必须一致地保证将原序列转为旋转序列。.net
2. 实现迭代器Iterator接口索引
为了使用迭代来遍历数组for (Obj o : CircularArray),咱们必须实现迭代器Iterator接口:接口
- 修改CircularArray<T>的定义,添加implements Iteratble<T>。这须要咱们添加一个iterator()方法给CircularArray<T>。element
- 创建CircularArrayIterator<T>类implements Iterator<T>,这须要咱们实现CircularArrayIterator的一些方法,如hasNext(), next(), 和 remove()。
一旦咱们实现了上面两项,for (Obj o : CircularArray)循环就会神奇的运行了。