Java tutorial
/* * Copyright 2002-2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.collections.primitives; import java.util.ConcurrentModificationException; import java.util.NoSuchElementException; /** * Abstract base class for {@link DoubleList}s backed * by random access structures like arrays. * <p /> * Read-only subclasses must override {@link #get} * and {@link #size}. Mutable subclasses * should also override {@link #set}. Variably-sized * subclasses should also override {@link #add} * and {@link #removeElementAt}. All other methods * have at least some base implementation derived from * these. Subclasses may choose to override these methods * to provide a more efficient implementation. * * @since Commons Primitives 1.0 * @version $Revision: 1.4 $ $Date: 2004/02/25 20:46:25 $ * * @author Rodney Waldhoff */ public abstract class RandomAccessDoubleList extends AbstractDoubleCollection implements DoubleList { // constructors //------------------------------------------------------------------------- /** Constructs an empty list. */ protected RandomAccessDoubleList() { } // fully abstract methods //------------------------------------------------------------------------- public abstract double get(int index); public abstract int size(); // unsupported in base //------------------------------------------------------------------------- /** * Unsupported in this implementation. * @throws UnsupportedOperationException since this method is not supported */ public double removeElementAt(int index) { throw new UnsupportedOperationException(); } /** * Unsupported in this implementation. * @throws UnsupportedOperationException since this method is not supported */ public double set(int index, double element) { throw new UnsupportedOperationException(); } /** * Unsupported in this implementation. * @throws UnsupportedOperationException since this method is not supported */ public void add(int index, double element) { throw new UnsupportedOperationException(); } //------------------------------------------------------------------------- // javadocs here are inherited public boolean add(double element) { add(size(), element); return true; } public boolean addAll(int index, DoubleCollection collection) { boolean modified = false; for (DoubleIterator iter = collection.iterator(); iter.hasNext();) { add(index++, iter.next()); modified = true; } return modified; } public int indexOf(double element) { int i = 0; for (DoubleIterator iter = iterator(); iter.hasNext();) { if (iter.next() == element) { return i; } else { i++; } } return -1; } public int lastIndexOf(double element) { for (DoubleListIterator iter = listIterator(size()); iter.hasPrevious();) { if (iter.previous() == element) { return iter.nextIndex(); } } return -1; } public DoubleIterator iterator() { return listIterator(); } public DoubleListIterator listIterator() { return listIterator(0); } public DoubleListIterator listIterator(int index) { return new RandomAccessDoubleListIterator(this, index); } public DoubleList subList(int fromIndex, int toIndex) { return new RandomAccessDoubleSubList(this, fromIndex, toIndex); } public boolean equals(Object that) { if (this == that) { return true; } else if (that instanceof DoubleList) { DoubleList thatList = (DoubleList) that; if (size() != thatList.size()) { return false; } for (DoubleIterator thatIter = thatList.iterator(), thisIter = iterator(); thisIter.hasNext();) { if (thisIter.next() != thatIter.next()) { return false; } } return true; } else { return false; } } public int hashCode() { int hash = 1; for (DoubleIterator iter = iterator(); iter.hasNext();) { long bits = Double.doubleToLongBits(iter.next()); hash = 31 * hash + ((int) (bits ^ (bits >>> 32))); } return hash; } public String toString() { StringBuffer buf = new StringBuffer(); buf.append("["); for (DoubleIterator iter = iterator(); iter.hasNext();) { buf.append(iter.next()); if (iter.hasNext()) { buf.append(", "); } } buf.append("]"); return buf.toString(); } // protected utilities //------------------------------------------------------------------------- /** Get my count of structural modifications. */ protected int getModCount() { return _modCount; } /** Increment my count of structural modifications. */ protected void incrModCount() { _modCount++; } // attributes //------------------------------------------------------------------------- private int _modCount = 0; // inner classes //------------------------------------------------------------------------- private static class ComodChecker { ComodChecker(RandomAccessDoubleList source) { _source = source; resyncModCount(); } protected RandomAccessDoubleList getList() { return _source; } protected void assertNotComodified() throws ConcurrentModificationException { if (_expectedModCount != getList().getModCount()) { throw new ConcurrentModificationException(); } } protected void resyncModCount() { _expectedModCount = getList().getModCount(); } private RandomAccessDoubleList _source = null; private int _expectedModCount = -1; } protected static class RandomAccessDoubleListIterator extends ComodChecker implements DoubleListIterator { RandomAccessDoubleListIterator(RandomAccessDoubleList list, int index) { super(list); if (index < 0 || index > getList().size()) { throw new IndexOutOfBoundsException("Index " + index + " not in [0," + getList().size() + ")"); } else { _nextIndex = index; resyncModCount(); } } public boolean hasNext() { assertNotComodified(); return _nextIndex < getList().size(); } public boolean hasPrevious() { assertNotComodified(); return _nextIndex > 0; } public int nextIndex() { assertNotComodified(); return _nextIndex; } public int previousIndex() { assertNotComodified(); return _nextIndex - 1; } public double next() { assertNotComodified(); if (!hasNext()) { throw new NoSuchElementException(); } else { double val = getList().get(_nextIndex); _lastReturnedIndex = _nextIndex; _nextIndex++; return val; } } public double previous() { assertNotComodified(); if (!hasPrevious()) { throw new NoSuchElementException(); } else { double val = getList().get(_nextIndex - 1); _lastReturnedIndex = _nextIndex - 1; _nextIndex--; return val; } } public void add(double value) { assertNotComodified(); getList().add(_nextIndex, value); _nextIndex++; _lastReturnedIndex = -1; resyncModCount(); } public void remove() { assertNotComodified(); if (-1 == _lastReturnedIndex) { throw new IllegalStateException(); } else { getList().removeElementAt(_lastReturnedIndex); _lastReturnedIndex = -1; _nextIndex--; resyncModCount(); } } public void set(double value) { assertNotComodified(); if (-1 == _lastReturnedIndex) { throw new IllegalStateException(); } else { getList().set(_lastReturnedIndex, value); resyncModCount(); } } private int _nextIndex = 0; private int _lastReturnedIndex = -1; } protected static class RandomAccessDoubleSubList extends RandomAccessDoubleList implements DoubleList { RandomAccessDoubleSubList(RandomAccessDoubleList list, int fromIndex, int toIndex) { if (fromIndex < 0 || toIndex > list.size()) { throw new IndexOutOfBoundsException(); } else if (fromIndex > toIndex) { throw new IllegalArgumentException(); } else { _list = list; _offset = fromIndex; _limit = toIndex - fromIndex; _comod = new ComodChecker(list); _comod.resyncModCount(); } } public double get(int index) { checkRange(index); _comod.assertNotComodified(); return _list.get(toUnderlyingIndex(index)); } public double removeElementAt(int index) { checkRange(index); _comod.assertNotComodified(); double val = _list.removeElementAt(toUnderlyingIndex(index)); _limit--; _comod.resyncModCount(); incrModCount(); return val; } public double set(int index, double element) { checkRange(index); _comod.assertNotComodified(); double val = _list.set(toUnderlyingIndex(index), element); incrModCount(); _comod.resyncModCount(); return val; } public void add(int index, double element) { checkRangeIncludingEndpoint(index); _comod.assertNotComodified(); _list.add(toUnderlyingIndex(index), element); _limit++; _comod.resyncModCount(); incrModCount(); } public int size() { _comod.assertNotComodified(); return _limit; } private void checkRange(int index) { if (index < 0 || index >= size()) { throw new IndexOutOfBoundsException("index " + index + " not in [0," + size() + ")"); } } private void checkRangeIncludingEndpoint(int index) { if (index < 0 || index > size()) { throw new IndexOutOfBoundsException("index " + index + " not in [0," + size() + "]"); } } private int toUnderlyingIndex(int index) { return (index + _offset); } private int _offset = 0; private int _limit = 0; private RandomAccessDoubleList _list = null; private ComodChecker _comod = null; } }