001: /*
002: * Copyright 2007 Google Inc.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License. You may obtain a copy of
006: * the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013: * License for the specific language governing permissions and limitations under
014: * the License.
015: */
016: package java.util;
017:
018: /**
019: * Skeletal implementation of the List interface. <a
020: * href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/AbstractList.html">[Sun
021: * docs]</a>
022: *
023: * @param <E> the element type.
024: */
025: public abstract class AbstractList<E> extends AbstractCollection<E>
026: implements List<E> {
027:
028: private class IteratorImpl implements Iterator<E> {
029: /*
030: * i is the index of the item that will be returned on the next call to
031: * next() last is the index of the item that was returned on the previous
032: * call to next() or previous (for ListIterator), -1 if no such item exists.
033: */
034:
035: int i = 0, last = -1;
036:
037: public boolean hasNext() {
038: return i < AbstractList.this .size();
039: }
040:
041: public E next() {
042: if (!hasNext()) {
043: throw new NoSuchElementException();
044: }
045: return AbstractList.this .get(last = i++);
046: }
047:
048: public void remove() {
049: if (last < 0) {
050: throw new IllegalStateException();
051: }
052: AbstractList.this .remove(last);
053: i = last;
054: last = -1;
055: }
056: }
057:
058: /**
059: * Implementation of <code>ListIterator</code> for abstract lists.
060: */
061: private final class ListIteratorImpl extends IteratorImpl implements
062: ListIterator<E> {
063: /*
064: * i is the index of the item that will be returned on the next call to
065: * next() last is the index of the item that was returned on the previous
066: * call to next() or previous (for ListIterator), -1 if no such item exists.
067: */
068:
069: private ListIteratorImpl() {
070: // Nothing to do
071: }
072:
073: private ListIteratorImpl(int start) {
074: int size = AbstractList.this .size();
075: if (start < 0 || start > size) {
076: AbstractList.this .indexOutOfBounds(start);
077: }
078: i = start;
079: }
080:
081: public void add(E o) {
082: AbstractList.this .add(i++, o);
083: last = -1;
084: }
085:
086: public boolean hasPrevious() {
087: return i > 0;
088: }
089:
090: public int nextIndex() {
091: return i;
092: }
093:
094: public E previous() {
095: if (!hasPrevious()) {
096: throw new NoSuchElementException();
097: }
098: return AbstractList.this .get(last = --i);
099: }
100:
101: public int previousIndex() {
102: return i - 1;
103: }
104:
105: public void set(E o) {
106: if (last == -1) {
107: throw new IllegalStateException();
108: }
109: AbstractList.this .set(last, o);
110: }
111: }
112:
113: protected AbstractList() {
114: }
115:
116: @Override
117: public boolean add(E obj) {
118: add(size(), obj);
119: return true;
120: }
121:
122: public void add(int index, E element) {
123: throw new UnsupportedOperationException("add");
124: }
125:
126: public boolean addAll(int index, Collection<? extends E> c) {
127: Iterator<? extends E> iter = c.iterator();
128: while (iter.hasNext()) {
129: add(index, iter.next());
130: ++index;
131: }
132: return !c.isEmpty();
133: }
134:
135: @Override
136: public void clear() {
137: removeRange(0, size());
138: }
139:
140: @Override
141: public boolean equals(Object o) {
142: if (o == this ) {
143: return true;
144: }
145:
146: if (!(o instanceof List)) {
147: return false;
148: }
149:
150: List<?> other = (List<?>) o;
151: if (size() != other.size()) {
152: return false;
153: }
154:
155: Iterator<E> iter = iterator();
156: Iterator<?> iterOther = other.iterator();
157:
158: while (iter.hasNext()) {
159: E elem = iter.next();
160: Object elemOther = iterOther.next();
161:
162: if (!(elem == null ? elemOther == null : elem
163: .equals(elemOther))) {
164: return false;
165: }
166: }
167:
168: return true;
169: }
170:
171: public abstract E get(int index);
172:
173: @Override
174: public int hashCode() {
175: int k = 1;
176: final int coeff = 31;
177: Iterator<E> iter = iterator();
178: while (iter.hasNext()) {
179: E obj = iter.next();
180: k = coeff * k + (obj == null ? 0 : obj.hashCode());
181: }
182: return k;
183: }
184:
185: public int indexOf(Object toFind) {
186: for (int i = 0, n = size(); i < n; ++i) {
187: if (toFind == null ? get(i) == null : toFind.equals(get(i))) {
188: return i;
189: }
190: }
191: return -1;
192: }
193:
194: @Override
195: public Iterator<E> iterator() {
196: return new IteratorImpl();
197: }
198:
199: public int lastIndexOf(Object toFind) {
200: for (int i = size() - 1; i > -1; --i) {
201: if (toFind == null ? get(i) == null : toFind.equals(get(i))) {
202: return i;
203: }
204: }
205: return -1;
206: }
207:
208: public ListIterator<E> listIterator() {
209: return new ListIteratorImpl();
210: }
211:
212: public ListIterator<E> listIterator(int from) {
213: return new ListIteratorImpl(from);
214: }
215:
216: public E remove(int index) {
217: throw new UnsupportedOperationException("remove");
218: }
219:
220: public E set(int index, E o) {
221: throw new UnsupportedOperationException("set");
222: }
223:
224: public List<E> subList(int fromIndex, int toIndex) {
225: // TODO Implement me.
226: throw new UnsupportedOperationException("subList");
227: }
228:
229: /**
230: * Throws an <code>indexOutOfBoundsException</code>.
231: */
232: protected void indexOutOfBounds(int i) {
233: throw new IndexOutOfBoundsException("Index: " + i + ", Size: "
234: + this .size());
235: }
236:
237: protected void removeRange(int fromIndex, int endIndex) {
238: ListIterator<E> iter = listIterator(fromIndex);
239: for (int i = fromIndex; i < endIndex; ++i) {
240: iter.next();
241: iter.remove();
242: }
243: }
244: }
|