http://git-wip-us.apache.org/repos/asf/commons-collections/blob/884baf0d/src/java/org/apache/commons/collections/list/TransformedList.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/commons/collections/list/TransformedList.java b/src/java/org/apache/commons/collections/list/TransformedList.java index 1c0316c..4ca6cf2 100644 --- a/src/java/org/apache/commons/collections/list/TransformedList.java +++ b/src/java/org/apache/commons/collections/list/TransformedList.java @@ -39,7 +39,7 @@ import org.apache.commons.collections.iterators.AbstractListIteratorDecorator; * * @author Stephen Colebourne */ -public class TransformedList extends TransformedCollection implements List { +public class TransformedList<E> extends TransformedCollection<E> implements List<E> { /** Serialization version */ private static final long serialVersionUID = 1077193035000013141L; @@ -54,8 +54,8 @@ public class TransformedList extends TransformedCollection implements List { * @param transformer the transformer to use for conversion, must not be null * @throws IllegalArgumentException if list or transformer is null */ - public static List decorate(List list, Transformer transformer) { - return new TransformedList(list, transformer); + public static <E> List<E> decorate(List<E> list, Transformer<? super E, ? extends E> transformer) { + return new TransformedList<E>(list, transformer); } //----------------------------------------------------------------------- @@ -69,7 +69,7 @@ public class TransformedList extends TransformedCollection implements List { * @param transformer the transformer to use for conversion, must not be null * @throws IllegalArgumentException if list or transformer is null */ - protected TransformedList(List list, Transformer transformer) { + protected TransformedList(List<E> list, Transformer<? super E, ? extends E> transformer) { super(list, transformer); } @@ -78,12 +78,12 @@ public class TransformedList extends TransformedCollection implements List { * * @return the decorated list */ - protected List getList() { - return (List) collection; + protected List<E> getList() { + return (List<E>) collection; } //----------------------------------------------------------------------- - public Object get(int index) { + public E get(int index) { return getList().get(index); } @@ -95,54 +95,54 @@ public class TransformedList extends TransformedCollection implements List { return getList().lastIndexOf(object); } - public Object remove(int index) { + public E remove(int index) { return getList().remove(index); } //----------------------------------------------------------------------- - public void add(int index, Object object) { + public void add(int index, E object) { object = transform(object); getList().add(index, object); } - public boolean addAll(int index, Collection coll) { + public boolean addAll(int index, Collection<? extends E> coll) { coll = transform(coll); return getList().addAll(index, coll); } - public ListIterator listIterator() { + public ListIterator<E> listIterator() { return listIterator(0); } - public ListIterator listIterator(int i) { + public ListIterator<E> listIterator(int i) { return new TransformedListIterator(getList().listIterator(i)); } - public Object set(int index, Object object) { + public E set(int index, E object) { object = transform(object); return getList().set(index, object); } - public List subList(int fromIndex, int toIndex) { - List sub = getList().subList(fromIndex, toIndex); - return new TransformedList(sub, transformer); + public List<E> subList(int fromIndex, int toIndex) { + List<E> sub = getList().subList(fromIndex, toIndex); + return new TransformedList<E>(sub, transformer); } /** * Inner class Iterator for the TransformedList */ - protected class TransformedListIterator extends AbstractListIteratorDecorator { - - protected TransformedListIterator(ListIterator iterator) { + protected class TransformedListIterator extends AbstractListIteratorDecorator<E> { + + protected TransformedListIterator(ListIterator<E> iterator) { super(iterator); } - - public void add(Object object) { + + public void add(E object) { object = transform(object); iterator.add(object); } - - public void set(Object object) { + + public void set(E object) { object = transform(object); iterator.set(object); }
http://git-wip-us.apache.org/repos/asf/commons-collections/blob/884baf0d/src/java/org/apache/commons/collections/list/TreeList.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/commons/collections/list/TreeList.java b/src/java/org/apache/commons/collections/list/TreeList.java index 1576f90..b93c4e0 100644 --- a/src/java/org/apache/commons/collections/list/TreeList.java +++ b/src/java/org/apache/commons/collections/list/TreeList.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You 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. @@ -48,22 +48,22 @@ import org.apache.commons.collections.OrderedIterator; * <p> * <code>LinkedList</code> is rarely a good choice of implementation. * <code>TreeList</code> is almost always a good replacement for it, although it - * does use sligtly more memory. - * + * does use slightly more memory. + * * @since Commons Collections 3.1 * @version $Revision$ $Date$ * * @author Joerg Schmuecker * @author Stephen Colebourne */ -public class TreeList extends AbstractList { +public class TreeList<E> extends AbstractList<E> { // add; toArray; iterator; insert; get; indexOf; remove // TreeList = 1260;7360;3080; 160; 170;3400; 170; // ArrayList = 220;1480;1760; 6870; 50;1540; 7200; // LinkedList = 270;7360;3350;55860;290720;2910;55200; /** The root node in the AVL tree */ - private AVLNode root; + private AVLNode<E> root; /** The current size of the list */ private int size; @@ -78,11 +78,11 @@ public class TreeList extends AbstractList { /** * Constructs a new empty list that copies the specified list. - * + * * @param coll the collection to copy * @throws NullPointerException if the collection is null */ - public TreeList(Collection coll) { + public TreeList(Collection<E> coll) { super(); addAll(coll); } @@ -90,18 +90,18 @@ public class TreeList extends AbstractList { //----------------------------------------------------------------------- /** * Gets the element at the specified index. - * + * * @param index the index to retrieve * @return the element at the specified index */ - public Object get(int index) { + public E get(int index) { checkInterval(index, 0, size() - 1); return root.get(index).getValue(); } /** * Gets the current size of the list. - * + * * @return the current size */ public int size() { @@ -110,40 +110,40 @@ public class TreeList extends AbstractList { /** * Gets an iterator over the list. - * + * * @return an iterator over the list */ - public Iterator iterator() { + public Iterator<E> iterator() { // override to go 75% faster return listIterator(0); } /** * Gets a ListIterator over the list. - * + * * @return the new iterator */ - public ListIterator listIterator() { + public ListIterator<E> listIterator() { // override to go 75% faster return listIterator(0); } /** * Gets a ListIterator over the list. - * + * * @param fromIndex the index to start from * @return the new iterator */ - public ListIterator listIterator(int fromIndex) { + public ListIterator<E> listIterator(int fromIndex) { // override to go 75% faster // cannot use EmptyIterator as iterator.add() must work checkInterval(fromIndex, 0, size()); - return new TreeListIterator(this, fromIndex); + return new TreeListIterator<E>(this, fromIndex); } /** * Searches for the index of an object in the list. - * + * * @return the index of the object, -1 if not found */ public int indexOf(Object object) { @@ -156,7 +156,7 @@ public class TreeList extends AbstractList { /** * Searches for the presence of an object in the list. - * + * * @return true if the object is found */ public boolean contains(Object object) { @@ -165,7 +165,7 @@ public class TreeList extends AbstractList { /** * Converts the list into an array. - * + * * @return the list as an array */ public Object[] toArray() { @@ -180,15 +180,15 @@ public class TreeList extends AbstractList { //----------------------------------------------------------------------- /** * Adds a new element to the list. - * + * * @param index the index to add before * @param obj the element to add */ - public void add(int index, Object obj) { + public void add(int index, E obj) { modCount++; checkInterval(index, 0, size()); if (root == null) { - root = new AVLNode(index, obj, null, null); + root = new AVLNode<E>(index, obj, null, null); } else { root = root.insert(index, obj); } @@ -197,30 +197,30 @@ public class TreeList extends AbstractList { /** * Sets the element at the specified index. - * + * * @param index the index to set * @param obj the object to store at the specified index * @return the previous object at that index * @throws IndexOutOfBoundsException if the index is invalid */ - public Object set(int index, Object obj) { + public E set(int index, E obj) { checkInterval(index, 0, size() - 1); - AVLNode node = root.get(index); - Object result = node.value; + AVLNode<E> node = root.get(index); + E result = node.value; node.setValue(obj); return result; } /** * Removes the element at the specified index. - * + * * @param index the index to remove * @return the previous object at that index */ - public Object remove(int index) { + public E remove(int index) { modCount++; checkInterval(index, 0, size() - 1); - Object result = get(index); + E result = get(index); root = root.remove(index); size--; return result; @@ -238,7 +238,7 @@ public class TreeList extends AbstractList { //----------------------------------------------------------------------- /** * Checks whether the index is valid. - * + * * @param index the index to check * @param startIndex the first allowed index * @param endIndex the last allowed index @@ -263,13 +263,13 @@ public class TreeList extends AbstractList { * The Faedelung calculation stores a flag for both the left and right child * to indicate if they are a child (false) or a link as in linked list (true). */ - static class AVLNode { + static class AVLNode<E> { /** The left child node or the predecessor if {@link #leftIsPrevious}.*/ - private AVLNode left; + private AVLNode<E> left; /** Flag indicating that left reference is not a subtree but the predecessor. */ private boolean leftIsPrevious; /** The right child node or the successor if {@link #rightIsNext}. */ - private AVLNode right; + private AVLNode<E> right; /** Flag indicating that right reference is not a subtree but the successor. */ private boolean rightIsNext; /** How many levels of left/right are below this one. */ @@ -277,17 +277,17 @@ public class TreeList extends AbstractList { /** The relative position, root holds absolute position. */ private int relativePosition; /** The stored element. */ - private Object value; + private E value; /** * Constructs a new node with a relative position. - * + * * @param relativePosition the relative position of the node * @param obj the value for the ndoe * @param rightFollower the node with the value following this one * @param leftFollower the node with the value leading this one */ - private AVLNode(int relativePosition, Object obj, AVLNode rightFollower, AVLNode leftFollower) { + private AVLNode(int relativePosition, E obj, AVLNode<E> rightFollower, AVLNode<E> leftFollower) { this.relativePosition = relativePosition; value = obj; rightIsNext = true; @@ -298,19 +298,19 @@ public class TreeList extends AbstractList { /** * Gets the value. - * + * * @return the value of this node */ - Object getValue() { + E getValue() { return value; } /** * Sets the value. - * + * * @param obj the value to store */ - void setValue(Object obj) { + void setValue(E obj) { this.value = obj; } @@ -318,14 +318,14 @@ public class TreeList extends AbstractList { * Locate the element with the given index relative to the * offset of the parent of this node. */ - AVLNode get(int index) { + AVLNode<E> get(int index) { int indexRelativeToMe = index - relativePosition; if (indexRelativeToMe == 0) { return this; } - AVLNode nextNode = ((indexRelativeToMe < 0) ? getLeftSubTree() : getRightSubTree()); + AVLNode<E> nextNode = ((indexRelativeToMe < 0) ? getLeftSubTree() : getRightSubTree()); if (nextNode == null) { return null; } @@ -353,7 +353,7 @@ public class TreeList extends AbstractList { /** * Stores the node and its children into the array specified. - * + * * @param array the array to be filled * @param index the index of this node */ @@ -369,10 +369,10 @@ public class TreeList extends AbstractList { /** * Gets the next node in the list after this one. - * + * * @return the next node */ - AVLNode next() { + AVLNode<E> next() { if (rightIsNext || right == null) { return right; } @@ -381,10 +381,10 @@ public class TreeList extends AbstractList { /** * Gets the node in the list before this one. - * + * * @return the previous node */ - AVLNode previous() { + AVLNode<E> previous() { if (leftIsPrevious || left == null) { return left; } @@ -392,27 +392,26 @@ public class TreeList extends AbstractList { } /** - * Inserts a node at the position index. - * - * @param index is the index of the position relative to the position of + * Inserts a node at the position index. + * + * @param index is the index of the position relative to the position of * the parent node. * @param obj is the object to be stored in the position. */ - AVLNode insert(int index, Object obj) { + AVLNode<E> insert(int index, E obj) { int indexRelativeToMe = index - relativePosition; if (indexRelativeToMe <= 0) { return insertOnLeft(indexRelativeToMe, obj); - } else { - return insertOnRight(indexRelativeToMe, obj); } + return insertOnRight(indexRelativeToMe, obj); } - private AVLNode insertOnLeft(int indexRelativeToMe, Object obj) { - AVLNode ret = this; + private AVLNode<E> insertOnLeft(int indexRelativeToMe, E obj) { + AVLNode<E> ret = this; if (getLeftSubTree() == null) { - setLeft(new AVLNode(-1, obj, this, left), null); + setLeft(new AVLNode<E>(-1, obj, this, left), null); } else { setLeft(left.insert(indexRelativeToMe, obj), null); } @@ -425,11 +424,11 @@ public class TreeList extends AbstractList { return ret; } - private AVLNode insertOnRight(int indexRelativeToMe, Object obj) { - AVLNode ret = this; + private AVLNode<E> insertOnRight(int indexRelativeToMe, E obj) { + AVLNode<E> ret = this; if (getRightSubTree() == null) { - setRight(new AVLNode(+1, obj, right, this), null); + setRight(new AVLNode<E>(+1, obj, right, this), null); } else { setRight(right.insert(indexRelativeToMe, obj), null); } @@ -445,42 +444,42 @@ public class TreeList extends AbstractList { /** * Gets the left node, returning null if its a faedelung. */ - private AVLNode getLeftSubTree() { + private AVLNode<E> getLeftSubTree() { return (leftIsPrevious ? null : left); } /** * Gets the right node, returning null if its a faedelung. */ - private AVLNode getRightSubTree() { + private AVLNode<E> getRightSubTree() { return (rightIsNext ? null : right); } /** * Gets the rightmost child of this node. - * + * * @return the rightmost child (greatest index) */ - private AVLNode max() { + private AVLNode<E> max() { return (getRightSubTree() == null) ? this : right.max(); } /** * Gets the leftmost child of this node. - * + * * @return the leftmost child (smallest index) */ - private AVLNode min() { + private AVLNode<E> min() { return (getLeftSubTree() == null) ? this : left.min(); } /** * Removes the node at a given position. - * - * @param index is the index of the element to be removed relative to the position of + * + * @param index is the index of the element to be removed relative to the position of * the parent node of the current node. */ - AVLNode remove(int index) { + AVLNode<E> remove(int index) { int indexRelativeToMe = index - relativePosition; if (indexRelativeToMe == 0) { @@ -501,7 +500,7 @@ public class TreeList extends AbstractList { return balance(); } - private AVLNode removeMax() { + private AVLNode<E> removeMax() { if (getRightSubTree() == null) { return removeSelf(); } @@ -513,7 +512,7 @@ public class TreeList extends AbstractList { return balance(); } - private AVLNode removeMin() { + private AVLNode<E> removeMin() { if (getLeftSubTree() == null) { return removeSelf(); } @@ -530,7 +529,7 @@ public class TreeList extends AbstractList { * * @return the node that replaces this one in the parent */ - private AVLNode removeSelf() { + private AVLNode<E> removeSelf() { if (getRightSubTree() == null && getLeftSubTree() == null) { return null; } @@ -549,7 +548,7 @@ public class TreeList extends AbstractList { if (heightRightMinusLeft() > 0) { // more on the right, so delete from the right - AVLNode rightMin = right.min(); + AVLNode<E> rightMin = right.min(); value = rightMin.value; if (leftIsPrevious) { left = rightMin.left; @@ -560,12 +559,12 @@ public class TreeList extends AbstractList { } } else { // more on the left or equal, so delete from the left - AVLNode leftMax = left.max(); + AVLNode<E> leftMax = left.max(); value = leftMax.value; if (rightIsNext) { right = leftMax.right; } - AVLNode leftPrevious = left.left; + AVLNode<E> leftPrevious = left.left; left = left.removeMax(); if (left == null) { // special case where left that was deleted was a double link @@ -585,7 +584,7 @@ public class TreeList extends AbstractList { /** * Balances according to the AVL algorithm. */ - private AVLNode balance() { + private AVLNode<E> balance() { switch (heightRightMinusLeft()) { case 1 : case 0 : @@ -609,7 +608,7 @@ public class TreeList extends AbstractList { /** * Gets the relative position. */ - private int getOffset(AVLNode node) { + private int getOffset(AVLNode<E> node) { if (node == null) { return 0; } @@ -619,7 +618,7 @@ public class TreeList extends AbstractList { /** * Sets the relative position. */ - private int setOffset(AVLNode node, int newOffest) { + private int setOffset(AVLNode<E> node, int newOffest) { if (node == null) { return 0; } @@ -640,7 +639,7 @@ public class TreeList extends AbstractList { /** * Returns the height of the node or -1 if the node is null. */ - private int getHeight(AVLNode node) { + private int getHeight(AVLNode<E> node) { return (node == null ? -1 : node.height); } @@ -651,9 +650,9 @@ public class TreeList extends AbstractList { return getHeight(getRightSubTree()) - getHeight(getLeftSubTree()); } - private AVLNode rotateLeft() { - AVLNode newTop = right; // can't be faedelung! - AVLNode movedNode = getRightSubTree().getLeftSubTree(); + private AVLNode<E> rotateLeft() { + AVLNode<E> newTop = right; // can't be faedelung! + AVLNode<E> movedNode = getRightSubTree().getLeftSubTree(); int newTopPosition = relativePosition + getOffset(newTop); int myNewPosition = -newTop.relativePosition; @@ -668,9 +667,9 @@ public class TreeList extends AbstractList { return newTop; } - private AVLNode rotateRight() { - AVLNode newTop = left; // can't be faedelung - AVLNode movedNode = getLeftSubTree().getRightSubTree(); + private AVLNode<E> rotateRight() { + AVLNode<E> newTop = left; // can't be faedelung + AVLNode<E> movedNode = getLeftSubTree().getRightSubTree(); int newTopPosition = relativePosition + getOffset(newTop); int myNewPosition = -newTop.relativePosition; @@ -691,7 +690,7 @@ public class TreeList extends AbstractList { * @param node the new left subtree node * @param previous the previous node in the linked list */ - private void setLeft(AVLNode node, AVLNode previous) { + private void setLeft(AVLNode<E> node, AVLNode<E> previous) { leftIsPrevious = (node == null); left = (leftIsPrevious ? previous : node); recalcHeight(); @@ -703,7 +702,7 @@ public class TreeList extends AbstractList { * @param node the new left subtree node * @param next the next node in the linked list */ - private void setRight(AVLNode node, AVLNode next) { + private void setRight(AVLNode<E> node, AVLNode<E> next) { rightIsNext = (node == null); right = (rightIsNext ? next : node); recalcHeight(); @@ -747,7 +746,7 @@ public class TreeList extends AbstractList { // } // return count + left.checkLeftSubNode(); // } -// +// // private int checkRightSubNode() { // AVLNode right = getRightSubTree(); // if (right == null) { @@ -773,13 +772,13 @@ public class TreeList extends AbstractList { /** * A list iterator over the linked list. */ - static class TreeListIterator implements ListIterator, OrderedIterator { + static class TreeListIterator<E> implements ListIterator<E>, OrderedIterator<E> { /** The parent list */ - protected final TreeList parent; + protected final TreeList<E> parent; /** * Cache of the next node that will be returned by {@link #next()}. */ - protected AVLNode next; + protected AVLNode<E> next; /** * The index of the next node to be returned. */ @@ -788,7 +787,7 @@ public class TreeList extends AbstractList { * Cache of the last node that was returned by {@link #next()} * or {@link #previous()}. */ - protected AVLNode current; + protected AVLNode<E> current; /** * The index of the last node that was returned. */ @@ -803,11 +802,11 @@ public class TreeList extends AbstractList { /** * Create a ListIterator for a list. - * + * * @param parent the parent list * @param fromIndex the index to start at */ - protected TreeListIterator(TreeList parent, int fromIndex) throws IndexOutOfBoundsException { + protected TreeListIterator(TreeList<E> parent, int fromIndex) throws IndexOutOfBoundsException { super(); this.parent = parent; this.expectedModCount = parent.modCount; @@ -819,7 +818,7 @@ public class TreeList extends AbstractList { /** * Checks the modification count of the list is the value that this * object expects. - * + * * @throws ConcurrentModificationException If the list's modification * count isn't the value that was expected. */ @@ -833,7 +832,7 @@ public class TreeList extends AbstractList { return (nextIndex < parent.size()); } - public Object next() { + public E next() { checkModCount(); if (!hasNext()) { throw new NoSuchElementException("No element at index " + nextIndex + "."); @@ -841,7 +840,7 @@ public class TreeList extends AbstractList { if (next == null) { next = parent.root.get(nextIndex); } - Object value = next.getValue(); + E value = next.getValue(); current = next; currentIndex = nextIndex++; next = next.next(); @@ -852,7 +851,7 @@ public class TreeList extends AbstractList { return (nextIndex > 0); } - public Object previous() { + public E previous() { checkModCount(); if (!hasPrevious()) { throw new NoSuchElementException("Already at start of list."); @@ -862,7 +861,7 @@ public class TreeList extends AbstractList { } else { next = next.previous(); } - Object value = next.getValue(); + E value = next.getValue(); current = next; currentIndex = --nextIndex; return value; @@ -895,7 +894,7 @@ public class TreeList extends AbstractList { expectedModCount++; } - public void set(Object obj) { + public void set(E obj) { checkModCount(); if (current == null) { throw new IllegalStateException(); @@ -903,7 +902,7 @@ public class TreeList extends AbstractList { current.setValue(obj); } - public void add(Object obj) { + public void add(E obj) { checkModCount(); parent.add(nextIndex, obj); current = null; http://git-wip-us.apache.org/repos/asf/commons-collections/blob/884baf0d/src/java/org/apache/commons/collections/list/UnmodifiableList.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/commons/collections/list/UnmodifiableList.java b/src/java/org/apache/commons/collections/list/UnmodifiableList.java index 1a34886..f11b700 100644 --- a/src/java/org/apache/commons/collections/list/UnmodifiableList.java +++ b/src/java/org/apache/commons/collections/list/UnmodifiableList.java @@ -35,8 +35,8 @@ import org.apache.commons.collections.iterators.UnmodifiableListIterator; * * @author Stephen Colebourne */ -public final class UnmodifiableList - extends AbstractSerializableListDecorator +public final class UnmodifiableList<E> + extends AbstractSerializableListDecorator<E> implements Unmodifiable { /** Serialization version */ @@ -48,11 +48,11 @@ public final class UnmodifiableList * @param list the list to decorate, must not be null * @throws IllegalArgumentException if list is null */ - public static List decorate(List list) { + public static <E> List<E> decorate(List<E> list) { if (list instanceof Unmodifiable) { return list; } - return new UnmodifiableList(list); + return new UnmodifiableList<E>(list); } //----------------------------------------------------------------------- @@ -61,13 +61,14 @@ public final class UnmodifiableList * * @param list the list to decorate, must not be null * @throws IllegalArgumentException if list is null + * @since Commons Collection 5 */ - private UnmodifiableList(List list) { + public UnmodifiableList(List<E> list) { super(list); } //----------------------------------------------------------------------- - public Iterator iterator() { + public Iterator<E> iterator() { return UnmodifiableIterator.decorate(decorated().iterator()); } @@ -75,7 +76,7 @@ public final class UnmodifiableList throw new UnsupportedOperationException(); } - public boolean addAll(Collection coll) { + public boolean addAll(Collection<? extends E> coll) { throw new UnsupportedOperationException(); } @@ -87,42 +88,42 @@ public final class UnmodifiableList throw new UnsupportedOperationException(); } - public boolean removeAll(Collection coll) { + public boolean removeAll(Collection<?> coll) { throw new UnsupportedOperationException(); } - public boolean retainAll(Collection coll) { + public boolean retainAll(Collection<?> coll) { throw new UnsupportedOperationException(); } //----------------------------------------------------------------------- - public ListIterator listIterator() { + public ListIterator<E> listIterator() { return UnmodifiableListIterator.decorate(decorated().listIterator()); } - public ListIterator listIterator(int index) { + public ListIterator<E> listIterator(int index) { return UnmodifiableListIterator.decorate(decorated().listIterator(index)); } - public void add(int index, Object object) { + public void add(int index, E object) { throw new UnsupportedOperationException(); } - public boolean addAll(int index, Collection coll) { + public boolean addAll(int index, Collection<? extends E> coll) { throw new UnsupportedOperationException(); } - public Object remove(int index) { + public E remove(int index) { throw new UnsupportedOperationException(); } - public Object set(int index, Object object) { + public E set(int index, E object) { throw new UnsupportedOperationException(); } - public List subList(int fromIndex, int toIndex) { - List sub = decorated().subList(fromIndex, toIndex); - return new UnmodifiableList(sub); + public List<E> subList(int fromIndex, int toIndex) { + List<E> sub = decorated().subList(fromIndex, toIndex); + return new UnmodifiableList<E>(sub); } } http://git-wip-us.apache.org/repos/asf/commons-collections/blob/884baf0d/src/java/org/apache/commons/collections/map/AbstractHashedMap.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/commons/collections/map/AbstractHashedMap.java b/src/java/org/apache/commons/collections/map/AbstractHashedMap.java index 1d0f196..b0d29a6 100644 --- a/src/java/org/apache/commons/collections/map/AbstractHashedMap.java +++ b/src/java/org/apache/commons/collections/map/AbstractHashedMap.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You 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. @@ -51,7 +51,7 @@ import org.apache.commons.collections.iterators.EmptyMapIterator; * NOTE: From Commons Collections 3.1 this class extends AbstractMap. * This is to provide backwards compatibility for ReferenceMap between v3.0 and v3.1. * This extends clause will be removed in v4.0. - * + * * @since Commons Collections 3.0 * @version $Revision$ $Date$ * @@ -59,15 +59,15 @@ import org.apache.commons.collections.iterators.EmptyMapIterator; * @author Stephen Colebourne * @author Christian Siefkes */ -public class AbstractHashedMap extends AbstractMap implements IterableMap { - +public class AbstractHashedMap<K, V> extends AbstractMap<K, V> implements IterableMap<K, V> { + protected static final String NO_NEXT_ENTRY = "No next() entry in the iteration"; protected static final String NO_PREVIOUS_ENTRY = "No previous() entry in the iteration"; protected static final String REMOVE_INVALID = "remove() can only be called once after next()"; protected static final String GETKEY_INVALID = "getKey() can only be called after next() and before remove()"; protected static final String GETVALUE_INVALID = "getValue() can only be called after next() and before remove()"; protected static final String SETVALUE_INVALID = "setValue() can only be called after next() and before remove()"; - + /** The default capacity to use */ protected static final int DEFAULT_CAPACITY = 16; /** The default threshold to use */ @@ -78,23 +78,23 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { protected static final int MAXIMUM_CAPACITY = 1 << 30; /** An object for masking null */ protected static final Object NULL = new Object(); - + /** Load factor, normally 0.75 */ protected transient float loadFactor; /** The size of the map */ protected transient int size; /** Map entries */ - protected transient HashEntry[] data; + protected transient HashEntry<K, V>[] data; /** Size at which to rehash */ protected transient int threshold; /** Modification count for iterators */ protected transient int modCount; /** Entry set */ - protected transient EntrySet entrySet; + protected transient EntrySet<K, V> entrySet; /** Key set */ - protected transient KeySet keySet; + protected transient KeySet<K> keySet; /** Values */ - protected transient Values values; + protected transient Values<V> values; /** * Constructor only used in deserialization, do not use otherwise. @@ -105,11 +105,12 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { /** * Constructor which performs no validation on the passed in parameters. - * + * * @param initialCapacity the initial capacity, must be a power of two * @param loadFactor the load factor, must be > 0.0f and generally < 1.0f * @param threshold the threshold, must be sensible */ + @SuppressWarnings("unchecked") protected AbstractHashedMap(int initialCapacity, float loadFactor, int threshold) { super(); this.loadFactor = loadFactor; @@ -120,7 +121,7 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { /** * Constructs a new, empty map with the specified initial capacity and - * default load factor. + * default load factor. * * @param initialCapacity the initial capacity * @throws IllegalArgumentException if the initial capacity is less than one @@ -131,13 +132,14 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { /** * Constructs a new, empty map with the specified initial capacity and - * load factor. + * load factor. * * @param initialCapacity the initial capacity * @param loadFactor the load factor * @throws IllegalArgumentException if the initial capacity is less than one * @throws IllegalArgumentException if the load factor is less than or equal to zero */ + @SuppressWarnings("unchecked") protected AbstractHashedMap(int initialCapacity, float loadFactor) { super(); if (initialCapacity < 1) { @@ -159,7 +161,7 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { * @param map the map to copy * @throws NullPointerException if the map is null */ - protected AbstractHashedMap(Map map) { + protected AbstractHashedMap(Map<K, V> map) { this(Math.max(2 * map.size(), DEFAULT_CAPACITY), DEFAULT_LOAD_FACTOR); putAll(map); } @@ -173,14 +175,14 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { //----------------------------------------------------------------------- /** * Gets the value mapped to the key specified. - * + * * @param key the key * @return the mapped value, null if no match */ - public Object get(Object key) { + public V get(Object key) { key = convertKey(key); int hashCode = hash(key); - HashEntry entry = data[hashIndex(hashCode, data.length)]; // no local for hash index + HashEntry<K, V> entry = data[hashIndex(hashCode, data.length)]; // no local for hash index while (entry != null) { if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) { return entry.getValue(); @@ -192,7 +194,7 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { /** * Gets the size of the map. - * + * * @return the size */ public int size() { @@ -201,7 +203,7 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { /** * Checks whether the map is currently empty. - * + * * @return true if the map is currently size zero */ public boolean isEmpty() { @@ -211,14 +213,14 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { //----------------------------------------------------------------------- /** * Checks whether the map contains the specified key. - * + * * @param key the key to search for * @return true if the map contains the key */ public boolean containsKey(Object key) { key = convertKey(key); int hashCode = hash(key); - HashEntry entry = data[hashIndex(hashCode, data.length)]; // no local for hash index + HashEntry<K, V> entry = data[hashIndex(hashCode, data.length)]; // no local for hash index while (entry != null) { if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) { return true; @@ -230,14 +232,14 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { /** * Checks whether the map contains the specified value. - * + * * @param value the value to search for * @return true if the map contains the value */ public boolean containsValue(Object value) { if (value == null) { for (int i = 0, isize = data.length; i < isize; i++) { - HashEntry entry = data[i]; + HashEntry<K, V> entry = data[i]; while (entry != null) { if (entry.getValue() == null) { return true; @@ -247,7 +249,7 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { } } else { for (int i = 0, isize = data.length; i < isize; i++) { - HashEntry entry = data[i]; + HashEntry<K, V> entry = data[i]; while (entry != null) { if (isEqualValue(value, entry.getValue())) { return true; @@ -262,25 +264,25 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { //----------------------------------------------------------------------- /** * Puts a key-value mapping into this map. - * + * * @param key the key to add * @param value the value to add * @return the value previously mapped to this key, null if none */ - public Object put(Object key, Object value) { - key = convertKey(key); - int hashCode = hash(key); + public V put(K key, V value) { + Object convertedKey = convertKey(key); + int hashCode = hash(convertedKey); int index = hashIndex(hashCode, data.length); - HashEntry entry = data[index]; + HashEntry<K, V> entry = data[index]; while (entry != null) { - if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) { - Object oldValue = entry.getValue(); + if (entry.hashCode == hashCode && isEqualKey(convertedKey, entry.key)) { + V oldValue = entry.getValue(); updateEntry(entry, value); return oldValue; } entry = entry.next; } - + addMapping(index, hashCode, key, value); return null; } @@ -290,38 +292,37 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { * <p> * This implementation iterates around the specified map and * uses {@link #put(Object, Object)}. - * + * * @param map the map to add * @throws NullPointerException if the map is null */ - public void putAll(Map map) { + public void putAll(Map<? extends K, ? extends V> map) { int mapSize = map.size(); if (mapSize == 0) { return; } int newSize = (int) ((size + mapSize) / loadFactor + 1); ensureCapacity(calculateNewCapacity(newSize)); - for (Iterator it = map.entrySet().iterator(); it.hasNext();) { - Map.Entry entry = (Map.Entry) it.next(); + for (Map.Entry<? extends K, ? extends V> entry: map.entrySet()) { put(entry.getKey(), entry.getValue()); } } /** * Removes the specified mapping from this map. - * + * * @param key the mapping to remove * @return the value mapped to the removed key, null if key not in map */ - public Object remove(Object key) { + public V remove(Object key) { key = convertKey(key); int hashCode = hash(key); int index = hashIndex(hashCode, data.length); - HashEntry entry = data[index]; - HashEntry previous = null; + HashEntry<K, V> entry = data[index]; + HashEntry<K, V> previous = null; while (entry != null) { if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) { - Object oldValue = entry.getValue(); + V oldValue = entry.getValue(); removeMapping(entry, index, previous); return oldValue; } @@ -337,7 +338,7 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { */ public void clear() { modCount++; - HashEntry[] data = this.data; + HashEntry<K, V>[] data = this.data; for (int i = data.length - 1; i >= 0; i--) { data[i] = null; } @@ -352,19 +353,19 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { * <p> * The reverse conversion can be changed, if required, by overriding the * getKey() method in the hash entry. - * + * * @param key the key convert * @return the converted key */ protected Object convertKey(Object key) { return (key == null ? NULL : key); } - + /** * Gets the hash code for the key specified. * This implementation uses the additional hashing routine from JDK1.4. * Subclasses can override this to return alternate hash codes. - * + * * @param key the key to get a hash code for * @return the hash code */ @@ -377,12 +378,12 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { h ^= (h >>> 10); return h; } - + /** * Compares two keys, in internal converted form, to see if they are equal. * This implementation uses the equals method and assumes neither key is null. * Subclasses can override this to match differently. - * + * * @param key1 the first key to compare passed in from outside * @param key2 the second key extracted from the entry via <code>entry.key</code> * @return true if equal @@ -390,12 +391,12 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { protected boolean isEqualKey(Object key1, Object key2) { return (key1 == key2 || key1.equals(key2)); } - + /** * Compares two values, in external form, to see if they are equal. * This implementation uses the equals method and assumes neither value is null. * Subclasses can override this to match differently. - * + * * @param value1 the first value to compare passed in from outside * @param value2 the second value extracted from the entry via <code>getValue()</code> * @return true if equal @@ -403,12 +404,12 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { protected boolean isEqualValue(Object value1, Object value2) { return (value1 == value2 || value1.equals(value2)); } - + /** * Gets the index into the data storage for the hashCode specified. * This implementation uses the least significant bits of the hashCode. * Subclasses can override this to return alternate bucketing. - * + * * @param hashCode the hash code to use * @param dataSize the size of the data to pick a bucket from * @return the bucket index @@ -416,7 +417,7 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { protected int hashIndex(int hashCode, int dataSize) { return hashCode & (dataSize - 1); } - + //----------------------------------------------------------------------- /** * Gets the entry mapped to the key specified. @@ -424,14 +425,14 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { * This method exists for subclasses that may need to perform a multi-step * process accessing the entry. The public methods in this class don't use this * method to gain a small performance boost. - * + * * @param key the key * @return the entry, null if no match */ - protected HashEntry getEntry(Object key) { + protected HashEntry<K, V> getEntry(Object key) { key = convertKey(key); int hashCode = hash(key); - HashEntry entry = data[hashIndex(hashCode, data.length)]; // no local for hash index + HashEntry<K, V> entry = data[hashIndex(hashCode, data.length)]; // no local for hash index while (entry != null) { if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) { return entry; @@ -447,33 +448,33 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { * <p> * This implementation calls <code>setValue()</code> on the entry. * Subclasses could override to handle changes to the map. - * + * * @param entry the entry to update * @param newValue the new value to store */ - protected void updateEntry(HashEntry entry, Object newValue) { + protected void updateEntry(HashEntry<K, V> entry, V newValue) { entry.setValue(newValue); } - + /** * Reuses an existing key-value mapping, storing completely new data. * <p> * This implementation sets all the data fields on the entry. * Subclasses could populate additional entry fields. - * + * * @param entry the entry to update, not null * @param hashIndex the index in the data array * @param hashCode the hash code of the key to add * @param key the key to add * @param value the value to add */ - protected void reuseEntry(HashEntry entry, int hashIndex, int hashCode, Object key, Object value) { + protected void reuseEntry(HashEntry<K, V> entry, int hashIndex, int hashCode, K key, V value) { entry.next = data[hashIndex]; entry.hashCode = hashCode; entry.key = key; entry.value = value; } - + //----------------------------------------------------------------------- /** * Adds a new key-value mapping into this map. @@ -482,37 +483,37 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { * and <code>checkCapacity()</code>. * It also handles changes to <code>modCount</code> and <code>size</code>. * Subclasses could override to fully control adds to the map. - * + * * @param hashIndex the index into the data array to store at * @param hashCode the hash code of the key to add * @param key the key to add * @param value the value to add */ - protected void addMapping(int hashIndex, int hashCode, Object key, Object value) { + protected void addMapping(int hashIndex, int hashCode, K key, V value) { modCount++; - HashEntry entry = createEntry(data[hashIndex], hashCode, key, value); + HashEntry<K, V> entry = createEntry(data[hashIndex], hashCode, key, value); addEntry(entry, hashIndex); size++; checkCapacity(); } - + /** * Creates an entry to store the key-value data. * <p> * This implementation creates a new HashEntry instance. * Subclasses can override this to return a different storage class, * or implement caching. - * + * * @param next the next entry in sequence * @param hashCode the hash code to use * @param key the key to store * @param value the value to store * @return the newly created entry */ - protected HashEntry createEntry(HashEntry next, int hashCode, Object key, Object value) { - return new HashEntry(next, hashCode, key, value); + protected HashEntry<K, V> createEntry(HashEntry<K, V> next, int hashCode, K key, V value) { + return new HashEntry<K, V>(next, hashCode, convertKey(key), value); } - + /** * Adds an entry into this map. * <p> @@ -522,10 +523,10 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { * @param entry the entry to add * @param hashIndex the index into the data array to store at */ - protected void addEntry(HashEntry entry, int hashIndex) { + protected void addEntry(HashEntry<K, V> entry, int hashIndex) { data[hashIndex] = entry; } - + //----------------------------------------------------------------------- /** * Removes a mapping from the map. @@ -533,51 +534,51 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { * This implementation calls <code>removeEntry()</code> and <code>destroyEntry()</code>. * It also handles changes to <code>modCount</code> and <code>size</code>. * Subclasses could override to fully control removals from the map. - * + * * @param entry the entry to remove * @param hashIndex the index into the data structure * @param previous the previous entry in the chain */ - protected void removeMapping(HashEntry entry, int hashIndex, HashEntry previous) { + protected void removeMapping(HashEntry<K, V> entry, int hashIndex, HashEntry<K, V> previous) { modCount++; removeEntry(entry, hashIndex, previous); size--; destroyEntry(entry); } - + /** * Removes an entry from the chain stored in a particular index. * <p> * This implementation removes the entry from the data storage table. * The size is not updated. * Subclasses could override to handle changes to the map. - * + * * @param entry the entry to remove * @param hashIndex the index into the data structure * @param previous the previous entry in the chain */ - protected void removeEntry(HashEntry entry, int hashIndex, HashEntry previous) { + protected void removeEntry(HashEntry<K, V> entry, int hashIndex, HashEntry<K, V> previous) { if (previous == null) { data[hashIndex] = entry.next; } else { previous.next = entry.next; } } - + /** * Kills an entry ready for the garbage collector. * <p> * This implementation prepares the HashEntry for garbage collection. * Subclasses can override this to implement caching (override clear as well). - * + * * @param entry the entry to destroy */ - protected void destroyEntry(HashEntry entry) { + protected void destroyEntry(HashEntry<K, V> entry) { entry.next = null; entry.key = null; entry.value = null; } - + //----------------------------------------------------------------------- /** * Checks the capacity of the map and enlarges it if necessary. @@ -592,12 +593,13 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { } } } - + /** * Changes the size of the data structure to the capacity proposed. - * + * * @param newCapacity the new capacity of the array (a power of two, less or equal to max) */ + @SuppressWarnings("unchecked") protected void ensureCapacity(int newCapacity) { int oldCapacity = data.length; if (newCapacity <= oldCapacity) { @@ -617,7 +619,7 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { oldEntries[i] = null; // gc do { HashEntry next = entry.next; - int index = hashIndex(entry.hashCode, newCapacity); + int index = hashIndex(entry.hashCode, newCapacity); entry.next = newEntries[index]; newEntries[index] = entry; entry = next; @@ -632,7 +634,7 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { /** * Calculates the new capacity of the map. * This implementation normalizes the capacity to a power of two. - * + * * @param proposedCapacity the proposed capacity * @return the normalized new capacity */ @@ -650,11 +652,11 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { } return newCapacity; } - + /** * Calculates the new threshold of the map, where it will be resized. * This implementation uses the load factor. - * + * * @param newCapacity the new capacity * @param factor the load factor * @return the new resize threshold @@ -662,60 +664,60 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { protected int calculateThreshold(int newCapacity, float factor) { return (int) (newCapacity * factor); } - + //----------------------------------------------------------------------- /** * Gets the <code>next</code> field from a <code>HashEntry</code>. * Used in subclasses that have no visibility of the field. - * + * * @param entry the entry to query, must not be null * @return the <code>next</code> field of the entry * @throws NullPointerException if the entry is null * @since Commons Collections 3.1 */ - protected HashEntry entryNext(HashEntry entry) { + protected HashEntry<K, V> entryNext(HashEntry<K, V> entry) { return entry.next; } - + /** * Gets the <code>hashCode</code> field from a <code>HashEntry</code>. * Used in subclasses that have no visibility of the field. - * + * * @param entry the entry to query, must not be null * @return the <code>hashCode</code> field of the entry * @throws NullPointerException if the entry is null * @since Commons Collections 3.1 */ - protected int entryHashCode(HashEntry entry) { + protected int entryHashCode(HashEntry<K, V> entry) { return entry.hashCode; } - + /** * Gets the <code>key</code> field from a <code>HashEntry</code>. * Used in subclasses that have no visibility of the field. - * + * * @param entry the entry to query, must not be null * @return the <code>key</code> field of the entry * @throws NullPointerException if the entry is null * @since Commons Collections 3.1 */ - protected Object entryKey(HashEntry entry) { - return entry.key; + protected K entryKey(HashEntry<K, V> entry) { + return entry.getKey(); } - + /** * Gets the <code>value</code> field from a <code>HashEntry</code>. * Used in subclasses that have no visibility of the field. - * + * * @param entry the entry to query, must not be null * @return the <code>value</code> field of the entry * @throws NullPointerException if the entry is null * @since Commons Collections 3.1 */ - protected Object entryValue(HashEntry entry) { - return entry.value; + protected V entryValue(HashEntry<K, V> entry) { + return entry.getValue(); } - + //----------------------------------------------------------------------- /** * Gets an iterator over the map. @@ -725,90 +727,90 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { * methods to get the key and value, and set the value. * It avoids the need to create an entrySet/keySet/values object. * It also avoids creating the Map.Entry object. - * + * * @return the map iterator */ - public MapIterator mapIterator() { + public MapIterator<K, V> mapIterator() { if (size == 0) { - return EmptyMapIterator.INSTANCE; + return EmptyMapIterator.<K, V>getInstance(); } - return new HashMapIterator(this); + return new HashMapIterator<K, V>(this); } /** * MapIterator implementation. */ - protected static class HashMapIterator extends HashIterator implements MapIterator { - - protected HashMapIterator(AbstractHashedMap parent) { + protected static class HashMapIterator<K, V> extends HashIterator<K, V> implements MapIterator<K, V> { + + protected HashMapIterator(AbstractHashedMap<K, V> parent) { super(parent); } - public Object next() { + public K next() { return super.nextEntry().getKey(); } - public Object getKey() { - HashEntry current = currentEntry(); + public K getKey() { + HashEntry<K, V> current = currentEntry(); if (current == null) { throw new IllegalStateException(AbstractHashedMap.GETKEY_INVALID); } return current.getKey(); } - public Object getValue() { - HashEntry current = currentEntry(); + public V getValue() { + HashEntry<K, V> current = currentEntry(); if (current == null) { throw new IllegalStateException(AbstractHashedMap.GETVALUE_INVALID); } return current.getValue(); } - public Object setValue(Object value) { - HashEntry current = currentEntry(); + public V setValue(V value) { + HashEntry<K, V> current = currentEntry(); if (current == null) { throw new IllegalStateException(AbstractHashedMap.SETVALUE_INVALID); } return current.setValue(value); } } - - //----------------------------------------------------------------------- + + //----------------------------------------------------------------------- /** * Gets the entrySet view of the map. * Changes made to the view affect this map. * To simply iterate through the entries, use {@link #mapIterator()}. - * + * * @return the entrySet view */ - public Set entrySet() { + public Set<Map.Entry<K, V>> entrySet() { if (entrySet == null) { - entrySet = new EntrySet(this); + entrySet = new EntrySet<K, V>(this); } return entrySet; } - + /** * Creates an entry set iterator. * Subclasses can override this to return iterators with different properties. - * + * * @return the entrySet iterator */ - protected Iterator createEntrySetIterator() { + protected Iterator<Map.Entry<K, V>> createEntrySetIterator() { if (size() == 0) { - return EmptyIterator.INSTANCE; + return EmptyIterator.<Map.Entry<K, V>>getInstance(); } - return new EntrySetIterator(this); + return new EntrySetIterator<K, V>(this); } /** * EntrySet implementation. */ - protected static class EntrySet extends AbstractSet { + protected static class EntrySet<K, V> extends AbstractSet<Map.Entry<K, V>> { /** The parent map */ - protected final AbstractHashedMap parent; - - protected EntrySet(AbstractHashedMap parent) { + protected final AbstractHashedMap<K, V> parent; + + protected EntrySet(AbstractHashedMap<K, V> parent) { super(); this.parent = parent; } @@ -816,20 +818,20 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { public int size() { return parent.size(); } - + public void clear() { parent.clear(); } - + public boolean contains(Object entry) { if (entry instanceof Map.Entry) { - Map.Entry e = (Map.Entry) entry; - Entry match = parent.getEntry(e.getKey()); + Map.Entry<?, ?> e = (Map.Entry<?, ?>) entry; + Entry<K, V> match = parent.getEntry(e.getKey()); return (match != null && match.equals(e)); } return false; } - + public boolean remove(Object obj) { if (obj instanceof Map.Entry == false) { return false; @@ -837,13 +839,12 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { if (contains(obj) == false) { return false; } - Map.Entry entry = (Map.Entry) obj; - Object key = entry.getKey(); - parent.remove(key); + Map.Entry<?, ?> entry = (Map.Entry<?, ?>) obj; + parent.remove(entry.getKey()); return true; } - public Iterator iterator() { + public Iterator<Map.Entry<K, V>> iterator() { return parent.createEntrySetIterator(); } } @@ -851,28 +852,28 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { /** * EntrySet iterator. */ - protected static class EntrySetIterator extends HashIterator { - - protected EntrySetIterator(AbstractHashedMap parent) { + protected static class EntrySetIterator<K, V> extends HashIterator<K, V> implements Iterator<Map.Entry<K, V>> { + + protected EntrySetIterator(AbstractHashedMap<K, V> parent) { super(parent); } - public Object next() { + public Map.Entry<K, V> next() { return super.nextEntry(); } } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- /** * Gets the keySet view of the map. * Changes made to the view affect this map. * To simply iterate through the keys, use {@link #mapIterator()}. - * + * * @return the keySet view */ - public Set keySet() { + public Set<K> keySet() { if (keySet == null) { - keySet = new KeySet(this); + keySet = new KeySet<K>(this); } return keySet; } @@ -880,24 +881,24 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { /** * Creates a key set iterator. * Subclasses can override this to return iterators with different properties. - * + * * @return the keySet iterator */ - protected Iterator createKeySetIterator() { + protected Iterator<K> createKeySetIterator() { if (size() == 0) { - return EmptyIterator.INSTANCE; + return EmptyIterator.<K>getInstance(); } - return new KeySetIterator(this); + return new KeySetIterator<K>(this); } /** * KeySet implementation. */ - protected static class KeySet extends AbstractSet { + protected static class KeySet<K> extends AbstractSet<K> { /** The parent map */ - protected final AbstractHashedMap parent; - - protected KeySet(AbstractHashedMap parent) { + protected final AbstractHashedMap<K, ?> parent; + + protected KeySet(AbstractHashedMap<K, ?> parent) { super(); this.parent = parent; } @@ -905,22 +906,22 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { public int size() { return parent.size(); } - + public void clear() { parent.clear(); } - + public boolean contains(Object key) { return parent.containsKey(key); } - + public boolean remove(Object key) { boolean result = parent.containsKey(key); parent.remove(key); return result; } - public Iterator iterator() { + public Iterator<K> iterator() { return parent.createKeySetIterator(); } } @@ -928,28 +929,29 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { /** * KeySet iterator. */ - protected static class KeySetIterator extends EntrySetIterator { - - protected KeySetIterator(AbstractHashedMap parent) { - super(parent); + protected static class KeySetIterator<K> extends HashIterator<K, Object> implements Iterator<K> { + + @SuppressWarnings("unchecked") + protected KeySetIterator(AbstractHashedMap<K, ?> parent) { + super((AbstractHashedMap<K, Object>) parent); } - public Object next() { + public K next() { return super.nextEntry().getKey(); } } - - //----------------------------------------------------------------------- + + //----------------------------------------------------------------------- /** * Gets the values view of the map. * Changes made to the view affect this map. * To simply iterate through the values, use {@link #mapIterator()}. - * + * * @return the values view */ - public Collection values() { + public Collection<V> values() { if (values == null) { - values = new Values(this); + values = new Values<V>(this); } return values; } @@ -957,24 +959,24 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { /** * Creates a values iterator. * Subclasses can override this to return iterators with different properties. - * + * * @return the values iterator */ - protected Iterator createValuesIterator() { + protected Iterator<V> createValuesIterator() { if (size() == 0) { - return EmptyIterator.INSTANCE; + return EmptyIterator.<V>getInstance(); } - return new ValuesIterator(this); + return new ValuesIterator<V>(this); } /** * Values implementation. */ - protected static class Values extends AbstractCollection { + protected static class Values<V> extends AbstractCollection<V> { /** The parent map */ - protected final AbstractHashedMap parent; - - protected Values(AbstractHashedMap parent) { + protected final AbstractHashedMap<?, V> parent; + + protected Values(AbstractHashedMap<?, V> parent) { super(); this.parent = parent; } @@ -982,16 +984,16 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { public int size() { return parent.size(); } - + public void clear() { parent.clear(); } - + public boolean contains(Object value) { return parent.containsValue(value); } - - public Iterator iterator() { + + public Iterator<V> iterator() { return parent.createValuesIterator(); } } @@ -999,17 +1001,18 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { /** * Values iterator. */ - protected static class ValuesIterator extends HashIterator { - - protected ValuesIterator(AbstractHashedMap parent) { - super(parent); + protected static class ValuesIterator<V> extends HashIterator<Object, V> implements Iterator<V> { + + @SuppressWarnings("unchecked") + protected ValuesIterator(AbstractHashedMap<?, V> parent) { + super((AbstractHashedMap<Object, V>) parent); } - public Object next() { + public V next() { return super.nextEntry().getValue(); } } - + //----------------------------------------------------------------------- /** * HashEntry used to store the data. @@ -1019,38 +1022,44 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { * The <code>entryXxx()</code> methods on <code>AbstractHashedMap</code> exist * to provide the necessary access. */ - protected static class HashEntry implements Map.Entry, KeyValue { + protected static class HashEntry<K, V> implements Map.Entry<K, V>, KeyValue<K, V> { /** The next entry in the hash chain */ - protected HashEntry next; + protected HashEntry<K, V> next; /** The hash code of the key */ protected int hashCode; /** The key */ protected Object key; /** The value */ protected Object value; - - protected HashEntry(HashEntry next, int hashCode, Object key, Object value) { + + protected HashEntry(HashEntry<K, V> next, int hashCode, Object key, V value) { super(); this.next = next; this.hashCode = hashCode; this.key = key; this.value = value; } - - public Object getKey() { - return (key == NULL ? null : key); + + @SuppressWarnings("unchecked") + public K getKey() { + if (key == NULL) { + return null; + } + return (K) key; } - - public Object getValue() { - return value; + + @SuppressWarnings("unchecked") + public V getValue() { + return (V) value; } - - public Object setValue(Object value) { + + @SuppressWarnings("unchecked") + public V setValue(V value) { Object old = this.value; this.value = value; - return old; + return (V) old; } - + public boolean equals(Object obj) { if (obj == this) { return true; @@ -1058,44 +1067,44 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { if (obj instanceof Map.Entry == false) { return false; } - Map.Entry other = (Map.Entry) obj; + Map.Entry<?, ?> other = (Map.Entry<?, ?>) obj; return (getKey() == null ? other.getKey() == null : getKey().equals(other.getKey())) && (getValue() == null ? other.getValue() == null : getValue().equals(other.getValue())); } - + public int hashCode() { return (getKey() == null ? 0 : getKey().hashCode()) ^ - (getValue() == null ? 0 : getValue().hashCode()); + (getValue() == null ? 0 : getValue().hashCode()); } - + public String toString() { return new StringBuffer().append(getKey()).append('=').append(getValue()).toString(); } } - + /** * Base Iterator */ - protected static abstract class HashIterator implements Iterator { - + protected static abstract class HashIterator<K, V> { + /** The parent map */ - protected final AbstractHashedMap parent; + protected final AbstractHashedMap<K, V> parent; /** The current index into the array of buckets */ protected int hashIndex; /** The last returned entry */ - protected HashEntry last; + protected HashEntry<K, V> last; /** The next entry */ - protected HashEntry next; + protected HashEntry<K, V> next; /** The modification count expected */ protected int expectedModCount; - - protected HashIterator(AbstractHashedMap parent) { + + protected HashIterator(AbstractHashedMap<K, V> parent) { super(); this.parent = parent; - HashEntry[] data = parent.data; + HashEntry<K, V>[] data = parent.data; int i = data.length; - HashEntry next = null; + HashEntry<K, V> next = null; while (i > 0 && next == null) { next = data[--i]; } @@ -1108,17 +1117,17 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { return (next != null); } - protected HashEntry nextEntry() { + protected HashEntry<K, V> nextEntry() { if (parent.modCount != expectedModCount) { throw new ConcurrentModificationException(); } - HashEntry newCurrent = next; + HashEntry<K, V> newCurrent = next; if (newCurrent == null) { throw new NoSuchElementException(AbstractHashedMap.NO_NEXT_ENTRY); } - HashEntry[] data = parent.data; + HashEntry<K, V>[] data = parent.data; int i = hashIndex; - HashEntry n = newCurrent.next; + HashEntry<K, V> n = newCurrent.next; while (n == null && i > 0) { n = data[--i]; } @@ -1128,10 +1137,10 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { return newCurrent; } - protected HashEntry currentEntry() { + protected HashEntry<K, V> currentEntry() { return last; } - + public void remove() { if (last == null) { throw new IllegalStateException(AbstractHashedMap.REMOVE_INVALID); @@ -1147,12 +1156,11 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { public String toString() { if (last != null) { return "Iterator[" + last.getKey() + "=" + last.getValue() + "]"; - } else { - return "Iterator[]"; } + return "Iterator[]"; } } - + //----------------------------------------------------------------------- /** * Writes the map data to the stream. This method must be overridden if a @@ -1170,14 +1178,14 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { * Subclasses may override if they have a specific field that must be present * on read before this implementation will work. Generally, the read determines * what must be serialized here, if anything. - * + * * @param out the output stream */ protected void doWriteObject(ObjectOutputStream out) throws IOException { out.writeFloat(loadFactor); out.writeInt(data.length); out.writeInt(size); - for (MapIterator it = mapIterator(); it.hasNext();) { + for (MapIterator<K, V> it = mapIterator(); it.hasNext();) { out.writeObject(it.next()); out.writeObject(it.getValue()); } @@ -1198,9 +1206,10 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { * <p> * Subclasses may override if the subclass has a specific field that must be present * before <code>put()</code> or <code>calculateThreshold()</code> will work correctly. - * + * * @param in the input stream */ + @SuppressWarnings("unchecked") protected void doReadObject(ObjectInputStream in) throws IOException, ClassNotFoundException { loadFactor = in.readFloat(); int capacity = in.readInt(); @@ -1209,12 +1218,12 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { threshold = calculateThreshold(capacity, loadFactor); data = new HashEntry[capacity]; for (int i = 0; i < size; i++) { - Object key = in.readObject(); - Object value = in.readObject(); + K key = (K) in.readObject(); + V value = (V) in.readObject(); put(key, value); } } - + //----------------------------------------------------------------------- /** * Clones the map without cloning the keys or values. @@ -1224,9 +1233,10 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { * * @return a shallow clone */ - protected Object clone() { + @SuppressWarnings("unchecked") + protected AbstractHashedMap<K, V> clone() { try { - AbstractHashedMap cloned = (AbstractHashedMap) super.clone(); + AbstractHashedMap<K, V> cloned = (AbstractHashedMap<K, V>) super.clone(); cloned.data = new HashEntry[data.length]; cloned.entrySet = null; cloned.keySet = null; @@ -1236,18 +1246,18 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { cloned.init(); cloned.putAll(this); return cloned; - } catch (CloneNotSupportedException ex) { return null; // should never happen } } - + /** * Compares this map with another. - * + * * @param obj the object to compare to * @return true if equal */ + @SuppressWarnings("unchecked") public boolean equals(Object obj) { if (obj == this) { return true; @@ -1284,12 +1294,12 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { /** * Gets the standard Map hashCode. - * + * * @return the hash code defined in the Map interface */ public int hashCode() { int total = 0; - Iterator it = createEntrySetIterator(); + Iterator<Map.Entry<K, V>> it = createEntrySetIterator(); while (it.hasNext()) { total += it.next().hashCode(); } @@ -1298,7 +1308,7 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { /** * Gets the map as a String. - * + * * @return a string version of the map */ public String toString() { @@ -1308,11 +1318,11 @@ public class AbstractHashedMap extends AbstractMap implements IterableMap { StringBuffer buf = new StringBuffer(32 * size()); buf.append('{'); - MapIterator it = mapIterator(); + MapIterator<K, V> it = mapIterator(); boolean hasNext = it.hasNext(); while (hasNext) { - Object key = it.next(); - Object value = it.getValue(); + K key = it.next(); + V value = it.getValue(); buf.append(key == this ? "(this Map)" : key) .append('=') .append(value == this ? "(this Map)" : value);