Merged gcj-eclipse branch to trunk.
From-SVN: r120621
This commit is contained in:
@@ -0,0 +1 @@
|
||||
LocaleData.java
|
||||
@@ -1,5 +1,5 @@
|
||||
/* AbstractCollection.java -- Abstract implementation of most of Collection
|
||||
Copyright (C) 1998, 2000, 2001, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 2000, 2001, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -62,13 +62,16 @@ import java.lang.reflect.Array;
|
||||
* @author Original author unknown
|
||||
* @author Bryce McKinlay
|
||||
* @author Eric Blake (ebb9@email.byu.edu)
|
||||
* @author Tom Tromey (tromey@redhat.com)
|
||||
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
|
||||
* @see Collection
|
||||
* @see AbstractSet
|
||||
* @see AbstractList
|
||||
* @since 1.2
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public abstract class AbstractCollection implements Collection
|
||||
public abstract class AbstractCollection<E>
|
||||
implements Collection<E>, Iterable<E>
|
||||
{
|
||||
/**
|
||||
* The main constructor, for use by subclasses.
|
||||
@@ -84,7 +87,7 @@ public abstract class AbstractCollection implements Collection
|
||||
*
|
||||
* @return an iterator
|
||||
*/
|
||||
public abstract Iterator iterator();
|
||||
public abstract Iterator<E> iterator();
|
||||
|
||||
/**
|
||||
* Return the number of elements in this collection. If there are more than
|
||||
@@ -110,7 +113,7 @@ public abstract class AbstractCollection implements Collection
|
||||
* @throws IllegalArgumentException if some aspect of the object prevents
|
||||
* it from being added
|
||||
*/
|
||||
public boolean add(Object o)
|
||||
public boolean add(E o)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
@@ -138,9 +141,9 @@ public abstract class AbstractCollection implements Collection
|
||||
* collection doesn't allow null values.
|
||||
* @see #add(Object)
|
||||
*/
|
||||
public boolean addAll(Collection c)
|
||||
public boolean addAll(Collection<? extends E> c)
|
||||
{
|
||||
Iterator itr = c.iterator();
|
||||
Iterator<? extends E> itr = c.iterator();
|
||||
boolean modified = false;
|
||||
int pos = c.size();
|
||||
while (--pos >= 0)
|
||||
@@ -162,7 +165,7 @@ public abstract class AbstractCollection implements Collection
|
||||
*/
|
||||
public void clear()
|
||||
{
|
||||
Iterator itr = iterator();
|
||||
Iterator<E> itr = iterator();
|
||||
int pos = size();
|
||||
while (--pos >= 0)
|
||||
{
|
||||
@@ -184,7 +187,7 @@ public abstract class AbstractCollection implements Collection
|
||||
*/
|
||||
public boolean contains(Object o)
|
||||
{
|
||||
Iterator itr = iterator();
|
||||
Iterator<E> itr = iterator();
|
||||
int pos = size();
|
||||
while (--pos >= 0)
|
||||
if (equals(o, itr.next()))
|
||||
@@ -204,9 +207,9 @@ public abstract class AbstractCollection implements Collection
|
||||
* @throws NullPointerException if the given collection is null
|
||||
* @see #contains(Object)
|
||||
*/
|
||||
public boolean containsAll(Collection c)
|
||||
public boolean containsAll(Collection<?> c)
|
||||
{
|
||||
Iterator itr = c.iterator();
|
||||
Iterator<?> itr = c.iterator();
|
||||
int pos = c.size();
|
||||
while (--pos >= 0)
|
||||
if (!contains(itr.next()))
|
||||
@@ -247,7 +250,7 @@ public abstract class AbstractCollection implements Collection
|
||||
*/
|
||||
public boolean remove(Object o)
|
||||
{
|
||||
Iterator itr = iterator();
|
||||
Iterator<E> itr = iterator();
|
||||
int pos = size();
|
||||
while (--pos >= 0)
|
||||
if (equals(o, itr.next()))
|
||||
@@ -273,7 +276,7 @@ public abstract class AbstractCollection implements Collection
|
||||
* @throws NullPointerException if the collection, c, is null.
|
||||
* @see Iterator#remove()
|
||||
*/
|
||||
public boolean removeAll(Collection c)
|
||||
public boolean removeAll(Collection<?> c)
|
||||
{
|
||||
return removeAllInternal(c);
|
||||
}
|
||||
@@ -295,9 +298,9 @@ public abstract class AbstractCollection implements Collection
|
||||
* @see Iterator#remove()
|
||||
*/
|
||||
// Package visible for use throughout java.util.
|
||||
boolean removeAllInternal(Collection c)
|
||||
boolean removeAllInternal(Collection<?> c)
|
||||
{
|
||||
Iterator itr = iterator();
|
||||
Iterator<E> itr = iterator();
|
||||
boolean modified = false;
|
||||
int pos = size();
|
||||
while (--pos >= 0)
|
||||
@@ -324,7 +327,7 @@ public abstract class AbstractCollection implements Collection
|
||||
* @throws NullPointerException if the collection, c, is null.
|
||||
* @see Iterator#remove()
|
||||
*/
|
||||
public boolean retainAll(Collection c)
|
||||
public boolean retainAll(Collection<?> c)
|
||||
{
|
||||
return retainAllInternal(c);
|
||||
}
|
||||
@@ -347,9 +350,9 @@ public abstract class AbstractCollection implements Collection
|
||||
* @see Iterator#remove()
|
||||
*/
|
||||
// Package visible for use throughout java.util.
|
||||
boolean retainAllInternal(Collection c)
|
||||
boolean retainAllInternal(Collection<?> c)
|
||||
{
|
||||
Iterator itr = iterator();
|
||||
Iterator<E> itr = iterator();
|
||||
boolean modified = false;
|
||||
int pos = size();
|
||||
while (--pos >= 0)
|
||||
@@ -372,7 +375,7 @@ public abstract class AbstractCollection implements Collection
|
||||
*/
|
||||
public Object[] toArray()
|
||||
{
|
||||
Iterator itr = iterator();
|
||||
Iterator<E> itr = iterator();
|
||||
int size = size();
|
||||
Object[] a = new Object[size];
|
||||
for (int pos = 0; pos < size; pos++)
|
||||
@@ -402,19 +405,18 @@ public abstract class AbstractCollection implements Collection
|
||||
* @throws ArrayStoreException if the type of the array precludes holding
|
||||
* one of the elements of the Collection
|
||||
*/
|
||||
public Object[] toArray(Object[] a)
|
||||
public <T> T[] toArray(T[] a)
|
||||
{
|
||||
int size = size();
|
||||
if (a.length < size)
|
||||
a = (Object[]) Array.newInstance(a.getClass().getComponentType(),
|
||||
a = (T[]) Array.newInstance(a.getClass().getComponentType(),
|
||||
size);
|
||||
else if (a.length > size)
|
||||
a[size] = null;
|
||||
|
||||
Iterator itr = iterator();
|
||||
Iterator<E> itr = iterator();
|
||||
for (int pos = 0; pos < size; pos++)
|
||||
a[pos] = itr.next();
|
||||
|
||||
a[pos] = (T) (itr.next());
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* AbstractList.java -- Abstract implementation of most of List
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -68,7 +69,9 @@ package java.util;
|
||||
* @since 1.2
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public abstract class AbstractList extends AbstractCollection implements List
|
||||
public abstract class AbstractList<E>
|
||||
extends AbstractCollection<E>
|
||||
implements List<E>
|
||||
{
|
||||
/**
|
||||
* A count of the number of structural modifications that have been made to
|
||||
@@ -101,7 +104,7 @@ public abstract class AbstractList extends AbstractCollection implements List
|
||||
* @return the element at that position
|
||||
* @throws IndexOutOfBoundsException if index < 0 || index >= size()
|
||||
*/
|
||||
public abstract Object get(int index);
|
||||
public abstract E get(int index);
|
||||
|
||||
/**
|
||||
* Insert an element into the list at a given position (optional operation).
|
||||
@@ -123,7 +126,7 @@ public abstract class AbstractList extends AbstractCollection implements List
|
||||
* some other reason
|
||||
* @see #modCount
|
||||
*/
|
||||
public void add(int index, Object o)
|
||||
public void add(int index, E o)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
@@ -144,7 +147,7 @@ public abstract class AbstractList extends AbstractCollection implements List
|
||||
* some other reason
|
||||
* @see #add(int, Object)
|
||||
*/
|
||||
public boolean add(Object o)
|
||||
public boolean add(E o)
|
||||
{
|
||||
add(size(), o);
|
||||
return true;
|
||||
@@ -173,9 +176,9 @@ public abstract class AbstractList extends AbstractCollection implements List
|
||||
* @throws NullPointerException if the specified collection is null
|
||||
* @see #add(int, Object)
|
||||
*/
|
||||
public boolean addAll(int index, Collection c)
|
||||
public boolean addAll(int index, Collection<? extends E> c)
|
||||
{
|
||||
Iterator itr = c.iterator();
|
||||
Iterator<? extends E> itr = c.iterator();
|
||||
int size = c.size();
|
||||
for (int pos = size; pos > 0; pos--)
|
||||
add(index++, itr.next());
|
||||
@@ -227,7 +230,7 @@ public abstract class AbstractList extends AbstractCollection implements List
|
||||
if (size != ((List) o).size())
|
||||
return false;
|
||||
|
||||
Iterator itr1 = iterator();
|
||||
Iterator<E> itr1 = iterator();
|
||||
Iterator itr2 = ((List) o).iterator();
|
||||
|
||||
while (--size >= 0)
|
||||
@@ -259,7 +262,7 @@ while (i.hasNext())
|
||||
public int hashCode()
|
||||
{
|
||||
int hashCode = 1;
|
||||
Iterator itr = iterator();
|
||||
Iterator<E> itr = iterator();
|
||||
int pos = size();
|
||||
while (--pos >= 0)
|
||||
hashCode = 31 * hashCode + hashCode(itr.next());
|
||||
@@ -277,7 +280,7 @@ while (i.hasNext())
|
||||
*/
|
||||
public int indexOf(Object o)
|
||||
{
|
||||
ListIterator itr = listIterator();
|
||||
ListIterator<E> itr = listIterator();
|
||||
int size = size();
|
||||
for (int pos = 0; pos < size; pos++)
|
||||
if (equals(o, itr.next()))
|
||||
@@ -297,10 +300,10 @@ while (i.hasNext())
|
||||
* @return an Iterator over the elements of this list, in order
|
||||
* @see #modCount
|
||||
*/
|
||||
public Iterator iterator()
|
||||
public Iterator<E> iterator()
|
||||
{
|
||||
// Bah, Sun's implementation forbids using listIterator(0).
|
||||
return new Iterator()
|
||||
return new Iterator<E>()
|
||||
{
|
||||
private int pos = 0;
|
||||
private int size = size();
|
||||
@@ -342,7 +345,7 @@ while (i.hasNext())
|
||||
* @throws ConcurrentModificationException if the
|
||||
* list has been modified elsewhere.
|
||||
*/
|
||||
public Object next()
|
||||
public E next()
|
||||
{
|
||||
checkMod();
|
||||
if (pos == size)
|
||||
@@ -388,7 +391,7 @@ while (i.hasNext())
|
||||
public int lastIndexOf(Object o)
|
||||
{
|
||||
int pos = size();
|
||||
ListIterator itr = listIterator(pos);
|
||||
ListIterator<E> itr = listIterator(pos);
|
||||
while (--pos >= 0)
|
||||
if (equals(o, itr.previous()))
|
||||
return pos;
|
||||
@@ -402,7 +405,7 @@ while (i.hasNext())
|
||||
* @return a ListIterator over the elements of this list, in order, starting
|
||||
* at the beginning
|
||||
*/
|
||||
public ListIterator listIterator()
|
||||
public ListIterator<E> listIterator()
|
||||
{
|
||||
return listIterator(0);
|
||||
}
|
||||
@@ -425,13 +428,13 @@ while (i.hasNext())
|
||||
* @throws IndexOutOfBoundsException if index < 0 || index > size()
|
||||
* @see #modCount
|
||||
*/
|
||||
public ListIterator listIterator(final int index)
|
||||
public ListIterator<E> listIterator(final int index)
|
||||
{
|
||||
if (index < 0 || index > size())
|
||||
throw new IndexOutOfBoundsException("Index: " + index + ", Size:"
|
||||
+ size());
|
||||
|
||||
return new ListIterator()
|
||||
return new ListIterator<E>()
|
||||
{
|
||||
private int knownMod = modCount;
|
||||
private int position = index;
|
||||
@@ -485,7 +488,7 @@ while (i.hasNext())
|
||||
* @throws ConcurrentModificationException if the
|
||||
* list has been modified elsewhere.
|
||||
*/
|
||||
public Object next()
|
||||
public E next()
|
||||
{
|
||||
checkMod();
|
||||
if (position == size)
|
||||
@@ -503,7 +506,7 @@ while (i.hasNext())
|
||||
* @throws ConcurrentModificationException if the
|
||||
* list has been modified elsewhere.
|
||||
*/
|
||||
public Object previous()
|
||||
public E previous()
|
||||
{
|
||||
checkMod();
|
||||
if (position == 0)
|
||||
@@ -577,7 +580,7 @@ while (i.hasNext())
|
||||
* @throws ConcurrentModificationException if the list
|
||||
* has been modified elsewhere.
|
||||
*/
|
||||
public void set(Object o)
|
||||
public void set(E o)
|
||||
{
|
||||
checkMod();
|
||||
if (lastReturned < 0)
|
||||
@@ -599,7 +602,7 @@ while (i.hasNext())
|
||||
* @throws ConcurrentModificationException if the list
|
||||
* has been modified elsewhere.
|
||||
*/
|
||||
public void add(Object o)
|
||||
public void add(E o)
|
||||
{
|
||||
checkMod();
|
||||
AbstractList.this.add(position++, o);
|
||||
@@ -624,7 +627,7 @@ while (i.hasNext())
|
||||
* @throws IndexOutOfBoundsException if index < 0 || index >= size()
|
||||
* @see #modCount
|
||||
*/
|
||||
public Object remove(int index)
|
||||
public E remove(int index)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
@@ -650,7 +653,7 @@ while (i.hasNext())
|
||||
*/
|
||||
protected void removeRange(int fromIndex, int toIndex)
|
||||
{
|
||||
ListIterator itr = listIterator(fromIndex);
|
||||
ListIterator<E> itr = listIterator(fromIndex);
|
||||
for (int index = fromIndex; index < toIndex; index++)
|
||||
{
|
||||
itr.next();
|
||||
@@ -673,7 +676,7 @@ while (i.hasNext())
|
||||
* @throws IllegalArgumentException if o cannot be added to this list for
|
||||
* some other reason
|
||||
*/
|
||||
public Object set(int index, Object o)
|
||||
public E set(int index, E o)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
@@ -722,7 +725,7 @@ while (i.hasNext())
|
||||
* @see ConcurrentModificationException
|
||||
* @see RandomAccess
|
||||
*/
|
||||
public List subList(int fromIndex, int toIndex)
|
||||
public List<E> subList(int fromIndex, int toIndex)
|
||||
{
|
||||
// This follows the specification of AbstractList, but is inconsistent
|
||||
// with the one in List. Don't you love Sun's inconsistencies?
|
||||
@@ -732,8 +735,8 @@ while (i.hasNext())
|
||||
throw new IndexOutOfBoundsException();
|
||||
|
||||
if (this instanceof RandomAccess)
|
||||
return new RandomAccessSubList(this, fromIndex, toIndex);
|
||||
return new SubList(this, fromIndex, toIndex);
|
||||
return new RandomAccessSubList<E>(this, fromIndex, toIndex);
|
||||
return new SubList<E>(this, fromIndex, toIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -744,16 +747,16 @@ while (i.hasNext())
|
||||
* @author Original author unknown
|
||||
* @author Eric Blake (ebb9@email.byu.edu)
|
||||
*/
|
||||
private static class SubList extends AbstractList
|
||||
private static class SubList<E> extends AbstractList<E>
|
||||
{
|
||||
// Package visible, for use by iterator.
|
||||
/** The original list. */
|
||||
final AbstractList backingList;
|
||||
final AbstractList<E> backingList;
|
||||
/** The index of the first element of the sublist. */
|
||||
final int offset;
|
||||
/** The size of the sublist. */
|
||||
int size;
|
||||
|
||||
|
||||
/**
|
||||
* Construct the sublist.
|
||||
*
|
||||
@@ -761,14 +764,14 @@ while (i.hasNext())
|
||||
* @param fromIndex the lower bound, inclusive
|
||||
* @param toIndex the upper bound, exclusive
|
||||
*/
|
||||
SubList(AbstractList backing, int fromIndex, int toIndex)
|
||||
SubList(AbstractList<E> backing, int fromIndex, int toIndex)
|
||||
{
|
||||
backingList = backing;
|
||||
modCount = backing.modCount;
|
||||
offset = fromIndex;
|
||||
size = toIndex - fromIndex;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method checks the two modCount fields to ensure that there has
|
||||
* not been a concurrent modification, returning if all is okay.
|
||||
@@ -780,9 +783,9 @@ while (i.hasNext())
|
||||
void checkMod()
|
||||
{
|
||||
if (modCount != backingList.modCount)
|
||||
throw new ConcurrentModificationException();
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method checks that a value is between 0 and size (inclusive). If
|
||||
* it is not, an exception is thrown.
|
||||
@@ -794,10 +797,10 @@ while (i.hasNext())
|
||||
private void checkBoundsInclusive(int index)
|
||||
{
|
||||
if (index < 0 || index > size)
|
||||
throw new IndexOutOfBoundsException("Index: " + index + ", Size:"
|
||||
+ size);
|
||||
throw new IndexOutOfBoundsException("Index: " + index + ", Size:"
|
||||
+ size);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method checks that a value is between 0 (inclusive) and size
|
||||
* (exclusive). If it is not, an exception is thrown.
|
||||
@@ -809,10 +812,10 @@ while (i.hasNext())
|
||||
private void checkBoundsExclusive(int index)
|
||||
{
|
||||
if (index < 0 || index >= size)
|
||||
throw new IndexOutOfBoundsException("Index: " + index + ", Size:"
|
||||
+ size);
|
||||
throw new IndexOutOfBoundsException("Index: " + index + ", Size:"
|
||||
+ size);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specified by AbstractList.subList to return the private field size.
|
||||
*
|
||||
@@ -825,7 +828,7 @@ while (i.hasNext())
|
||||
checkMod();
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specified by AbstractList.subList to delegate to the backing list.
|
||||
*
|
||||
@@ -842,13 +845,13 @@ while (i.hasNext())
|
||||
* @throws IllegalArgumentException if o cannot be added to the backing list
|
||||
* for some other reason
|
||||
*/
|
||||
public Object set(int index, Object o)
|
||||
public E set(int index, E o)
|
||||
{
|
||||
checkMod();
|
||||
checkBoundsExclusive(index);
|
||||
return backingList.set(index + offset, o);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specified by AbstractList.subList to delegate to the backing list.
|
||||
*
|
||||
@@ -858,13 +861,13 @@ while (i.hasNext())
|
||||
* modified externally to this sublist
|
||||
* @throws IndexOutOfBoundsException if index < 0 || index >= size()
|
||||
*/
|
||||
public Object get(int index)
|
||||
public E get(int index)
|
||||
{
|
||||
checkMod();
|
||||
checkBoundsExclusive(index);
|
||||
return backingList.get(index + offset);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specified by AbstractList.subList to delegate to the backing list.
|
||||
*
|
||||
@@ -880,7 +883,7 @@ while (i.hasNext())
|
||||
* @throws IllegalArgumentException if o cannot be added to the backing
|
||||
* list for some other reason.
|
||||
*/
|
||||
public void add(int index, Object o)
|
||||
public void add(int index, E o)
|
||||
{
|
||||
checkMod();
|
||||
checkBoundsInclusive(index);
|
||||
@@ -888,7 +891,7 @@ while (i.hasNext())
|
||||
size++;
|
||||
modCount = backingList.modCount;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specified by AbstractList.subList to delegate to the backing list.
|
||||
*
|
||||
@@ -900,16 +903,16 @@ while (i.hasNext())
|
||||
* @throws UnsupportedOperationException if the backing list does not
|
||||
* support the remove operation
|
||||
*/
|
||||
public Object remove(int index)
|
||||
public E remove(int index)
|
||||
{
|
||||
checkMod();
|
||||
checkBoundsExclusive(index);
|
||||
Object o = backingList.remove(index + offset);
|
||||
E o = backingList.remove(index + offset);
|
||||
size--;
|
||||
modCount = backingList.modCount;
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specified by AbstractList.subList to delegate to the backing list.
|
||||
* This does no bounds checking, as it assumes it will only be called
|
||||
@@ -925,12 +928,12 @@ while (i.hasNext())
|
||||
protected void removeRange(int fromIndex, int toIndex)
|
||||
{
|
||||
checkMod();
|
||||
|
||||
|
||||
backingList.removeRange(offset + fromIndex, offset + toIndex);
|
||||
size -= toIndex - fromIndex;
|
||||
modCount = backingList.modCount;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specified by AbstractList.subList to delegate to the backing list.
|
||||
*
|
||||
@@ -948,7 +951,7 @@ while (i.hasNext())
|
||||
* to this list for some other reason
|
||||
* @throws NullPointerException if the specified collection is null
|
||||
*/
|
||||
public boolean addAll(int index, Collection c)
|
||||
public boolean addAll(int index, Collection<? extends E> c)
|
||||
{
|
||||
checkMod();
|
||||
checkBoundsInclusive(index);
|
||||
@@ -958,7 +961,7 @@ while (i.hasNext())
|
||||
modCount = backingList.modCount;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specified by AbstractList.subList to return addAll(size, c).
|
||||
*
|
||||
@@ -974,21 +977,21 @@ while (i.hasNext())
|
||||
* to this list for some other reason
|
||||
* @throws NullPointerException if the specified collection is null
|
||||
*/
|
||||
public boolean addAll(Collection c)
|
||||
public boolean addAll(Collection<? extends E> c)
|
||||
{
|
||||
return addAll(size, c);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specified by AbstractList.subList to return listIterator().
|
||||
*
|
||||
* @return an iterator over the sublist
|
||||
*/
|
||||
public Iterator iterator()
|
||||
public Iterator<E> iterator()
|
||||
{
|
||||
return listIterator();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specified by AbstractList.subList to return a wrapper around the
|
||||
* backing list's iterator.
|
||||
@@ -999,179 +1002,180 @@ while (i.hasNext())
|
||||
* modified externally to this sublist
|
||||
* @throws IndexOutOfBoundsException if the value is out of range
|
||||
*/
|
||||
public ListIterator listIterator(final int index)
|
||||
public ListIterator<E> listIterator(final int index)
|
||||
{
|
||||
checkMod();
|
||||
checkBoundsInclusive(index);
|
||||
|
||||
return new ListIterator<E>()
|
||||
{
|
||||
private final ListIterator<E> i
|
||||
= backingList.listIterator(index + offset);
|
||||
private int position = index;
|
||||
|
||||
/**
|
||||
* Tests to see if there are any more objects to
|
||||
* return.
|
||||
*
|
||||
* @return True if the end of the list has not yet been
|
||||
* reached.
|
||||
*/
|
||||
public boolean hasNext()
|
||||
{
|
||||
return position < size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests to see if there are objects prior to the
|
||||
* current position in the list.
|
||||
*
|
||||
* @return True if objects exist prior to the current
|
||||
* position of the iterator.
|
||||
*/
|
||||
public boolean hasPrevious()
|
||||
{
|
||||
return position > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next object from the list.
|
||||
*
|
||||
* @return The next object.
|
||||
* @throws NoSuchElementException if there are no
|
||||
* more objects to retrieve.
|
||||
* @throws ConcurrentModificationException if the
|
||||
* list has been modified elsewhere.
|
||||
*/
|
||||
public E next()
|
||||
{
|
||||
if (position == size)
|
||||
throw new NoSuchElementException();
|
||||
position++;
|
||||
return i.next();
|
||||
}
|
||||
|
||||
return new ListIterator()
|
||||
{
|
||||
private final ListIterator i = backingList.listIterator(index + offset);
|
||||
private int position = index;
|
||||
|
||||
/**
|
||||
* Tests to see if there are any more objects to
|
||||
* return.
|
||||
*
|
||||
* @return True if the end of the list has not yet been
|
||||
* reached.
|
||||
*/
|
||||
public boolean hasNext()
|
||||
{
|
||||
return position < size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests to see if there are objects prior to the
|
||||
* current position in the list.
|
||||
*
|
||||
* @return True if objects exist prior to the current
|
||||
* position of the iterator.
|
||||
*/
|
||||
public boolean hasPrevious()
|
||||
{
|
||||
return position > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next object from the list.
|
||||
*
|
||||
* @return The next object.
|
||||
* @throws NoSuchElementException if there are no
|
||||
* more objects to retrieve.
|
||||
* @throws ConcurrentModificationException if the
|
||||
* list has been modified elsewhere.
|
||||
*/
|
||||
public Object next()
|
||||
{
|
||||
if (position == size)
|
||||
throw new NoSuchElementException();
|
||||
position++;
|
||||
return i.next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the previous object from the list.
|
||||
*
|
||||
* @return The next object.
|
||||
* @throws NoSuchElementException if there are no
|
||||
* previous objects to retrieve.
|
||||
* @throws ConcurrentModificationException if the
|
||||
* list has been modified elsewhere.
|
||||
*/
|
||||
public Object previous()
|
||||
{
|
||||
if (position == 0)
|
||||
throw new NoSuchElementException();
|
||||
position--;
|
||||
return i.previous();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the next element in the
|
||||
* list, which will be retrieved by <code>next()</code>
|
||||
*
|
||||
* @return The index of the next element.
|
||||
*/
|
||||
public int nextIndex()
|
||||
{
|
||||
return i.nextIndex() - offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the previous element in the
|
||||
* list, which will be retrieved by <code>previous()</code>
|
||||
*
|
||||
* @return The index of the previous element.
|
||||
*/
|
||||
public int previousIndex()
|
||||
{
|
||||
return i.previousIndex() - offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the last object retrieved by <code>next()</code>
|
||||
* from the list, if the list supports object removal.
|
||||
*
|
||||
* @throws IllegalStateException if the iterator is positioned
|
||||
* before the start of the list or the last object has already
|
||||
* been removed.
|
||||
* @throws UnsupportedOperationException if the list does
|
||||
* not support removing elements.
|
||||
*/
|
||||
public void remove()
|
||||
{
|
||||
i.remove();
|
||||
size--;
|
||||
position = nextIndex();
|
||||
modCount = backingList.modCount;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replaces the last object retrieved by <code>next()</code>
|
||||
* or <code>previous</code> with o, if the list supports object
|
||||
* replacement and an add or remove operation has not already
|
||||
* been performed.
|
||||
*
|
||||
* @throws IllegalStateException if the iterator is positioned
|
||||
* before the start of the list or the last object has already
|
||||
* been removed.
|
||||
* @throws UnsupportedOperationException if the list doesn't support
|
||||
* the addition or removal of elements.
|
||||
* @throws ClassCastException if the type of o is not a valid type
|
||||
* for this list.
|
||||
* @throws IllegalArgumentException if something else related to o
|
||||
* prevents its addition.
|
||||
* @throws ConcurrentModificationException if the list
|
||||
* has been modified elsewhere.
|
||||
*/
|
||||
public void set(Object o)
|
||||
{
|
||||
i.set(o);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the supplied object before the element that would be returned
|
||||
* by a call to <code>next()</code>, if the list supports addition.
|
||||
*
|
||||
* @param o The object to add to the list.
|
||||
* @throws UnsupportedOperationException if the list doesn't support
|
||||
* the addition of new elements.
|
||||
* @throws ClassCastException if the type of o is not a valid type
|
||||
* for this list.
|
||||
* @throws IllegalArgumentException if something else related to o
|
||||
* prevents its addition.
|
||||
* @throws ConcurrentModificationException if the list
|
||||
* has been modified elsewhere.
|
||||
*/
|
||||
public void add(Object o)
|
||||
{
|
||||
i.add(o);
|
||||
size++;
|
||||
position++;
|
||||
modCount = backingList.modCount;
|
||||
}
|
||||
|
||||
// Here is the reason why the various modCount fields are mostly
|
||||
// ignored in this wrapper listIterator.
|
||||
// If the backing listIterator is failfast, then the following holds:
|
||||
// Using any other method on this list will call a corresponding
|
||||
// method on the backing list *after* the backing listIterator
|
||||
// is created, which will in turn cause a ConcurrentModException
|
||||
// when this listIterator comes to use the backing one. So it is
|
||||
// implicitly failfast.
|
||||
// If the backing listIterator is NOT failfast, then the whole of
|
||||
// this list isn't failfast, because the modCount field of the
|
||||
// backing list is not valid. It would still be *possible* to
|
||||
// make the iterator failfast wrt modifications of the sublist
|
||||
// only, but somewhat pointless when the list can be changed under
|
||||
// us.
|
||||
// Either way, no explicit handling of modCount is needed.
|
||||
// However modCount = backingList.modCount must be executed in add
|
||||
// and remove, and size must also be updated in these two methods,
|
||||
// since they do not go through the corresponding methods of the subList.
|
||||
};
|
||||
/**
|
||||
* Retrieves the previous object from the list.
|
||||
*
|
||||
* @return The next object.
|
||||
* @throws NoSuchElementException if there are no
|
||||
* previous objects to retrieve.
|
||||
* @throws ConcurrentModificationException if the
|
||||
* list has been modified elsewhere.
|
||||
*/
|
||||
public E previous()
|
||||
{
|
||||
if (position == 0)
|
||||
throw new NoSuchElementException();
|
||||
position--;
|
||||
return i.previous();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the next element in the
|
||||
* list, which will be retrieved by <code>next()</code>
|
||||
*
|
||||
* @return The index of the next element.
|
||||
*/
|
||||
public int nextIndex()
|
||||
{
|
||||
return i.nextIndex() - offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the previous element in the
|
||||
* list, which will be retrieved by <code>previous()</code>
|
||||
*
|
||||
* @return The index of the previous element.
|
||||
*/
|
||||
public int previousIndex()
|
||||
{
|
||||
return i.previousIndex() - offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the last object retrieved by <code>next()</code>
|
||||
* from the list, if the list supports object removal.
|
||||
*
|
||||
* @throws IllegalStateException if the iterator is positioned
|
||||
* before the start of the list or the last object has already
|
||||
* been removed.
|
||||
* @throws UnsupportedOperationException if the list does
|
||||
* not support removing elements.
|
||||
*/
|
||||
public void remove()
|
||||
{
|
||||
i.remove();
|
||||
size--;
|
||||
position = nextIndex();
|
||||
modCount = backingList.modCount;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replaces the last object retrieved by <code>next()</code>
|
||||
* or <code>previous</code> with o, if the list supports object
|
||||
* replacement and an add or remove operation has not already
|
||||
* been performed.
|
||||
*
|
||||
* @throws IllegalStateException if the iterator is positioned
|
||||
* before the start of the list or the last object has already
|
||||
* been removed.
|
||||
* @throws UnsupportedOperationException if the list doesn't support
|
||||
* the addition or removal of elements.
|
||||
* @throws ClassCastException if the type of o is not a valid type
|
||||
* for this list.
|
||||
* @throws IllegalArgumentException if something else related to o
|
||||
* prevents its addition.
|
||||
* @throws ConcurrentModificationException if the list
|
||||
* has been modified elsewhere.
|
||||
*/
|
||||
public void set(E o)
|
||||
{
|
||||
i.set(o);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the supplied object before the element that would be returned
|
||||
* by a call to <code>next()</code>, if the list supports addition.
|
||||
*
|
||||
* @param o The object to add to the list.
|
||||
* @throws UnsupportedOperationException if the list doesn't support
|
||||
* the addition of new elements.
|
||||
* @throws ClassCastException if the type of o is not a valid type
|
||||
* for this list.
|
||||
* @throws IllegalArgumentException if something else related to o
|
||||
* prevents its addition.
|
||||
* @throws ConcurrentModificationException if the list
|
||||
* has been modified elsewhere.
|
||||
*/
|
||||
public void add(E o)
|
||||
{
|
||||
i.add(o);
|
||||
size++;
|
||||
position++;
|
||||
modCount = backingList.modCount;
|
||||
}
|
||||
|
||||
// Here is the reason why the various modCount fields are mostly
|
||||
// ignored in this wrapper listIterator.
|
||||
// If the backing listIterator is failfast, then the following holds:
|
||||
// Using any other method on this list will call a corresponding
|
||||
// method on the backing list *after* the backing listIterator
|
||||
// is created, which will in turn cause a ConcurrentModException
|
||||
// when this listIterator comes to use the backing one. So it is
|
||||
// implicitly failfast.
|
||||
// If the backing listIterator is NOT failfast, then the whole of
|
||||
// this list isn't failfast, because the modCount field of the
|
||||
// backing list is not valid. It would still be *possible* to
|
||||
// make the iterator failfast wrt modifications of the sublist
|
||||
// only, but somewhat pointless when the list can be changed under
|
||||
// us.
|
||||
// Either way, no explicit handling of modCount is needed.
|
||||
// However modCount = backingList.modCount must be executed in add
|
||||
// and remove, and size must also be updated in these two methods,
|
||||
// since they do not go through the corresponding methods of the subList.
|
||||
};
|
||||
}
|
||||
} // class SubList
|
||||
|
||||
@@ -1181,7 +1185,7 @@ while (i.hasNext())
|
||||
*
|
||||
* @author Eric Blake (ebb9@email.byu.edu)
|
||||
*/
|
||||
private static final class RandomAccessSubList extends SubList
|
||||
private static final class RandomAccessSubList<E> extends SubList<E>
|
||||
implements RandomAccess
|
||||
{
|
||||
/**
|
||||
@@ -1191,10 +1195,10 @@ while (i.hasNext())
|
||||
* @param fromIndex the lower bound, inclusive
|
||||
* @param toIndex the upper bound, exclusive
|
||||
*/
|
||||
RandomAccessSubList(AbstractList backing, int fromIndex, int toIndex)
|
||||
RandomAccessSubList(AbstractList<E> backing, int fromIndex, int toIndex)
|
||||
{
|
||||
super(backing, fromIndex, toIndex);
|
||||
}
|
||||
} // class RandomAccessSubList
|
||||
|
||||
|
||||
} // class AbstractList
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* AbstractMap.java -- Abstract implementation of most of Map
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -38,6 +39,8 @@ exception statement from your version. */
|
||||
|
||||
package java.util;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* An abstract implementation of Map to make it easier to create your own
|
||||
* implementations. In order to create an unmodifiable Map, subclass
|
||||
@@ -64,9 +67,43 @@ package java.util;
|
||||
* @since 1.2
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public abstract class AbstractMap implements Map
|
||||
public abstract class AbstractMap<K, V> implements Map<K, V>
|
||||
{
|
||||
/** An "enum" of iterator types. */
|
||||
/** @since 1.6 */
|
||||
public static class SimpleImmutableEntry<K, V>
|
||||
implements Entry<K, V>, Serializable
|
||||
{
|
||||
K key;
|
||||
V value;
|
||||
|
||||
public SimpleImmutableEntry(K key, V value)
|
||||
{
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public SimpleImmutableEntry(Entry<? extends K, ? extends V> entry)
|
||||
{
|
||||
this(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
public K getKey()
|
||||
{
|
||||
return key;
|
||||
}
|
||||
|
||||
public V getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public V setValue(V value)
|
||||
{
|
||||
throw new UnsupportedOperationException("setValue not supported on immutable entry");
|
||||
}
|
||||
}
|
||||
|
||||
/** An "enum" of iterator types. */
|
||||
// Package visible for use by subclasses.
|
||||
static final int KEYS = 0,
|
||||
VALUES = 1,
|
||||
@@ -76,13 +113,13 @@ public abstract class AbstractMap implements Map
|
||||
* The cache for {@link #keySet()}.
|
||||
*/
|
||||
// Package visible for use by subclasses.
|
||||
Set keys;
|
||||
Set<K> keys;
|
||||
|
||||
/**
|
||||
* The cache for {@link #values()}.
|
||||
*/
|
||||
// Package visible for use by subclasses.
|
||||
Collection values;
|
||||
Collection<V> values;
|
||||
|
||||
/**
|
||||
* The main constructor, for use by subclasses.
|
||||
@@ -104,7 +141,7 @@ public abstract class AbstractMap implements Map
|
||||
* @return the entry set
|
||||
* @see Map.Entry
|
||||
*/
|
||||
public abstract Set entrySet();
|
||||
public abstract Set<Map.Entry<K, V>> entrySet();
|
||||
|
||||
/**
|
||||
* Remove all entries from this Map (optional operation). This default
|
||||
@@ -133,7 +170,7 @@ public abstract class AbstractMap implements Map
|
||||
*/
|
||||
protected Object clone() throws CloneNotSupportedException
|
||||
{
|
||||
AbstractMap copy = (AbstractMap) super.clone();
|
||||
AbstractMap<K, V> copy = (AbstractMap<K, V>) super.clone();
|
||||
// Clear out the caches; they are stale.
|
||||
copy.keys = null;
|
||||
copy.values = null;
|
||||
@@ -155,10 +192,10 @@ public abstract class AbstractMap implements Map
|
||||
*/
|
||||
public boolean containsKey(Object key)
|
||||
{
|
||||
Iterator entries = entrySet().iterator();
|
||||
Iterator<Map.Entry<K, V>> entries = entrySet().iterator();
|
||||
int pos = size();
|
||||
while (--pos >= 0)
|
||||
if (equals(key, ((Map.Entry) entries.next()).getKey()))
|
||||
if (equals(key, entries.next().getKey()))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -178,10 +215,10 @@ public abstract class AbstractMap implements Map
|
||||
*/
|
||||
public boolean containsValue(Object value)
|
||||
{
|
||||
Iterator entries = entrySet().iterator();
|
||||
Iterator<Map.Entry<K, V>> entries = entrySet().iterator();
|
||||
int pos = size();
|
||||
while (--pos >= 0)
|
||||
if (equals(value, ((Map.Entry) entries.next()).getValue()))
|
||||
if (equals(value, entries.next().getValue()))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -198,9 +235,9 @@ public abstract class AbstractMap implements Map
|
||||
*/
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
return (o == this ||
|
||||
(o instanceof Map &&
|
||||
entrySet().equals(((Map) o).entrySet())));
|
||||
return (o == this
|
||||
|| (o instanceof Map
|
||||
&& entrySet().equals(((Map<K, V>) o).entrySet())));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -215,13 +252,13 @@ public abstract class AbstractMap implements Map
|
||||
* @throws NullPointerException if this map does not accept null keys
|
||||
* @see #containsKey(Object)
|
||||
*/
|
||||
public Object get(Object key)
|
||||
public V get(Object key)
|
||||
{
|
||||
Iterator entries = entrySet().iterator();
|
||||
Iterator<Map.Entry<K, V>> entries = entrySet().iterator();
|
||||
int pos = size();
|
||||
while (--pos >= 0)
|
||||
{
|
||||
Map.Entry entry = (Map.Entry) entries.next();
|
||||
Map.Entry<K, V> entry = entries.next();
|
||||
if (equals(key, entry.getKey()))
|
||||
return entry.getValue();
|
||||
}
|
||||
@@ -273,10 +310,10 @@ public abstract class AbstractMap implements Map
|
||||
* @see #containsKey(Object)
|
||||
* @see #values()
|
||||
*/
|
||||
public Set keySet()
|
||||
public Set<K> keySet()
|
||||
{
|
||||
if (keys == null)
|
||||
keys = new AbstractSet()
|
||||
keys = new AbstractSet<K>()
|
||||
{
|
||||
/**
|
||||
* Retrieves the number of keys in the backing map.
|
||||
@@ -294,7 +331,7 @@ public abstract class AbstractMap implements Map
|
||||
*
|
||||
* @param key The key to search for.
|
||||
* @return True if the key was found, false otherwise.
|
||||
*/
|
||||
*/
|
||||
public boolean contains(Object key)
|
||||
{
|
||||
return containsKey(key);
|
||||
@@ -307,14 +344,15 @@ public abstract class AbstractMap implements Map
|
||||
*
|
||||
* @return An iterator over the keys.
|
||||
*/
|
||||
public Iterator iterator()
|
||||
public Iterator<K> iterator()
|
||||
{
|
||||
return new Iterator()
|
||||
return new Iterator<K>()
|
||||
{
|
||||
/**
|
||||
* The iterator returned by <code>entrySet()</code>.
|
||||
*/
|
||||
private final Iterator map_iterator = entrySet().iterator();
|
||||
private final Iterator<Map.Entry<K, V>> map_iterator
|
||||
= entrySet().iterator();
|
||||
|
||||
/**
|
||||
* Returns true if a call to <code>next()</code> will
|
||||
@@ -333,10 +371,10 @@ public abstract class AbstractMap implements Map
|
||||
* by the underlying <code>entrySet()</code> iterator.
|
||||
*
|
||||
* @return The next key.
|
||||
*/
|
||||
public Object next()
|
||||
*/
|
||||
public K next()
|
||||
{
|
||||
return ((Map.Entry) map_iterator.next()).getKey();
|
||||
return map_iterator.next().getKey();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -374,7 +412,7 @@ public abstract class AbstractMap implements Map
|
||||
* @throws NullPointerException if the map forbids null keys or values
|
||||
* @see #containsKey(Object)
|
||||
*/
|
||||
public Object put(Object key, Object value)
|
||||
public V put(K key, V value)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
@@ -396,13 +434,16 @@ public abstract class AbstractMap implements Map
|
||||
* @throws NullPointerException if <code>m</code> is null.
|
||||
* @see #put(Object, Object)
|
||||
*/
|
||||
public void putAll(Map m)
|
||||
public void putAll(Map<? extends K, ? extends V> m)
|
||||
{
|
||||
Iterator entries = m.entrySet().iterator();
|
||||
// FIXME: bogus circumlocution.
|
||||
Iterator entries2 = m.entrySet().iterator();
|
||||
Iterator<Map.Entry<? extends K, ? extends V>> entries
|
||||
= (Iterator<Map.Entry<? extends K, ? extends V>>) entries2;
|
||||
int pos = m.size();
|
||||
while (--pos >= 0)
|
||||
{
|
||||
Map.Entry entry = (Map.Entry) entries.next();
|
||||
Map.Entry<? extends K, ? extends V> entry = entries.next();
|
||||
put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
@@ -424,17 +465,17 @@ public abstract class AbstractMap implements Map
|
||||
* @throws UnsupportedOperationException if deletion is unsupported
|
||||
* @see Iterator#remove()
|
||||
*/
|
||||
public Object remove(Object key)
|
||||
public V remove(Object key)
|
||||
{
|
||||
Iterator entries = entrySet().iterator();
|
||||
Iterator<Map.Entry<K, V>> entries = entrySet().iterator();
|
||||
int pos = size();
|
||||
while (--pos >= 0)
|
||||
{
|
||||
Map.Entry entry = (Map.Entry) entries.next();
|
||||
Map.Entry<K, V> entry = entries.next();
|
||||
if (equals(key, entry.getKey()))
|
||||
{
|
||||
// Must get the value before we remove it from iterator.
|
||||
Object r = entry.getValue();
|
||||
V r = entry.getValue();
|
||||
entries.remove();
|
||||
return r;
|
||||
}
|
||||
@@ -469,11 +510,11 @@ public abstract class AbstractMap implements Map
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
Iterator entries = entrySet().iterator();
|
||||
Iterator<Map.Entry<K, V>> entries = entrySet().iterator();
|
||||
StringBuffer r = new StringBuffer("{");
|
||||
for (int pos = size(); pos > 0; pos--)
|
||||
{
|
||||
Map.Entry entry = (Map.Entry) entries.next();
|
||||
Map.Entry<K, V> entry = entries.next();
|
||||
r.append(entry.getKey());
|
||||
r.append('=');
|
||||
r.append(entry.getValue());
|
||||
@@ -504,18 +545,18 @@ public abstract class AbstractMap implements Map
|
||||
* @see #containsValue(Object)
|
||||
* @see #keySet()
|
||||
*/
|
||||
public Collection values()
|
||||
public Collection<V> values()
|
||||
{
|
||||
if (values == null)
|
||||
values = new AbstractCollection()
|
||||
values = new AbstractCollection<V>()
|
||||
{
|
||||
/**
|
||||
/**
|
||||
* Returns the number of values stored in
|
||||
* the backing map.
|
||||
*
|
||||
* @return The number of values.
|
||||
*/
|
||||
public int size()
|
||||
public int size()
|
||||
{
|
||||
return AbstractMap.this.size();
|
||||
}
|
||||
@@ -539,46 +580,47 @@ public abstract class AbstractMap implements Map
|
||||
*
|
||||
* @return An iterator over the values.
|
||||
*/
|
||||
public Iterator iterator()
|
||||
public Iterator<V> iterator()
|
||||
{
|
||||
return new Iterator()
|
||||
return new Iterator<V>()
|
||||
{
|
||||
/**
|
||||
* The iterator returned by <code>entrySet()</code>.
|
||||
*/
|
||||
private final Iterator map_iterator = entrySet().iterator();
|
||||
private final Iterator<Map.Entry<K, V>> map_iterator
|
||||
= entrySet().iterator();
|
||||
|
||||
/**
|
||||
* Returns true if a call to <code>next()</call> will
|
||||
* return another value.
|
||||
*
|
||||
* @return True if the iterator has not yet reached
|
||||
* the last value.
|
||||
*/
|
||||
/**
|
||||
* Returns true if a call to <code>next()</call> will
|
||||
* return another value.
|
||||
*
|
||||
* @return True if the iterator has not yet reached
|
||||
* the last value.
|
||||
*/
|
||||
public boolean hasNext()
|
||||
{
|
||||
return map_iterator.hasNext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value from the next entry retrieved
|
||||
* by the underlying <code>entrySet()</code> iterator.
|
||||
*
|
||||
* @return The next value.
|
||||
*/
|
||||
public Object next()
|
||||
/**
|
||||
* Returns the value from the next entry retrieved
|
||||
* by the underlying <code>entrySet()</code> iterator.
|
||||
*
|
||||
* @return The next value.
|
||||
*/
|
||||
public V next()
|
||||
{
|
||||
return ((Map.Entry) map_iterator.next()).getValue();
|
||||
return map_iterator.next().getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the map entry which has a key equal
|
||||
* to that returned by the last call to
|
||||
* <code>next()</code>.
|
||||
*
|
||||
* @throws UnsupportedOperationException if the
|
||||
* map doesn't support removal.
|
||||
*/
|
||||
/**
|
||||
* Removes the map entry which has a key equal
|
||||
* to that returned by the last call to
|
||||
* <code>next()</code>.
|
||||
*
|
||||
* @throws UnsupportedOperationException if the
|
||||
* map doesn't support removal.
|
||||
*/
|
||||
public void remove()
|
||||
{
|
||||
map_iterator.remove();
|
||||
@@ -623,31 +665,36 @@ public abstract class AbstractMap implements Map
|
||||
*
|
||||
* @author Jon Zeppieri
|
||||
* @author Eric Blake (ebb9@email.byu.edu)
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
// XXX - FIXME Use fully qualified implements as gcj 3.1 workaround.
|
||||
// Bug still exists in 3.4.1
|
||||
static class BasicMapEntry implements Map.Entry
|
||||
public static class SimpleEntry<K, V> implements Entry<K, V>, Serializable
|
||||
{
|
||||
/**
|
||||
* The key. Package visible for direct manipulation.
|
||||
*/
|
||||
Object key;
|
||||
K key;
|
||||
|
||||
/**
|
||||
* The value. Package visible for direct manipulation.
|
||||
*/
|
||||
Object value;
|
||||
V value;
|
||||
|
||||
/**
|
||||
* Basic constructor initializes the fields.
|
||||
* @param newKey the key
|
||||
* @param newValue the value
|
||||
*/
|
||||
BasicMapEntry(Object newKey, Object newValue)
|
||||
public SimpleEntry(K newKey, V newValue)
|
||||
{
|
||||
key = newKey;
|
||||
value = newValue;
|
||||
}
|
||||
|
||||
public SimpleEntry(Entry<? extends K, ? extends V> entry)
|
||||
{
|
||||
this(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the specified object with this entry. Returns true only if
|
||||
@@ -662,14 +709,14 @@ public abstract class AbstractMap implements Map
|
||||
* @param o the object to compare
|
||||
* @return <code>true</code> if it is equal
|
||||
*/
|
||||
public final boolean equals(Object o)
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (! (o instanceof Map.Entry))
|
||||
return false;
|
||||
// Optimize for our own entries.
|
||||
if (o instanceof BasicMapEntry)
|
||||
if (o instanceof SimpleEntry)
|
||||
{
|
||||
BasicMapEntry e = (BasicMapEntry) o;
|
||||
SimpleEntry e = (SimpleEntry) o;
|
||||
return (AbstractMap.equals(key, e.key)
|
||||
&& AbstractMap.equals(value, e.value));
|
||||
}
|
||||
@@ -683,7 +730,7 @@ public abstract class AbstractMap implements Map
|
||||
*
|
||||
* @return the key
|
||||
*/
|
||||
public final Object getKey()
|
||||
public final K getKey()
|
||||
{
|
||||
return key;
|
||||
}
|
||||
@@ -694,7 +741,7 @@ public abstract class AbstractMap implements Map
|
||||
*
|
||||
* @return the value
|
||||
*/
|
||||
public final Object getValue()
|
||||
public final V getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
@@ -728,9 +775,9 @@ public abstract class AbstractMap implements Map
|
||||
* @throws IllegalArgumentException if something else about this
|
||||
* value prevents it being stored in the map.
|
||||
*/
|
||||
public Object setValue(Object newVal)
|
||||
public V setValue(V newVal)
|
||||
{
|
||||
Object r = value;
|
||||
V r = value;
|
||||
value = newVal;
|
||||
return r;
|
||||
}
|
||||
@@ -745,5 +792,7 @@ public abstract class AbstractMap implements Map
|
||||
{
|
||||
return key + "=" + value;
|
||||
}
|
||||
} // class BasicMapEntry
|
||||
} // class SimpleEntry
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* AbstractSequentialList.java -- List implementation for sequential access
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -71,7 +71,7 @@ package java.util;
|
||||
* @since 1.2
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public abstract class AbstractSequentialList extends AbstractList
|
||||
public abstract class AbstractSequentialList<E> extends AbstractList<E>
|
||||
{
|
||||
/**
|
||||
* The main constructor, for use by subclasses.
|
||||
@@ -88,7 +88,7 @@ public abstract class AbstractSequentialList extends AbstractList
|
||||
* @return the list iterator
|
||||
* @throws IndexOutOfBoundsException if index < 0 || index > size()
|
||||
*/
|
||||
public abstract ListIterator listIterator(int index);
|
||||
public abstract ListIterator<E> listIterator(int index);
|
||||
|
||||
/**
|
||||
* Insert an element into the list at a given position (optional operation).
|
||||
@@ -109,7 +109,7 @@ public abstract class AbstractSequentialList extends AbstractList
|
||||
* @throws NullPointerException if o is null and the list does not permit
|
||||
* the addition of null values.
|
||||
*/
|
||||
public void add(int index, Object o)
|
||||
public void add(int index, E o)
|
||||
{
|
||||
listIterator(index).add(o);
|
||||
}
|
||||
@@ -143,11 +143,11 @@ public abstract class AbstractSequentialList extends AbstractList
|
||||
* does not permit the addition of null values.
|
||||
* @see #add(int, Object)
|
||||
*/
|
||||
public boolean addAll(int index, Collection c)
|
||||
public boolean addAll(int index, Collection<? extends E> c)
|
||||
{
|
||||
Iterator ci = c.iterator();
|
||||
Iterator<? extends E> ci = c.iterator();
|
||||
int size = c.size();
|
||||
ListIterator i = listIterator(index);
|
||||
ListIterator<E> i = listIterator(index);
|
||||
for (int pos = size; pos > 0; pos--)
|
||||
i.add(ci.next());
|
||||
return size > 0;
|
||||
@@ -161,7 +161,7 @@ public abstract class AbstractSequentialList extends AbstractList
|
||||
* @return the element at index index in this list
|
||||
* @throws IndexOutOfBoundsException if index < 0 || index >= size()
|
||||
*/
|
||||
public Object get(int index)
|
||||
public E get(int index)
|
||||
{
|
||||
// This is a legal listIterator position, but an illegal get.
|
||||
if (index == size())
|
||||
@@ -176,7 +176,7 @@ public abstract class AbstractSequentialList extends AbstractList
|
||||
*
|
||||
* @return an Iterator over the elements of this list, in order
|
||||
*/
|
||||
public Iterator iterator()
|
||||
public Iterator<E> iterator()
|
||||
{
|
||||
return listIterator();
|
||||
}
|
||||
@@ -192,14 +192,14 @@ public abstract class AbstractSequentialList extends AbstractList
|
||||
* remove operation
|
||||
* @throws IndexOutOfBoundsException if index < 0 || index >= size()
|
||||
*/
|
||||
public Object remove(int index)
|
||||
public E remove(int index)
|
||||
{
|
||||
// This is a legal listIterator position, but an illegal remove.
|
||||
if (index == size())
|
||||
throw new IndexOutOfBoundsException("Index: " + index + ", Size:"
|
||||
+ size());
|
||||
ListIterator i = listIterator(index);
|
||||
Object removed = i.next();
|
||||
ListIterator<E> i = listIterator(index);
|
||||
E removed = i.next();
|
||||
i.remove();
|
||||
return removed;
|
||||
}
|
||||
@@ -221,14 +221,14 @@ public abstract class AbstractSequentialList extends AbstractList
|
||||
* @throws NullPointerException if o is null and the list does not allow
|
||||
* a value to be set to null.
|
||||
*/
|
||||
public Object set(int index, Object o)
|
||||
public E set(int index, E o)
|
||||
{
|
||||
// This is a legal listIterator position, but an illegal set.
|
||||
if (index == size())
|
||||
throw new IndexOutOfBoundsException("Index: " + index + ", Size:"
|
||||
+ size());
|
||||
ListIterator i = listIterator(index);
|
||||
Object old = i.next();
|
||||
ListIterator<E> i = listIterator(index);
|
||||
E old = i.next();
|
||||
i.set(o);
|
||||
return old;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* AbstractSet.java -- Abstract implementation of most of Set
|
||||
Copyright (C) 1998, 2000, 2001, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 2000, 2001, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -58,7 +59,9 @@ package java.util;
|
||||
* @since 1.2
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public abstract class AbstractSet extends AbstractCollection implements Set
|
||||
public abstract class AbstractSet<E>
|
||||
extends AbstractCollection<E>
|
||||
implements Set<E>
|
||||
{
|
||||
/**
|
||||
* The main constructor, for use by subclasses.
|
||||
@@ -79,9 +82,9 @@ public abstract class AbstractSet extends AbstractCollection implements Set
|
||||
*/
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
return (o == this ||
|
||||
(o instanceof Set && ((Set) o).size() == size()
|
||||
&& containsAll((Collection) o)));
|
||||
return (o == this
|
||||
|| (o instanceof Set && ((Set) o).size() == size()
|
||||
&& containsAll((Collection) o)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,7 +97,7 @@ public abstract class AbstractSet extends AbstractCollection implements Set
|
||||
*/
|
||||
public int hashCode()
|
||||
{
|
||||
Iterator itr = iterator();
|
||||
Iterator<E> itr = iterator();
|
||||
int hash = 0;
|
||||
int pos = size();
|
||||
while (--pos >= 0)
|
||||
@@ -119,21 +122,25 @@ public abstract class AbstractSet extends AbstractCollection implements Set
|
||||
* @see Collection#contains(Object)
|
||||
* @see Iterator#remove()
|
||||
*/
|
||||
public boolean removeAll(Collection c)
|
||||
public boolean removeAll(Collection<?> c)
|
||||
{
|
||||
int oldsize = size();
|
||||
int count = c.size();
|
||||
Iterator i;
|
||||
if (oldsize < count)
|
||||
{
|
||||
Iterator<E> i;
|
||||
for (i = iterator(), count = oldsize; count > 0; count--)
|
||||
if (c.contains(i.next()))
|
||||
i.remove();
|
||||
{
|
||||
if (c.contains(i.next()))
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
else
|
||||
for (i = c.iterator(); count > 0; count--)
|
||||
remove(i.next());
|
||||
{
|
||||
Iterator<?> i;
|
||||
for (i = c.iterator(); count > 0; count--)
|
||||
remove(i.next());
|
||||
}
|
||||
return oldsize != size();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -81,8 +81,8 @@ import java.lang.reflect.Array;
|
||||
* @see AbstractList
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public class ArrayList extends AbstractList
|
||||
implements List, RandomAccess, Cloneable, Serializable
|
||||
public class ArrayList<E> extends AbstractList<E>
|
||||
implements List<E>, RandomAccess, Cloneable, Serializable
|
||||
{
|
||||
/**
|
||||
* Compatible with JDK 1.2
|
||||
@@ -103,7 +103,7 @@ public class ArrayList extends AbstractList
|
||||
/**
|
||||
* Where the data is stored.
|
||||
*/
|
||||
private transient Object[] data;
|
||||
private transient E[] data;
|
||||
|
||||
/**
|
||||
* Construct a new ArrayList with the supplied initial capacity.
|
||||
@@ -116,7 +116,7 @@ public class ArrayList extends AbstractList
|
||||
// Must explicitly check, to get correct exception.
|
||||
if (capacity < 0)
|
||||
throw new IllegalArgumentException();
|
||||
data = new Object[capacity];
|
||||
data = (E[]) new Object[capacity];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,7 +135,7 @@ public class ArrayList extends AbstractList
|
||||
* @param c the collection whose elements will initialize this list
|
||||
* @throws NullPointerException if c is null
|
||||
*/
|
||||
public ArrayList(Collection c)
|
||||
public ArrayList(Collection<? extends E> c)
|
||||
{
|
||||
this((int) (c.size() * 1.1f));
|
||||
addAll(c);
|
||||
@@ -151,7 +151,7 @@ public class ArrayList extends AbstractList
|
||||
// so don't update modCount.
|
||||
if (size != data.length)
|
||||
{
|
||||
Object[] newData = new Object[size];
|
||||
E[] newData = (E[]) new Object[size];
|
||||
System.arraycopy(data, 0, newData, 0, size);
|
||||
data = newData;
|
||||
}
|
||||
@@ -173,7 +173,7 @@ public class ArrayList extends AbstractList
|
||||
|
||||
if (minCapacity > current)
|
||||
{
|
||||
Object[] newData = new Object[Math.max(current * 2, minCapacity)];
|
||||
E[] newData = (E[]) new Object[Math.max(current * 2, minCapacity)];
|
||||
System.arraycopy(data, 0, newData, 0, size);
|
||||
data = newData;
|
||||
}
|
||||
@@ -247,11 +247,11 @@ public class ArrayList extends AbstractList
|
||||
*/
|
||||
public Object clone()
|
||||
{
|
||||
ArrayList clone = null;
|
||||
ArrayList<E> clone = null;
|
||||
try
|
||||
{
|
||||
clone = (ArrayList) super.clone();
|
||||
clone.data = (Object[]) data.clone();
|
||||
clone = (ArrayList<E>) super.clone();
|
||||
clone.data = (E[]) data.clone();
|
||||
}
|
||||
catch (CloneNotSupportedException e)
|
||||
{
|
||||
@@ -268,7 +268,7 @@ public class ArrayList extends AbstractList
|
||||
*/
|
||||
public Object[] toArray()
|
||||
{
|
||||
Object[] array = new Object[size];
|
||||
E[] array = (E[]) new Object[size];
|
||||
System.arraycopy(data, 0, array, 0, size);
|
||||
return array;
|
||||
}
|
||||
@@ -287,11 +287,10 @@ public class ArrayList extends AbstractList
|
||||
* an element in this list
|
||||
* @throws NullPointerException if a is null
|
||||
*/
|
||||
public Object[] toArray(Object[] a)
|
||||
public <T> T[] toArray(T[] a)
|
||||
{
|
||||
if (a.length < size)
|
||||
a = (Object[]) Array.newInstance(a.getClass().getComponentType(),
|
||||
size);
|
||||
a = (T[]) Array.newInstance(a.getClass().getComponentType(), size);
|
||||
else if (a.length > size)
|
||||
a[size] = null;
|
||||
System.arraycopy(data, 0, a, 0, size);
|
||||
@@ -304,7 +303,7 @@ public class ArrayList extends AbstractList
|
||||
* @param index the index of the element we are fetching
|
||||
* @throws IndexOutOfBoundsException if index < 0 || index >= size()
|
||||
*/
|
||||
public Object get(int index)
|
||||
public E get(int index)
|
||||
{
|
||||
checkBoundExclusive(index);
|
||||
return data[index];
|
||||
@@ -319,10 +318,10 @@ public class ArrayList extends AbstractList
|
||||
* @return the element previously at the specified index
|
||||
* @throws IndexOutOfBoundsException if index < 0 || index >= 0
|
||||
*/
|
||||
public Object set(int index, Object e)
|
||||
public E set(int index, E e)
|
||||
{
|
||||
checkBoundExclusive(index);
|
||||
Object result = data[index];
|
||||
E result = data[index];
|
||||
data[index] = e;
|
||||
return result;
|
||||
}
|
||||
@@ -334,7 +333,7 @@ public class ArrayList extends AbstractList
|
||||
* @param e the element to be appended to this list
|
||||
* @return true, the add will always succeed
|
||||
*/
|
||||
public boolean add(Object e)
|
||||
public boolean add(E e)
|
||||
{
|
||||
modCount++;
|
||||
if (size == data.length)
|
||||
@@ -352,7 +351,7 @@ public class ArrayList extends AbstractList
|
||||
* @param e the item being added
|
||||
* @throws IndexOutOfBoundsException if index < 0 || index > size()
|
||||
*/
|
||||
public void add(int index, Object e)
|
||||
public void add(int index, E e)
|
||||
{
|
||||
checkBoundInclusive(index);
|
||||
modCount++;
|
||||
@@ -371,10 +370,10 @@ public class ArrayList extends AbstractList
|
||||
* @return the removed Object
|
||||
* @throws IndexOutOfBoundsException if index < 0 || index >= size()
|
||||
*/
|
||||
public Object remove(int index)
|
||||
public E remove(int index)
|
||||
{
|
||||
checkBoundExclusive(index);
|
||||
Object r = data[index];
|
||||
E r = data[index];
|
||||
modCount++;
|
||||
if (index != --size)
|
||||
System.arraycopy(data, index + 1, data, index, size - index);
|
||||
@@ -407,7 +406,7 @@ public class ArrayList extends AbstractList
|
||||
* @return true if the list was modified, in other words c is not empty
|
||||
* @throws NullPointerException if c is null
|
||||
*/
|
||||
public boolean addAll(Collection c)
|
||||
public boolean addAll(Collection<? extends E> c)
|
||||
{
|
||||
return addAll(size, c);
|
||||
}
|
||||
@@ -422,10 +421,10 @@ public class ArrayList extends AbstractList
|
||||
* @throws IndexOutOfBoundsException if index < 0 || index > 0
|
||||
* @throws NullPointerException if c is null
|
||||
*/
|
||||
public boolean addAll(int index, Collection c)
|
||||
public boolean addAll(int index, Collection<? extends E> c)
|
||||
{
|
||||
checkBoundInclusive(index);
|
||||
Iterator itr = c.iterator();
|
||||
Iterator<? extends E> itr = c.iterator();
|
||||
int csize = c.size();
|
||||
|
||||
modCount++;
|
||||
@@ -502,7 +501,7 @@ public class ArrayList extends AbstractList
|
||||
* @return true if this list changed
|
||||
* @throws NullPointerException if c is null
|
||||
*/
|
||||
boolean removeAllInternal(Collection c)
|
||||
boolean removeAllInternal(Collection<?> c)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
@@ -530,7 +529,7 @@ public class ArrayList extends AbstractList
|
||||
* @throws NullPointerException if c is null
|
||||
* @since 1.2
|
||||
*/
|
||||
boolean retainAllInternal(Collection c)
|
||||
boolean retainAllInternal(Collection<?> c)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
@@ -584,8 +583,8 @@ public class ArrayList extends AbstractList
|
||||
// the `size' field.
|
||||
s.defaultReadObject();
|
||||
int capacity = s.readInt();
|
||||
data = new Object[capacity];
|
||||
data = (E[]) new Object[capacity];
|
||||
for (int i = 0; i < size; i++)
|
||||
data[i] = s.readObject();
|
||||
data[i] = (E) s.readObject();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -362,7 +362,7 @@ public class Arrays
|
||||
* @throws NullPointerException if a null element is compared with natural
|
||||
* ordering (only possible when c is null)
|
||||
*/
|
||||
public static int binarySearch(Object[] a, Object key, Comparator c)
|
||||
public static <T> int binarySearch(T[] a, T key, Comparator<? super T> c)
|
||||
{
|
||||
int low = 0;
|
||||
int hi = a.length - 1;
|
||||
@@ -2163,7 +2163,7 @@ public class Arrays
|
||||
* @throws NullPointerException if a null element is compared with natural
|
||||
* ordering (only possible when c is null)
|
||||
*/
|
||||
public static void sort(Object[] a, Comparator c)
|
||||
public static <T> void sort(T[] a, Comparator<? super T> c)
|
||||
{
|
||||
sort(a, 0, a.length, c);
|
||||
}
|
||||
@@ -2213,7 +2213,8 @@ public class Arrays
|
||||
* @throws NullPointerException if a null element is compared with natural
|
||||
* ordering (only possible when c is null)
|
||||
*/
|
||||
public static void sort(Object[] a, int fromIndex, int toIndex, Comparator c)
|
||||
public static <T> void sort(T[] a, int fromIndex, int toIndex,
|
||||
Comparator<? super T> c)
|
||||
{
|
||||
if (fromIndex > toIndex)
|
||||
throw new IllegalArgumentException("fromIndex " + fromIndex
|
||||
@@ -2235,7 +2236,7 @@ public class Arrays
|
||||
{
|
||||
// not already sorted
|
||||
int j = i;
|
||||
Object elem = a[j];
|
||||
T elem = a[j];
|
||||
do
|
||||
{
|
||||
a[j] = a[j - 1];
|
||||
@@ -2253,9 +2254,9 @@ public class Arrays
|
||||
if (len <= 6)
|
||||
return;
|
||||
|
||||
Object[] src = a;
|
||||
Object[] dest = new Object[len];
|
||||
Object[] t = null; // t is used for swapping src and dest
|
||||
T[] src = a;
|
||||
T[] dest = (T[]) new Object[len];
|
||||
T[] t = null; // t is used for swapping src and dest
|
||||
|
||||
// The difference of the fromIndex of the src and dest array.
|
||||
int srcDestDiff = -fromIndex;
|
||||
@@ -2349,7 +2350,7 @@ public class Arrays
|
||||
* @see RandomAccess
|
||||
* @see Arrays.ArrayList
|
||||
*/
|
||||
public static List asList(final Object[] a)
|
||||
public static <T> List<T> asList(final T... a)
|
||||
{
|
||||
return new Arrays.ArrayList(a);
|
||||
}
|
||||
@@ -2546,11 +2547,10 @@ public class Arrays
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hashcode of an array of integer numbers. If two arrays
|
||||
* Returns the hashcode of an array of objects. If two arrays
|
||||
* are equal, according to <code>equals()</code>, they should have the
|
||||
* same hashcode. The hashcode returned by the method is equal to that
|
||||
* obtained by the corresponding <code>List</code> object. This has the same
|
||||
* data, but represents ints in their wrapper class, <code>Integer</code>.
|
||||
* obtained by the corresponding <code>List</code> object.
|
||||
* For <code>null</code>, 0 is returned.
|
||||
*
|
||||
* @param v an array of integer numbers for which the hash code should be
|
||||
@@ -2571,7 +2571,6 @@ public class Arrays
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @since 1.5 */
|
||||
public static int deepHashCode(Object[] v)
|
||||
{
|
||||
if (v == null)
|
||||
@@ -2914,7 +2913,7 @@ public class Arrays
|
||||
* @author Eric Blake (ebb9@email.byu.edu)
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
private static final class ArrayList extends AbstractList
|
||||
private static final class ArrayList<E> extends AbstractList<E>
|
||||
implements Serializable, RandomAccess
|
||||
{
|
||||
// We override the necessary methods, plus others which will be much
|
||||
@@ -2929,14 +2928,14 @@ public class Arrays
|
||||
* The array we are viewing.
|
||||
* @serial the array
|
||||
*/
|
||||
private final Object[] a;
|
||||
private final E[] a;
|
||||
|
||||
/**
|
||||
* Construct a list view of the array.
|
||||
* @param a the array to view
|
||||
* @throws NullPointerException if a is null
|
||||
*/
|
||||
ArrayList(Object[] a)
|
||||
ArrayList(E[] a)
|
||||
{
|
||||
// We have to explicitly check.
|
||||
if (a == null)
|
||||
@@ -2951,7 +2950,7 @@ public class Arrays
|
||||
* @param index The index to retrieve an object from.
|
||||
* @return The object at the array index specified.
|
||||
*/
|
||||
public Object get(int index)
|
||||
public E get(int index)
|
||||
{
|
||||
return a[index];
|
||||
}
|
||||
@@ -2974,9 +2973,9 @@ public class Arrays
|
||||
* @param element The new object.
|
||||
* @return The object replaced by this operation.
|
||||
*/
|
||||
public Object set(int index, Object element)
|
||||
public E set(int index, E element)
|
||||
{
|
||||
Object old = a[index];
|
||||
E old = a[index];
|
||||
a[index] = element;
|
||||
return old;
|
||||
}
|
||||
@@ -3047,12 +3046,12 @@ public class Arrays
|
||||
* @return The array containing the objects in this list,
|
||||
* which may or may not be == to array.
|
||||
*/
|
||||
public Object[] toArray(Object[] array)
|
||||
public <T> T[] toArray(T[] array)
|
||||
{
|
||||
int size = a.length;
|
||||
if (array.length < size)
|
||||
array = (Object[])
|
||||
Array.newInstance(array.getClass().getComponentType(), size);
|
||||
array = (T[]) Array.newInstance(array.getClass().getComponentType(),
|
||||
size);
|
||||
else if (array.length > size)
|
||||
array[size] = null;
|
||||
|
||||
|
||||
@@ -741,4 +741,15 @@ public class BitSet implements Cloneable, Serializable
|
||||
bits = nd;
|
||||
}
|
||||
}
|
||||
|
||||
// This is used by EnumSet for efficiency.
|
||||
final boolean containsAll(BitSet other)
|
||||
{
|
||||
for (int i = other.bits.length - 1; i >= 0; i--)
|
||||
{
|
||||
if ((bits[i] & other.bits[i]) != other.bits[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* Calendar.java --
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006,
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -103,7 +104,8 @@ day_of_week + week_of_year</pre>
|
||||
* @see TimeZone
|
||||
* @see java.text.DateFormat
|
||||
*/
|
||||
public abstract class Calendar implements Serializable, Cloneable
|
||||
public abstract class Calendar
|
||||
implements Serializable, Cloneable, Comparable<Calendar>
|
||||
{
|
||||
/**
|
||||
* Constant representing the era time field.
|
||||
@@ -483,6 +485,8 @@ public abstract class Calendar implements Serializable, Cloneable
|
||||
/**
|
||||
* Creates a calendar representing the actual time, using the default
|
||||
* time zone and locale.
|
||||
*
|
||||
* @return The new calendar.
|
||||
*/
|
||||
public static synchronized Calendar getInstance()
|
||||
{
|
||||
@@ -492,7 +496,12 @@ public abstract class Calendar implements Serializable, Cloneable
|
||||
/**
|
||||
* Creates a calendar representing the actual time, using the given
|
||||
* time zone and the default locale.
|
||||
* @param zone a time zone.
|
||||
*
|
||||
* @param zone a time zone (<code>null</code> not permitted).
|
||||
*
|
||||
* @return The new calendar.
|
||||
*
|
||||
* @throws NullPointerException if <code>zone</code> is <code>null</code>.
|
||||
*/
|
||||
public static synchronized Calendar getInstance(TimeZone zone)
|
||||
{
|
||||
@@ -502,7 +511,12 @@ public abstract class Calendar implements Serializable, Cloneable
|
||||
/**
|
||||
* Creates a calendar representing the actual time, using the default
|
||||
* time zone and the given locale.
|
||||
* @param locale a locale.
|
||||
*
|
||||
* @param locale a locale (<code>null</code> not permitted).
|
||||
*
|
||||
* @return The new calendar.
|
||||
*
|
||||
* @throws NullPointerException if <code>locale</code> is <code>null</code>.
|
||||
*/
|
||||
public static synchronized Calendar getInstance(Locale locale)
|
||||
{
|
||||
@@ -524,8 +538,14 @@ public abstract class Calendar implements Serializable, Cloneable
|
||||
/**
|
||||
* Creates a calendar representing the actual time, using the given
|
||||
* time zone and locale.
|
||||
* @param zone a time zone.
|
||||
* @param locale a locale.
|
||||
*
|
||||
* @param zone a time zone (<code>null</code> not permitted).
|
||||
* @param locale a locale (<code>null</code> not permitted).
|
||||
*
|
||||
* @return The new calendar.
|
||||
*
|
||||
* @throws NullPointerException if <code>zone</code> or <code>locale</code>
|
||||
* is <code>null</code>.
|
||||
*/
|
||||
public static synchronized Calendar getInstance(TimeZone zone, Locale locale)
|
||||
{
|
||||
@@ -617,6 +637,10 @@ public abstract class Calendar implements Serializable, Cloneable
|
||||
/**
|
||||
* Sets this Calendar's time to the given Date. All time fields
|
||||
* are invalidated by this method.
|
||||
*
|
||||
* @param date the date (<code>null</code> not permitted).
|
||||
*
|
||||
* @throws NullPointerException if <code>date</code> is <code>null</code>.
|
||||
*/
|
||||
public final void setTime(Date date)
|
||||
{
|
||||
@@ -1195,6 +1219,31 @@ public abstract class Calendar implements Serializable, Cloneable
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the time of two calendar instances.
|
||||
* @param calendar the calendar to which the time should be compared.
|
||||
* @return 0 if the two calendars are set to the same time,
|
||||
* less than 0 if the time of this calendar is before that of
|
||||
* <code>cal</code>, or more than 0 if the time of this calendar is after
|
||||
* that of <code>cal</code>.
|
||||
*
|
||||
* @param cal the calendar to compare this instance with.
|
||||
* @throws NullPointerException if <code>cal</code> is null.
|
||||
* @throws IllegalArgumentException if either calendar has fields set to
|
||||
* invalid values.
|
||||
* @since 1.5
|
||||
*/
|
||||
public int compareTo(Calendar cal)
|
||||
{
|
||||
long t1 = getTimeInMillis();
|
||||
long t2 = cal.getTimeInMillis();
|
||||
if(t1 == t2)
|
||||
return 0;
|
||||
if(t1 > t2)
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a clone of this object.
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Collection.java -- Interface that represents a collection of objects
|
||||
Copyright (C) 1998, 2001, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 2001, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -67,6 +67,8 @@ package java.util;
|
||||
*
|
||||
* @author Original author unknown
|
||||
* @author Eric Blake (ebb9@email.byu.edu)
|
||||
* @author Tom Tromey (tromey@redhat.com)
|
||||
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
|
||||
* @see List
|
||||
* @see Set
|
||||
* @see Map
|
||||
@@ -81,9 +83,9 @@ package java.util;
|
||||
* @see Arrays
|
||||
* @see AbstractCollection
|
||||
* @since 1.2
|
||||
* @status updated to 1.5 (minus generics)
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public interface Collection extends Iterable
|
||||
public interface Collection<E> extends Iterable<E>
|
||||
{
|
||||
/**
|
||||
* Add an element to this collection.
|
||||
@@ -99,7 +101,7 @@ public interface Collection extends Iterable
|
||||
* @throws IllegalArgumentException if o cannot be added to this
|
||||
* collection for some other reason.
|
||||
*/
|
||||
boolean add(Object o);
|
||||
boolean add(E o);
|
||||
|
||||
/**
|
||||
* Add the contents of a given collection to this collection.
|
||||
@@ -116,7 +118,7 @@ public interface Collection extends Iterable
|
||||
* @throws IllegalArgumentException if some element of c cannot be added
|
||||
* to this collection for some other reason.
|
||||
*/
|
||||
boolean addAll(Collection c);
|
||||
boolean addAll(Collection<? extends E> c);
|
||||
|
||||
/**
|
||||
* Clear the collection, such that a subsequent call to isEmpty() would
|
||||
@@ -152,7 +154,7 @@ public interface Collection extends Iterable
|
||||
* collection does not support null values.
|
||||
* @throws NullPointerException if c itself is null.
|
||||
*/
|
||||
boolean containsAll(Collection c);
|
||||
boolean containsAll(Collection<?> c);
|
||||
|
||||
/**
|
||||
* Test whether this collection is equal to some object. The Collection
|
||||
@@ -200,7 +202,7 @@ public interface Collection extends Iterable
|
||||
*
|
||||
* @return an Iterator over the elements of this collection, in any order.
|
||||
*/
|
||||
Iterator iterator();
|
||||
Iterator<E> iterator();
|
||||
|
||||
/**
|
||||
* Remove a single occurrence of an object from this collection. That is,
|
||||
@@ -233,7 +235,7 @@ public interface Collection extends Iterable
|
||||
* collection does not support removing null values.
|
||||
* @throws NullPointerException if c itself is null.
|
||||
*/
|
||||
boolean removeAll(Collection c);
|
||||
boolean removeAll(Collection<?> c);
|
||||
|
||||
/**
|
||||
* Remove all elements of this collection that are not contained in a given
|
||||
@@ -249,7 +251,7 @@ public interface Collection extends Iterable
|
||||
* collection does not support retaining null values.
|
||||
* @throws NullPointerException if c itself is null.
|
||||
*/
|
||||
boolean retainAll(Collection c);
|
||||
boolean retainAll(Collection<?> c);
|
||||
|
||||
/**
|
||||
* Get the number of elements in this collection.
|
||||
@@ -284,5 +286,5 @@ public interface Collection extends Iterable
|
||||
* @throws ArrayStoreException if the type of any element of the
|
||||
* collection is not a subtype of the element type of a.
|
||||
*/
|
||||
Object[] toArray(Object[] a);
|
||||
<T> T[] toArray(T[] a);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/* Comparator.java -- Interface for objects that specify an ordering
|
||||
Copyright (C) 1998, 2001, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 2001, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -71,7 +71,7 @@ package java.util;
|
||||
* @since 1.2
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public interface Comparator
|
||||
public interface Comparator<T>
|
||||
{
|
||||
/**
|
||||
* Return an integer that is negative, zero or positive depending on whether
|
||||
@@ -102,7 +102,7 @@ public interface Comparator
|
||||
* @throws ClassCastException if the elements are not of types that can be
|
||||
* compared by this ordering.
|
||||
*/
|
||||
int compare(Object o1, Object o2);
|
||||
int compare(T o1, T o2);
|
||||
|
||||
/**
|
||||
* Return true if the object is equal to this object. To be
|
||||
|
||||
@@ -108,7 +108,7 @@ import java.text.SimpleDateFormat;
|
||||
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
|
||||
*/
|
||||
public class Date
|
||||
implements Cloneable, Comparable, Serializable
|
||||
implements Cloneable, Comparable<Date>, Serializable
|
||||
{
|
||||
/**
|
||||
* This is the serialization UID for this class
|
||||
@@ -353,24 +353,6 @@ public class Date
|
||||
return (time < when.time) ? -1 : (time == when.time) ? 0 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this Date to another object. This behaves like
|
||||
* <code>compareTo(Date)</code>, but it takes a generic object
|
||||
* and throws a <code>ClassCastException</code> if obj is
|
||||
* not a <code>Date</code>.
|
||||
*
|
||||
* @param obj the other date.
|
||||
* @return 0, if the date represented
|
||||
* by obj is exactly the same as the time represented by this
|
||||
* object, a negative if this Date is before the other Date, and
|
||||
* a positive value otherwise.
|
||||
* @exception ClassCastException if obj is not of type Date.
|
||||
*/
|
||||
public int compareTo(Object obj)
|
||||
{
|
||||
return compareTo((Date) obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the hash code of this <code>Date</code> as the
|
||||
* XOR of the most significant and the least significant
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Dictionary.java -- an abstract (and essentially worthless)
|
||||
class which is Hashtable's superclass
|
||||
Copyright (C) 1998, 2001, 2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 2001, 2002, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -57,7 +57,7 @@ package java.util;
|
||||
* @since 1.0
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public abstract class Dictionary
|
||||
public abstract class Dictionary<K, V>
|
||||
{
|
||||
// WARNING: Dictionary is a CORE class in the bootstrap cycle. See the
|
||||
// comments in vm/reference/java/lang/Runtime for implications of this fact.
|
||||
@@ -75,7 +75,7 @@ public abstract class Dictionary
|
||||
* @return an Enumeration of the values
|
||||
* @see #keys()
|
||||
*/
|
||||
public abstract Enumeration elements();
|
||||
public abstract Enumeration<V> elements();
|
||||
|
||||
/**
|
||||
* Returns the value associated with the supplied key, or null
|
||||
@@ -87,7 +87,7 @@ public abstract class Dictionary
|
||||
* @throws NullPointerException if key is null
|
||||
* @see #put(Object, Object)
|
||||
*/
|
||||
public abstract Object get(Object key);
|
||||
public abstract V get(Object key);
|
||||
|
||||
/**
|
||||
* Returns true when there are no elements in this Dictionary.
|
||||
@@ -102,7 +102,7 @@ public abstract class Dictionary
|
||||
* @return an Enumeration of the keys
|
||||
* @see #elements()
|
||||
*/
|
||||
public abstract Enumeration keys();
|
||||
public abstract Enumeration<K> keys();
|
||||
|
||||
/**
|
||||
* Inserts a new value into this Dictionary, located by the
|
||||
@@ -115,7 +115,7 @@ public abstract class Dictionary
|
||||
* @throws NullPointerException if key or value is null
|
||||
* @see #get(Object)
|
||||
*/
|
||||
public abstract Object put(Object key, Object value);
|
||||
public abstract V put(K key, V value);
|
||||
|
||||
/**
|
||||
* Removes from the Dictionary the value located by the given key. A null
|
||||
@@ -125,7 +125,7 @@ public abstract class Dictionary
|
||||
* @return the value associated with the removed key
|
||||
* @throws NullPointerException if key is null
|
||||
*/
|
||||
public abstract Object remove(Object key);
|
||||
public abstract V remove(Object key);
|
||||
|
||||
/**
|
||||
* Returns the number of values currently in this Dictionary.
|
||||
|
||||
@@ -0,0 +1,394 @@
|
||||
/* EnumMap.java - Map where keys are enum constants
|
||||
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.util;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author Tom Tromey (tromey@redhat.com)
|
||||
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
|
||||
* @since 1.5
|
||||
*/
|
||||
|
||||
public class EnumMap<K extends Enum<K>, V>
|
||||
extends AbstractMap<K, V>
|
||||
implements Cloneable, Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 458661240069192865L;
|
||||
|
||||
V[] store;
|
||||
int cardinality;
|
||||
Class<K> enumClass;
|
||||
|
||||
/**
|
||||
* The cache for {@link #entrySet()}.
|
||||
*/
|
||||
transient Set<Map.Entry<K, V>> entries;
|
||||
|
||||
static final Object emptySlot = new Object();
|
||||
|
||||
public EnumMap(Class<K> keyType)
|
||||
{
|
||||
store = (V[]) new Object[keyType.getEnumConstants().length];
|
||||
Arrays.fill(store, emptySlot);
|
||||
cardinality = 0;
|
||||
enumClass = keyType;
|
||||
}
|
||||
|
||||
public EnumMap(EnumMap<K, ? extends V> map)
|
||||
{
|
||||
store = (V[]) map.store.clone();
|
||||
cardinality = map.cardinality;
|
||||
enumClass = map.enumClass;
|
||||
}
|
||||
|
||||
public EnumMap(Map<K, ? extends V> map)
|
||||
{
|
||||
if (map instanceof EnumMap)
|
||||
{
|
||||
EnumMap<K, ? extends V> other = (EnumMap<K, ? extends V>) map;
|
||||
store = (V[]) other.store.clone();
|
||||
cardinality = other.cardinality;
|
||||
enumClass = other.enumClass;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (K key : map.keySet())
|
||||
{
|
||||
V value = map.get(key);
|
||||
if (store == null)
|
||||
{
|
||||
enumClass = key.getDeclaringClass();
|
||||
store = (V[]) new Object[enumClass.getEnumConstants().length];
|
||||
}
|
||||
int o = key.ordinal();
|
||||
if (store[o] == emptySlot)
|
||||
++cardinality;
|
||||
store[o] = value;
|
||||
}
|
||||
// There must be a single element.
|
||||
if (store == null)
|
||||
throw new IllegalArgumentException("no elements in map");
|
||||
}
|
||||
}
|
||||
|
||||
public int size()
|
||||
{
|
||||
return cardinality;
|
||||
}
|
||||
|
||||
public boolean containsValue(Object value)
|
||||
{
|
||||
for (V i : store)
|
||||
{
|
||||
if (i != emptySlot && AbstractCollection.equals(i , value))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean containsKey(Object key)
|
||||
{
|
||||
if (! (key instanceof Enum))
|
||||
return false;
|
||||
Enum<K> e = (Enum<K>) key;
|
||||
if (e.getDeclaringClass() != enumClass)
|
||||
return false;
|
||||
return store[e.ordinal()] != emptySlot;
|
||||
}
|
||||
|
||||
public V get(Object key)
|
||||
{
|
||||
if (! (key instanceof Enum))
|
||||
return null;
|
||||
Enum<K> e = (Enum<K>) key;
|
||||
if (e.getDeclaringClass() != enumClass)
|
||||
return null;
|
||||
return store[e.ordinal()];
|
||||
}
|
||||
|
||||
public V put(K key, V value)
|
||||
{
|
||||
int o = key.ordinal();
|
||||
V result;
|
||||
if (store[o] == emptySlot)
|
||||
{
|
||||
result = null;
|
||||
++cardinality;
|
||||
}
|
||||
else
|
||||
result = store[o];
|
||||
store[o] = value;
|
||||
return result;
|
||||
}
|
||||
|
||||
public V remove(Object key)
|
||||
{
|
||||
if (! (key instanceof Enum))
|
||||
return null;
|
||||
Enum<K> e = (Enum<K>) key;
|
||||
if (e.getDeclaringClass() != enumClass)
|
||||
return null;
|
||||
V result = store[e.ordinal()];
|
||||
if (result == emptySlot)
|
||||
result = null;
|
||||
else
|
||||
--cardinality;
|
||||
store[e.ordinal()] = (V) emptySlot;
|
||||
return result;
|
||||
}
|
||||
|
||||
public void putAll(Map<? extends K, ? extends V> map)
|
||||
{
|
||||
for (K key : map.keySet())
|
||||
{
|
||||
V value = map.get(key);
|
||||
|
||||
int o = key.ordinal();
|
||||
if (store[o] == emptySlot)
|
||||
++cardinality;
|
||||
store[o] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
Arrays.fill(store, emptySlot);
|
||||
cardinality = 0;
|
||||
}
|
||||
|
||||
public Set<K> keySet()
|
||||
{
|
||||
if (keys == null)
|
||||
{
|
||||
keys = new AbstractSet<K>()
|
||||
{
|
||||
public int size()
|
||||
{
|
||||
return cardinality;
|
||||
}
|
||||
|
||||
public Iterator<K> iterator()
|
||||
{
|
||||
return new Iterator<K>()
|
||||
{
|
||||
int count = 0;
|
||||
int index = -1;
|
||||
|
||||
public boolean hasNext()
|
||||
{
|
||||
return count < cardinality;
|
||||
}
|
||||
|
||||
public K next()
|
||||
{
|
||||
++count;
|
||||
for (++index; store[index] == emptySlot; ++index)
|
||||
;
|
||||
return enumClass.getEnumConstants()[index];
|
||||
}
|
||||
|
||||
public void remove()
|
||||
{
|
||||
--cardinality;
|
||||
store[index] = (V) emptySlot;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
EnumMap.this.clear();
|
||||
}
|
||||
|
||||
public boolean contains(Object o)
|
||||
{
|
||||
return contains(o);
|
||||
}
|
||||
|
||||
public boolean remove(Object o)
|
||||
{
|
||||
return EnumMap.this.remove(o) != null;
|
||||
}
|
||||
};
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
public Collection<V> values()
|
||||
{
|
||||
if (values == null)
|
||||
{
|
||||
values = new AbstractCollection<V>()
|
||||
{
|
||||
public int size()
|
||||
{
|
||||
return cardinality;
|
||||
}
|
||||
|
||||
public Iterator<V> iterator()
|
||||
{
|
||||
return new Iterator<V>()
|
||||
{
|
||||
int count = 0;
|
||||
int index = -1;
|
||||
|
||||
public boolean hasNext()
|
||||
{
|
||||
return count < cardinality;
|
||||
}
|
||||
|
||||
public V next()
|
||||
{
|
||||
++count;
|
||||
for (++index; store[index] == emptySlot; ++index)
|
||||
;
|
||||
return store[index];
|
||||
}
|
||||
|
||||
public void remove()
|
||||
{
|
||||
--cardinality;
|
||||
store[index] = (V) emptySlot;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
EnumMap.this.clear();
|
||||
}
|
||||
};
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
public Set<Map.Entry<K, V>> entrySet()
|
||||
{
|
||||
if (entries == null)
|
||||
{
|
||||
entries = new AbstractSet<Map.Entry<K, V>>()
|
||||
{
|
||||
public int size()
|
||||
{
|
||||
return cardinality;
|
||||
}
|
||||
|
||||
public Iterator<Map.Entry<K, V>> iterator()
|
||||
{
|
||||
return new Iterator<Map.Entry<K, V>>()
|
||||
{
|
||||
int count = 0;
|
||||
int index = -1;
|
||||
|
||||
public boolean hasNext()
|
||||
{
|
||||
return count < cardinality;
|
||||
}
|
||||
|
||||
public Map.Entry<K,V> next()
|
||||
{
|
||||
++count;
|
||||
for (++index; store[index] == emptySlot; ++index)
|
||||
;
|
||||
// FIXME: we could just return something that
|
||||
// only knows the index. That would be cleaner.
|
||||
return new AbstractMap.SimpleEntry<K, V>(enumClass.getEnumConstants()[index],
|
||||
store[index])
|
||||
{
|
||||
public V setValue(V newVal)
|
||||
{
|
||||
value = newVal;
|
||||
return put(key, newVal);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void remove()
|
||||
{
|
||||
--cardinality;
|
||||
store[index] = (V) emptySlot;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
EnumMap.this.clear();
|
||||
}
|
||||
|
||||
public boolean contains(Object o)
|
||||
{
|
||||
if (! (o instanceof Map.Entry))
|
||||
return false;
|
||||
Map.Entry<K, V> other = (Map.Entry<K, V>) o;
|
||||
return (containsKey(other.getKey())
|
||||
&& AbstractCollection.equals(get(other.getKey()),
|
||||
other.getValue()));
|
||||
}
|
||||
|
||||
public boolean remove(Object o)
|
||||
{
|
||||
if (! (o instanceof Map.Entry))
|
||||
return false;
|
||||
Map.Entry<K, V> other = (Map.Entry<K, V>) o;
|
||||
return EnumMap.this.remove(other.getKey()) != null;
|
||||
}
|
||||
};
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (! (o instanceof EnumMap))
|
||||
return false;
|
||||
EnumMap<K, V> other = (EnumMap<K, V>) o;
|
||||
if (other.enumClass != enumClass || other.cardinality != cardinality)
|
||||
return false;
|
||||
return Arrays.equals(store, other.store);
|
||||
}
|
||||
|
||||
public EnumMap<K, V> clone()
|
||||
{
|
||||
/* This constructor provides this functionality */
|
||||
return new EnumMap(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,365 @@
|
||||
/* EnumSet.java - Set of enum objects
|
||||
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.util;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author Tom Tromey (tromey@redhat.com)
|
||||
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
|
||||
* @since 1.5
|
||||
*/
|
||||
|
||||
// FIXME: serialization is special.
|
||||
public class EnumSet<T extends Enum<T>>
|
||||
extends AbstractSet<T>
|
||||
implements Cloneable, Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 4782406773684236311L;
|
||||
|
||||
BitSet store;
|
||||
int cardinality;
|
||||
Class<T> enumClass;
|
||||
|
||||
EnumSet()
|
||||
{
|
||||
}
|
||||
|
||||
public EnumSet<T> clone()
|
||||
{
|
||||
EnumSet<T> r;
|
||||
|
||||
try
|
||||
{
|
||||
r = (EnumSet<T>) super.clone();
|
||||
}
|
||||
catch (CloneNotSupportedException _)
|
||||
{
|
||||
/* Can't happen */
|
||||
return null;
|
||||
}
|
||||
r.store = (BitSet) store.clone();
|
||||
return r;
|
||||
}
|
||||
|
||||
public int size()
|
||||
{
|
||||
return cardinality;
|
||||
}
|
||||
|
||||
public Iterator<T> iterator()
|
||||
{
|
||||
return new Iterator<T>()
|
||||
{
|
||||
int next = -1;
|
||||
int count = 0;
|
||||
|
||||
public boolean hasNext()
|
||||
{
|
||||
return count < cardinality;
|
||||
}
|
||||
|
||||
public T next()
|
||||
{
|
||||
next = store.nextSetBit(next + 1);
|
||||
++count;
|
||||
return enumClass.getEnumConstants()[next];
|
||||
}
|
||||
|
||||
public void remove()
|
||||
{
|
||||
if (! store.get(next))
|
||||
{
|
||||
store.clear(next);
|
||||
--cardinality;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public boolean add(T val)
|
||||
{
|
||||
if (store.get(val.ordinal()))
|
||||
return false;
|
||||
store.set(val.ordinal());
|
||||
++cardinality;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean addAll(Collection<? extends T> c)
|
||||
{
|
||||
boolean result = false;
|
||||
if (c instanceof EnumSet)
|
||||
{
|
||||
EnumSet<T> other = (EnumSet<T>) c;
|
||||
if (enumClass == other.enumClass)
|
||||
{
|
||||
store.or(other.store);
|
||||
int save = cardinality;
|
||||
cardinality = store.cardinality();
|
||||
result = save != cardinality;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (T val : c)
|
||||
{
|
||||
if (add (val))
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
store.clear();
|
||||
cardinality = 0;
|
||||
}
|
||||
|
||||
public boolean contains(Object o)
|
||||
{
|
||||
if (! (o instanceof Enum))
|
||||
return false;
|
||||
Enum<T> e = (Enum<T>) o;
|
||||
if (e.getDeclaringClass() != enumClass)
|
||||
return false;
|
||||
return store.get(e.ordinal());
|
||||
}
|
||||
|
||||
public boolean containsAll(Collection<?> c)
|
||||
{
|
||||
if (c instanceof EnumSet)
|
||||
{
|
||||
EnumSet<T> other = (EnumSet<T>) c;
|
||||
if (enumClass == other.enumClass)
|
||||
return store.containsAll(other.store);
|
||||
return false;
|
||||
}
|
||||
return super.containsAll(c);
|
||||
}
|
||||
|
||||
public boolean remove(Object o)
|
||||
{
|
||||
if (! (o instanceof Enum))
|
||||
return false;
|
||||
Enum<T> e = (Enum<T>) o;
|
||||
if (e.getDeclaringClass() != enumClass)
|
||||
return false;
|
||||
store.clear(e.ordinal());
|
||||
--cardinality;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean removeAll(Collection<?> c)
|
||||
{
|
||||
if (c instanceof EnumSet)
|
||||
{
|
||||
EnumSet<T> other = (EnumSet<T>) c;
|
||||
if (enumClass != other.enumClass)
|
||||
return false;
|
||||
store.andNot(other.store);
|
||||
int save = cardinality;
|
||||
cardinality = store.cardinality();
|
||||
return save != cardinality;
|
||||
}
|
||||
return super.removeAll(c);
|
||||
}
|
||||
|
||||
public boolean retainAll(Collection<?> c)
|
||||
{
|
||||
if (c instanceof EnumSet)
|
||||
{
|
||||
EnumSet<T> other = (EnumSet<T>) c;
|
||||
if (enumClass != other.enumClass)
|
||||
return false;
|
||||
store.and(other.store);
|
||||
int save = cardinality;
|
||||
cardinality = store.cardinality();
|
||||
return save != cardinality;
|
||||
}
|
||||
return super.retainAll(c);
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>> EnumSet<T> allOf(Class<T> eltType)
|
||||
{
|
||||
EnumSet<T> r = new EnumSet<T>();
|
||||
r.store = new BitSet(eltType.getEnumConstants().length);
|
||||
r.store.set(0, r.store.size());
|
||||
r.cardinality = r.store.size();
|
||||
r.enumClass = eltType;
|
||||
return r;
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>> EnumSet<T> noneOf(Class<T> eltType)
|
||||
{
|
||||
EnumSet<T> r = new EnumSet<T>();
|
||||
r.store = new BitSet(eltType.getEnumConstants().length);
|
||||
r.enumClass = eltType;
|
||||
return r;
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>> EnumSet<T> copyOf(EnumSet<T> other)
|
||||
{
|
||||
// We can't just use `other.clone' since we don't want to make a
|
||||
// subclass.
|
||||
EnumSet<T> r = new EnumSet<T>();
|
||||
r.store = (BitSet) other.store.clone();
|
||||
r.cardinality = other.cardinality;
|
||||
r.enumClass = other.enumClass;
|
||||
return r;
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>> EnumSet<T> copyOf(Collection<T> other)
|
||||
{
|
||||
if (other instanceof EnumSet)
|
||||
return copyOf((EnumSet<T>) other);
|
||||
EnumSet<T> r = new EnumSet<T>();
|
||||
for (T val : other)
|
||||
{
|
||||
if (r.store == null)
|
||||
{
|
||||
r.enumClass = val.getDeclaringClass();
|
||||
r.store = new BitSet(r.enumClass.getEnumConstants().length);
|
||||
}
|
||||
r.store.set(val.ordinal());
|
||||
}
|
||||
// The collection must contain at least one element.
|
||||
if (r.store == null)
|
||||
throw new IllegalArgumentException();
|
||||
r.cardinality = r.store.cardinality();
|
||||
return r;
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>> EnumSet<T> complementOf(EnumSet<T> other)
|
||||
{
|
||||
EnumSet<T> r = new EnumSet<T>();
|
||||
r.store = (BitSet) other.store.clone();
|
||||
r.store.flip(0, r.store.size());
|
||||
r.cardinality = r.store.size() - other.cardinality;
|
||||
r.enumClass = other.enumClass;
|
||||
return r;
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>> EnumSet<T> of(T first)
|
||||
{
|
||||
EnumSet<T> r = new EnumSet<T>();
|
||||
r.enumClass = first.getDeclaringClass();
|
||||
r.store = new BitSet(r.enumClass.getEnumConstants().length);
|
||||
r.store.set(first.ordinal());
|
||||
r.cardinality = 1;
|
||||
return r;
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>> EnumSet<T> of(T first, T second)
|
||||
{
|
||||
EnumSet<T> r = new EnumSet<T>();
|
||||
r.enumClass = first.getDeclaringClass();
|
||||
r.store = new BitSet(r.enumClass.getEnumConstants().length);
|
||||
r.store.set(first.ordinal());
|
||||
r.store.set(second.ordinal());
|
||||
r.cardinality = r.store.cardinality();
|
||||
return r;
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>> EnumSet<T> of(T first, T second, T third)
|
||||
{
|
||||
EnumSet<T> r = new EnumSet<T>();
|
||||
r.enumClass = first.getDeclaringClass();
|
||||
r.store = new BitSet(r.enumClass.getEnumConstants().length);
|
||||
r.store.set(first.ordinal());
|
||||
r.store.set(second.ordinal());
|
||||
r.store.set(third.ordinal());
|
||||
r.cardinality = r.store.cardinality();
|
||||
return r;
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>> EnumSet<T> of(T first, T second, T third,
|
||||
T fourth)
|
||||
{
|
||||
EnumSet<T> r = new EnumSet<T>();
|
||||
r.enumClass = first.getDeclaringClass();
|
||||
r.store = new BitSet(r.enumClass.getEnumConstants().length);
|
||||
r.store.set(first.ordinal());
|
||||
r.store.set(second.ordinal());
|
||||
r.store.set(third.ordinal());
|
||||
r.store.set(fourth.ordinal());
|
||||
r.cardinality = r.store.cardinality();
|
||||
return r;
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>> EnumSet<T> of(T first, T second, T third,
|
||||
T fourth, T fifth)
|
||||
{
|
||||
EnumSet<T> r = new EnumSet<T>();
|
||||
r.enumClass = first.getDeclaringClass();
|
||||
r.store = new BitSet(r.enumClass.getEnumConstants().length);
|
||||
r.store.set(first.ordinal());
|
||||
r.store.set(second.ordinal());
|
||||
r.store.set(third.ordinal());
|
||||
r.store.set(fourth.ordinal());
|
||||
r.store.set(fifth.ordinal());
|
||||
r.cardinality = r.store.cardinality();
|
||||
return r;
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>> EnumSet<T> of(T first, T... rest)
|
||||
{
|
||||
EnumSet<T> r = new EnumSet<T>();
|
||||
r.enumClass = first.getDeclaringClass();
|
||||
r.store = new BitSet(r.enumClass.getEnumConstants().length);
|
||||
r.store.set(first.ordinal());
|
||||
for (T val : rest)
|
||||
r.store.set(val.ordinal());
|
||||
r.cardinality = r.store.cardinality();
|
||||
return r;
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>> EnumSet<T> range(T from, T to)
|
||||
{
|
||||
if (from.compareTo(to) > 0)
|
||||
throw new IllegalArgumentException();
|
||||
EnumSet<T> r = new EnumSet<T>();
|
||||
r.store = new BitSet(from.getDeclaringClass().getEnumConstants().length);
|
||||
r.store.set(from.ordinal(), to.ordinal() + 1);
|
||||
r.enumClass = from.getDeclaringClass();
|
||||
r.cardinality = to.ordinal() - from.ordinal() + 1;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
/* Enumeration.java -- Interface for enumerating lists of objects
|
||||
Copyright (C) 1998, 1999, 2001, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 1999, 2001, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -60,7 +61,7 @@ package java.util;
|
||||
* @since 1.0
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public interface Enumeration
|
||||
public interface Enumeration<E>
|
||||
{
|
||||
/**
|
||||
* Tests whether there are elements remaining in the enumeration.
|
||||
@@ -77,5 +78,5 @@ public interface Enumeration
|
||||
* @return the next element in the enumeration
|
||||
* @throws NoSuchElementException if there are no more elements
|
||||
*/
|
||||
Object nextElement();
|
||||
E nextElement();
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ public final class Formatter
|
||||
/**
|
||||
* The output of the formatter.
|
||||
*/
|
||||
private StringBuilder out;
|
||||
private Appendable out;
|
||||
|
||||
/**
|
||||
* The locale used by the formatter.
|
||||
@@ -142,6 +142,15 @@ public final class Formatter
|
||||
private static final String lineSeparator
|
||||
= SystemProperties.getProperty("line.separator");
|
||||
|
||||
/**
|
||||
* The type of numeric output format for a {@link BigDecimal}.
|
||||
*/
|
||||
public enum BigDecimalLayoutForm
|
||||
{
|
||||
DECIMAL_FLOAT,
|
||||
SCIENTIFIC
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>Formatter</code> using the default
|
||||
* locale and a {@link StringBuilder} as the output stream.
|
||||
@@ -170,7 +179,7 @@ public final class Formatter
|
||||
*
|
||||
* @param app the output stream to use.
|
||||
*/
|
||||
public Formatter(StringBuilder app)
|
||||
public Formatter(Appendable app)
|
||||
{
|
||||
this(app, Locale.getDefault());
|
||||
}
|
||||
@@ -183,12 +192,188 @@ public final class Formatter
|
||||
* @param app the output stream to use.
|
||||
* @param loc the locale to use.
|
||||
*/
|
||||
public Formatter(StringBuilder app, Locale loc)
|
||||
public Formatter(Appendable app, Locale loc)
|
||||
{
|
||||
this.out = app == null ? new StringBuilder() : app;
|
||||
this.locale = loc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>Formatter</code> using the default
|
||||
* locale and character set, with the specified file as the
|
||||
* output stream.
|
||||
*
|
||||
* @param file the file to use for output.
|
||||
* @throws FileNotFoundException if the file does not exist
|
||||
* and can not be created.
|
||||
* @throws SecurityException if a security manager is present
|
||||
* and doesn't allow writing to the file.
|
||||
*/
|
||||
public Formatter(File file)
|
||||
throws FileNotFoundException
|
||||
{
|
||||
this(new OutputStreamWriter(new FileOutputStream(file)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>Formatter</code> using the default
|
||||
* locale, with the specified file as the output stream
|
||||
* and the supplied character set.
|
||||
*
|
||||
* @param file the file to use for output.
|
||||
* @param charset the character set to use for output.
|
||||
* @throws FileNotFoundException if the file does not exist
|
||||
* and can not be created.
|
||||
* @throws SecurityException if a security manager is present
|
||||
* and doesn't allow writing to the file.
|
||||
* @throws UnsupportedEncodingException if the supplied character
|
||||
* set is not supported.
|
||||
*/
|
||||
public Formatter(File file, String charset)
|
||||
throws FileNotFoundException, UnsupportedEncodingException
|
||||
{
|
||||
this(file, charset, Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>Formatter</code> using the specified
|
||||
* file as the output stream with the supplied character set
|
||||
* and locale. If the locale is <code>null</code>, then no
|
||||
* localization is applied.
|
||||
*
|
||||
* @param file the file to use for output.
|
||||
* @param charset the character set to use for output.
|
||||
* @param loc the locale to use.
|
||||
* @throws FileNotFoundException if the file does not exist
|
||||
* and can not be created.
|
||||
* @throws SecurityException if a security manager is present
|
||||
* and doesn't allow writing to the file.
|
||||
* @throws UnsupportedEncodingException if the supplied character
|
||||
* set is not supported.
|
||||
*/
|
||||
public Formatter(File file, String charset, Locale loc)
|
||||
throws FileNotFoundException, UnsupportedEncodingException
|
||||
{
|
||||
this(new OutputStreamWriter(new FileOutputStream(file), charset),
|
||||
loc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>Formatter</code> using the default
|
||||
* locale and character set, with the specified output stream.
|
||||
*
|
||||
* @param out the output stream to use.
|
||||
*/
|
||||
public Formatter(OutputStream out)
|
||||
{
|
||||
this(new OutputStreamWriter(out));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>Formatter</code> using the default
|
||||
* locale, with the specified file output stream and the
|
||||
* supplied character set.
|
||||
*
|
||||
* @param out the output stream.
|
||||
* @param charset the character set to use for output.
|
||||
* @throws UnsupportedEncodingException if the supplied character
|
||||
* set is not supported.
|
||||
*/
|
||||
public Formatter(OutputStream out, String charset)
|
||||
throws UnsupportedEncodingException
|
||||
{
|
||||
this(out, charset, Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>Formatter</code> using the specified
|
||||
* output stream with the supplied character set and locale.
|
||||
* If the locale is <code>null</code>, then no localization is
|
||||
* applied.
|
||||
*
|
||||
* @param file the output stream.
|
||||
* @param charset the character set to use for output.
|
||||
* @param loc the locale to use.
|
||||
* @throws UnsupportedEncodingException if the supplied character
|
||||
* set is not supported.
|
||||
*/
|
||||
public Formatter(OutputStream out, String charset, Locale loc)
|
||||
throws UnsupportedEncodingException
|
||||
{
|
||||
this(new OutputStreamWriter(out, charset), loc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>Formatter</code> using the default
|
||||
* locale with the specified output stream. The character
|
||||
* set used is that of the output stream.
|
||||
*
|
||||
* @param out the output stream to use.
|
||||
*/
|
||||
public Formatter(PrintStream out)
|
||||
{
|
||||
this((Appendable) out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>Formatter</code> using the default
|
||||
* locale and character set, with the specified file as the
|
||||
* output stream.
|
||||
*
|
||||
* @param file the file to use for output.
|
||||
* @throws FileNotFoundException if the file does not exist
|
||||
* and can not be created.
|
||||
* @throws SecurityException if a security manager is present
|
||||
* and doesn't allow writing to the file.
|
||||
*/
|
||||
public Formatter(String file) throws FileNotFoundException
|
||||
{
|
||||
this(new OutputStreamWriter(new FileOutputStream(file)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>Formatter</code> using the default
|
||||
* locale, with the specified file as the output stream
|
||||
* and the supplied character set.
|
||||
*
|
||||
* @param file the file to use for output.
|
||||
* @param charset the character set to use for output.
|
||||
* @throws FileNotFoundException if the file does not exist
|
||||
* and can not be created.
|
||||
* @throws SecurityException if a security manager is present
|
||||
* and doesn't allow writing to the file.
|
||||
* @throws UnsupportedEncodingException if the supplied character
|
||||
* set is not supported.
|
||||
*/
|
||||
public Formatter(String file, String charset)
|
||||
throws FileNotFoundException, UnsupportedEncodingException
|
||||
{
|
||||
this(file, charset, Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>Formatter</code> using the specified
|
||||
* file as the output stream with the supplied character set
|
||||
* and locale. If the locale is <code>null</code>, then no
|
||||
* localization is applied.
|
||||
*
|
||||
* @param file the file to use for output.
|
||||
* @param charset the character set to use for output.
|
||||
* @param loc the locale to use.
|
||||
* @throws FileNotFoundException if the file does not exist
|
||||
* and can not be created.
|
||||
* @throws SecurityException if a security manager is present
|
||||
* and doesn't allow writing to the file.
|
||||
* @throws UnsupportedEncodingException if the supplied character
|
||||
* set is not supported.
|
||||
*/
|
||||
public Formatter(String file, String charset, Locale loc)
|
||||
throws FileNotFoundException, UnsupportedEncodingException
|
||||
{
|
||||
this(new OutputStreamWriter(new FileOutputStream(file), charset),
|
||||
loc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the formatter, so as to release used resources.
|
||||
* If the underlying output stream supports the {@link Closeable}
|
||||
@@ -201,6 +386,16 @@ public final class Formatter
|
||||
{
|
||||
if (closed)
|
||||
return;
|
||||
try
|
||||
{
|
||||
if (out instanceof Closeable)
|
||||
((Closeable) out).close();
|
||||
}
|
||||
catch (IOException _)
|
||||
{
|
||||
// FIXME: do we ignore these or do we set ioException?
|
||||
// The docs seem to indicate that we should ignore.
|
||||
}
|
||||
closed = true;
|
||||
}
|
||||
|
||||
@@ -215,6 +410,16 @@ public final class Formatter
|
||||
{
|
||||
if (closed)
|
||||
throw new FormatterClosedException();
|
||||
try
|
||||
{
|
||||
if (out instanceof Flushable)
|
||||
((Flushable) out).flush();
|
||||
}
|
||||
catch (IOException _)
|
||||
{
|
||||
// FIXME: do we ignore these or do we set ioException?
|
||||
// The docs seem to indicate that we should ignore.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -544,9 +749,6 @@ public final class Formatter
|
||||
noPrecision(precision);
|
||||
|
||||
// Some error checking.
|
||||
if ((flags & FormattableFlags.ZERO) != 0
|
||||
&& (flags & FormattableFlags.LEFT_JUSTIFY) == 0)
|
||||
throw new IllegalFormatFlagsException(getName(flags));
|
||||
if ((flags & FormattableFlags.PLUS) != 0
|
||||
&& (flags & FormattableFlags.SPACE) != 0)
|
||||
throw new IllegalFormatFlagsException(getName(flags));
|
||||
@@ -984,7 +1186,7 @@ public final class Formatter
|
||||
advance();
|
||||
if (start == index)
|
||||
return -1;
|
||||
return Integer.decode(format.substring(start, index)).intValue();
|
||||
return Integer.decode(format.substring(start, index));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1090,7 +1292,7 @@ public final class Formatter
|
||||
* between it and the arguments.
|
||||
* @throws FormatterClosedException if the formatter is closed.
|
||||
*/
|
||||
public Formatter format(Locale loc, String fmt, Object[] args)
|
||||
public Formatter format(Locale loc, String fmt, Object... args)
|
||||
{
|
||||
if (closed)
|
||||
throw new FormatterClosedException();
|
||||
@@ -1233,7 +1435,7 @@ public final class Formatter
|
||||
* between it and the arguments.
|
||||
* @throws FormatterClosedException if the formatter is closed.
|
||||
*/
|
||||
public Formatter format(String format, Object[] args)
|
||||
public Formatter format(String format, Object... args)
|
||||
{
|
||||
return format(locale, format, args);
|
||||
}
|
||||
@@ -1269,7 +1471,7 @@ public final class Formatter
|
||||
* @return the formatter's output stream.
|
||||
* @throws FormatterClosedException if the formatter is closed.
|
||||
*/
|
||||
public StringBuilder out()
|
||||
public Appendable out()
|
||||
{
|
||||
if (closed)
|
||||
throw new FormatterClosedException();
|
||||
|
||||
@@ -935,11 +935,10 @@ public class GregorianCalendar extends Calendar
|
||||
fields[MONTH] += 12;
|
||||
fields[YEAR]--;
|
||||
}
|
||||
isTimeSet = false;
|
||||
int maxDay = getActualMaximum(DAY_OF_MONTH);
|
||||
if (fields[DAY_OF_MONTH] > maxDay)
|
||||
fields[DAY_OF_MONTH] = maxDay;
|
||||
set(YEAR, fields[YEAR]);
|
||||
set(MONTH, fields[MONTH]);
|
||||
break;
|
||||
case DAY_OF_MONTH:
|
||||
case DAY_OF_YEAR:
|
||||
|
||||
@@ -96,8 +96,8 @@ import java.io.Serializable;
|
||||
* @since 1.2
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public class HashMap extends AbstractMap
|
||||
implements Map, Cloneable, Serializable
|
||||
public class HashMap<K, V> extends AbstractMap<K, V>
|
||||
implements Map<K, V>, Cloneable, Serializable
|
||||
{
|
||||
/**
|
||||
* Default number of buckets. This is the value the JDK 1.3 uses. Some
|
||||
@@ -136,7 +136,7 @@ public class HashMap extends AbstractMap
|
||||
* Array containing the actual key-value mappings.
|
||||
* Package visible for use by nested and subclasses.
|
||||
*/
|
||||
transient HashEntry[] buckets;
|
||||
transient HashEntry<K, V>[] buckets;
|
||||
|
||||
/**
|
||||
* Counts the number of modifications this HashMap has undergone, used
|
||||
@@ -154,7 +154,7 @@ public class HashMap extends AbstractMap
|
||||
/**
|
||||
* The cache for {@link #entrySet()}.
|
||||
*/
|
||||
private transient Set entries;
|
||||
private transient Set<Map.Entry<K, V>> entries;
|
||||
|
||||
/**
|
||||
* Class to represent an entry in the hash table. Holds a single key-value
|
||||
@@ -162,19 +162,19 @@ public class HashMap extends AbstractMap
|
||||
*
|
||||
* @author Eric Blake (ebb9@email.byu.edu)
|
||||
*/
|
||||
static class HashEntry extends AbstractMap.BasicMapEntry
|
||||
static class HashEntry<K, V> extends AbstractMap.SimpleEntry<K, V>
|
||||
{
|
||||
/**
|
||||
* The next entry in the linked list. Package visible for use by subclass.
|
||||
*/
|
||||
HashEntry next;
|
||||
HashEntry<K, V> next;
|
||||
|
||||
/**
|
||||
* Simple constructor.
|
||||
* @param key the key
|
||||
* @param value the value
|
||||
*/
|
||||
HashEntry(Object key, Object value)
|
||||
HashEntry(K key, V value)
|
||||
{
|
||||
super(key, value);
|
||||
}
|
||||
@@ -194,7 +194,7 @@ public class HashMap extends AbstractMap
|
||||
*
|
||||
* @return the value of this key as it is removed
|
||||
*/
|
||||
Object cleanup()
|
||||
V cleanup()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
@@ -220,7 +220,7 @@ public class HashMap extends AbstractMap
|
||||
* <b>NOTE: key / value pairs are not cloned in this constructor.</b>
|
||||
* @throws NullPointerException if m is null
|
||||
*/
|
||||
public HashMap(Map m)
|
||||
public HashMap(Map<? extends K, ? extends V> m)
|
||||
{
|
||||
this(Math.max(m.size() * 2, DEFAULT_CAPACITY), DEFAULT_LOAD_FACTOR);
|
||||
putAll(m);
|
||||
@@ -256,7 +256,7 @@ public class HashMap extends AbstractMap
|
||||
|
||||
if (initialCapacity == 0)
|
||||
initialCapacity = 1;
|
||||
buckets = new HashEntry[initialCapacity];
|
||||
buckets = (HashEntry<K, V>[]) new HashEntry[initialCapacity];
|
||||
this.loadFactor = loadFactor;
|
||||
threshold = (int) (initialCapacity * loadFactor);
|
||||
}
|
||||
@@ -292,10 +292,10 @@ public class HashMap extends AbstractMap
|
||||
* @see #put(Object, Object)
|
||||
* @see #containsKey(Object)
|
||||
*/
|
||||
public Object get(Object key)
|
||||
public V get(Object key)
|
||||
{
|
||||
int idx = hash(key);
|
||||
HashEntry e = buckets[idx];
|
||||
HashEntry<K, V> e = buckets[idx];
|
||||
while (e != null)
|
||||
{
|
||||
if (equals(key, e.key))
|
||||
@@ -316,7 +316,7 @@ public class HashMap extends AbstractMap
|
||||
public boolean containsKey(Object key)
|
||||
{
|
||||
int idx = hash(key);
|
||||
HashEntry e = buckets[idx];
|
||||
HashEntry<K, V> e = buckets[idx];
|
||||
while (e != null)
|
||||
{
|
||||
if (equals(key, e.key))
|
||||
@@ -339,17 +339,17 @@ public class HashMap extends AbstractMap
|
||||
* @see #get(Object)
|
||||
* @see Object#equals(Object)
|
||||
*/
|
||||
public Object put(Object key, Object value)
|
||||
public V put(K key, V value)
|
||||
{
|
||||
int idx = hash(key);
|
||||
HashEntry e = buckets[idx];
|
||||
HashEntry<K, V> e = buckets[idx];
|
||||
|
||||
while (e != null)
|
||||
{
|
||||
if (equals(key, e.key))
|
||||
{
|
||||
e.access(); // Must call this for bookkeeping in LinkedHashMap.
|
||||
Object r = e.value;
|
||||
V r = e.value;
|
||||
e.value = value;
|
||||
return r;
|
||||
}
|
||||
@@ -378,23 +378,25 @@ public class HashMap extends AbstractMap
|
||||
*
|
||||
* @param m the map to be hashed into this
|
||||
*/
|
||||
public void putAll(Map m)
|
||||
public void putAll(Map<? extends K, ? extends V> m)
|
||||
{
|
||||
Iterator itr = m.entrySet().iterator();
|
||||
while (itr.hasNext())
|
||||
Map<K,V> addMap;
|
||||
|
||||
addMap = (Map<K,V>) m;
|
||||
for (Map.Entry<K,V> e : addMap.entrySet())
|
||||
{
|
||||
Map.Entry e = (Map.Entry) itr.next();
|
||||
// Optimize in case the Entry is one of our own.
|
||||
if (e instanceof AbstractMap.BasicMapEntry)
|
||||
if (e instanceof AbstractMap.SimpleEntry)
|
||||
{
|
||||
AbstractMap.BasicMapEntry entry = (AbstractMap.BasicMapEntry) e;
|
||||
AbstractMap.SimpleEntry<? extends K, ? extends V> entry
|
||||
= (AbstractMap.SimpleEntry<? extends K, ? extends V>) e;
|
||||
put(entry.key, entry.value);
|
||||
}
|
||||
else
|
||||
put(e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes from the HashMap and returns the value which is mapped by the
|
||||
* supplied key. If the key maps to nothing, then the HashMap remains
|
||||
@@ -405,11 +407,11 @@ public class HashMap extends AbstractMap
|
||||
* @param key the key used to locate the value to remove
|
||||
* @return whatever the key mapped to, if present
|
||||
*/
|
||||
public Object remove(Object key)
|
||||
public V remove(Object key)
|
||||
{
|
||||
int idx = hash(key);
|
||||
HashEntry e = buckets[idx];
|
||||
HashEntry last = null;
|
||||
HashEntry<K, V> e = buckets[idx];
|
||||
HashEntry<K, V> last = null;
|
||||
|
||||
while (e != null)
|
||||
{
|
||||
@@ -455,7 +457,7 @@ public class HashMap extends AbstractMap
|
||||
{
|
||||
for (int i = buckets.length - 1; i >= 0; i--)
|
||||
{
|
||||
HashEntry e = buckets[i];
|
||||
HashEntry<K, V> e = buckets[i];
|
||||
while (e != null)
|
||||
{
|
||||
if (equals(value, e.value))
|
||||
@@ -474,16 +476,16 @@ public class HashMap extends AbstractMap
|
||||
*/
|
||||
public Object clone()
|
||||
{
|
||||
HashMap copy = null;
|
||||
HashMap<K, V> copy = null;
|
||||
try
|
||||
{
|
||||
copy = (HashMap) super.clone();
|
||||
copy = (HashMap<K, V>) super.clone();
|
||||
}
|
||||
catch (CloneNotSupportedException x)
|
||||
{
|
||||
// This is impossible.
|
||||
}
|
||||
copy.buckets = new HashEntry[buckets.length];
|
||||
copy.buckets = (HashEntry<K, V>[]) new HashEntry[buckets.length];
|
||||
copy.putAllInternal(this);
|
||||
// Clear the entry cache. AbstractMap.clone() does the others.
|
||||
copy.entries = null;
|
||||
@@ -499,19 +501,19 @@ public class HashMap extends AbstractMap
|
||||
* @see #values()
|
||||
* @see #entrySet()
|
||||
*/
|
||||
public Set keySet()
|
||||
public Set<K> keySet()
|
||||
{
|
||||
if (keys == null)
|
||||
// Create an AbstractSet with custom implementations of those methods
|
||||
// that can be overridden easily and efficiently.
|
||||
keys = new AbstractSet()
|
||||
keys = new AbstractSet<K>()
|
||||
{
|
||||
public int size()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
public Iterator iterator()
|
||||
public Iterator<K> iterator()
|
||||
{
|
||||
// Cannot create the iterator directly, because of LinkedHashMap.
|
||||
return HashMap.this.iterator(KEYS);
|
||||
@@ -550,19 +552,19 @@ public class HashMap extends AbstractMap
|
||||
* @see #keySet()
|
||||
* @see #entrySet()
|
||||
*/
|
||||
public Collection values()
|
||||
public Collection<V> values()
|
||||
{
|
||||
if (values == null)
|
||||
// We don't bother overriding many of the optional methods, as doing so
|
||||
// wouldn't provide any significant performance advantage.
|
||||
values = new AbstractCollection()
|
||||
values = new AbstractCollection<V>()
|
||||
{
|
||||
public int size()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
public Iterator iterator()
|
||||
public Iterator<V> iterator()
|
||||
{
|
||||
// Cannot create the iterator directly, because of LinkedHashMap.
|
||||
return HashMap.this.iterator(VALUES);
|
||||
@@ -589,19 +591,19 @@ public class HashMap extends AbstractMap
|
||||
* @see #values()
|
||||
* @see Map.Entry
|
||||
*/
|
||||
public Set entrySet()
|
||||
public Set<Map.Entry<K, V>> entrySet()
|
||||
{
|
||||
if (entries == null)
|
||||
// Create an AbstractSet with custom implementations of those methods
|
||||
// that can be overridden easily and efficiently.
|
||||
entries = new AbstractSet()
|
||||
entries = new AbstractSet<Map.Entry<K, V>>()
|
||||
{
|
||||
public int size()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
public Iterator iterator()
|
||||
public Iterator<Map.Entry<K, V>> iterator()
|
||||
{
|
||||
// Cannot create the iterator directly, because of LinkedHashMap.
|
||||
return HashMap.this.iterator(ENTRIES);
|
||||
@@ -619,7 +621,7 @@ public class HashMap extends AbstractMap
|
||||
|
||||
public boolean remove(Object o)
|
||||
{
|
||||
HashEntry e = getEntry(o);
|
||||
HashEntry<K, V> e = getEntry(o);
|
||||
if (e != null)
|
||||
{
|
||||
HashMap.this.remove(e.key);
|
||||
@@ -641,9 +643,9 @@ public class HashMap extends AbstractMap
|
||||
* @param callRemove whether to call the removeEldestEntry method
|
||||
* @see #put(Object, Object)
|
||||
*/
|
||||
void addEntry(Object key, Object value, int idx, boolean callRemove)
|
||||
void addEntry(K key, V value, int idx, boolean callRemove)
|
||||
{
|
||||
HashEntry e = new HashEntry(key, value);
|
||||
HashEntry<K, V> e = new HashEntry<K, V>(key, value);
|
||||
e.next = buckets[idx];
|
||||
buckets[idx] = e;
|
||||
}
|
||||
@@ -657,14 +659,14 @@ public class HashMap extends AbstractMap
|
||||
* @see #entrySet()
|
||||
*/
|
||||
// Package visible, for use in nested classes.
|
||||
final HashEntry getEntry(Object o)
|
||||
final HashEntry<K, V> getEntry(Object o)
|
||||
{
|
||||
if (! (o instanceof Map.Entry))
|
||||
return null;
|
||||
Map.Entry me = (Map.Entry) o;
|
||||
Object key = me.getKey();
|
||||
Map.Entry<K, V> me = (Map.Entry<K, V>) o;
|
||||
K key = me.getKey();
|
||||
int idx = hash(key);
|
||||
HashEntry e = buckets[idx];
|
||||
HashEntry<K, V> e = buckets[idx];
|
||||
while (e != null)
|
||||
{
|
||||
if (equals(e.key, key))
|
||||
@@ -693,9 +695,10 @@ public class HashMap extends AbstractMap
|
||||
* @param type {@link #KEYS}, {@link #VALUES}, or {@link #ENTRIES}
|
||||
* @return the appropriate iterator
|
||||
*/
|
||||
Iterator iterator(int type)
|
||||
<T> Iterator<T> iterator(int type)
|
||||
{
|
||||
return new HashIterator(type);
|
||||
// FIXME: bogus cast here.
|
||||
return new HashIterator<T>(type);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -705,15 +708,16 @@ public class HashMap extends AbstractMap
|
||||
*
|
||||
* @param m the map to initialize this from
|
||||
*/
|
||||
void putAllInternal(Map m)
|
||||
void putAllInternal(Map<? extends K, ? extends V> m)
|
||||
{
|
||||
Iterator itr = m.entrySet().iterator();
|
||||
Map<K,V> addMap;
|
||||
|
||||
addMap = (Map<K,V>) m;
|
||||
size = 0;
|
||||
while (itr.hasNext())
|
||||
for (Map.Entry<K,V> e : addMap.entrySet())
|
||||
{
|
||||
size++;
|
||||
Map.Entry e = (Map.Entry) itr.next();
|
||||
Object key = e.getKey();
|
||||
K key = e.getKey();
|
||||
int idx = hash(key);
|
||||
addEntry(key, e.getValue(), idx, false);
|
||||
}
|
||||
@@ -730,20 +734,20 @@ public class HashMap extends AbstractMap
|
||||
*/
|
||||
private void rehash()
|
||||
{
|
||||
HashEntry[] oldBuckets = buckets;
|
||||
HashEntry<K, V>[] oldBuckets = buckets;
|
||||
|
||||
int newcapacity = (buckets.length * 2) + 1;
|
||||
threshold = (int) (newcapacity * loadFactor);
|
||||
buckets = new HashEntry[newcapacity];
|
||||
buckets = (HashEntry<K, V>[]) new HashEntry[newcapacity];
|
||||
|
||||
for (int i = oldBuckets.length - 1; i >= 0; i--)
|
||||
{
|
||||
HashEntry e = oldBuckets[i];
|
||||
HashEntry<K, V> e = oldBuckets[i];
|
||||
while (e != null)
|
||||
{
|
||||
int idx = hash(e.key);
|
||||
HashEntry dest = buckets[idx];
|
||||
HashEntry next = e.next;
|
||||
HashEntry<K, V> dest = buckets[idx];
|
||||
HashEntry<K, V> next = e.next;
|
||||
e.next = buckets[idx];
|
||||
buckets[idx] = e;
|
||||
e = next;
|
||||
@@ -769,10 +773,10 @@ public class HashMap extends AbstractMap
|
||||
s.writeInt(buckets.length);
|
||||
s.writeInt(size);
|
||||
// Avoid creating a wasted Set by creating the iterator directly.
|
||||
Iterator it = iterator(ENTRIES);
|
||||
Iterator<HashEntry<K, V>> it = iterator(ENTRIES);
|
||||
while (it.hasNext())
|
||||
{
|
||||
HashEntry entry = (HashEntry) it.next();
|
||||
HashEntry<K, V> entry = it.next();
|
||||
s.writeObject(entry.key);
|
||||
s.writeObject(entry.value);
|
||||
}
|
||||
@@ -796,13 +800,13 @@ public class HashMap extends AbstractMap
|
||||
s.defaultReadObject();
|
||||
|
||||
// Read and use capacity, followed by key/value pairs.
|
||||
buckets = new HashEntry[s.readInt()];
|
||||
buckets = (HashEntry<K, V>[]) new HashEntry[s.readInt()];
|
||||
int len = s.readInt();
|
||||
size = len;
|
||||
while (len-- > 0)
|
||||
{
|
||||
Object key = s.readObject();
|
||||
addEntry(key, s.readObject(), hash(key), false);
|
||||
addEntry((K) key, (V) s.readObject(), hash(key), false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -813,7 +817,7 @@ public class HashMap extends AbstractMap
|
||||
*
|
||||
* @author Jon Zeppieri
|
||||
*/
|
||||
private final class HashIterator implements Iterator
|
||||
private final class HashIterator<T> implements Iterator<T>
|
||||
{
|
||||
/**
|
||||
* The type of this Iterator: {@link #KEYS}, {@link #VALUES},
|
||||
@@ -861,7 +865,7 @@ public class HashMap extends AbstractMap
|
||||
* @throws ConcurrentModificationException if the HashMap was modified
|
||||
* @throws NoSuchElementException if there is none
|
||||
*/
|
||||
public Object next()
|
||||
public T next()
|
||||
{
|
||||
if (knownMod != modCount)
|
||||
throw new ConcurrentModificationException();
|
||||
@@ -876,10 +880,10 @@ public class HashMap extends AbstractMap
|
||||
next = e.next;
|
||||
last = e;
|
||||
if (type == VALUES)
|
||||
return e.value;
|
||||
return (T) e.value;
|
||||
if (type == KEYS)
|
||||
return e.key;
|
||||
return e;
|
||||
return (T) e.key;
|
||||
return (T) e;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -76,8 +76,8 @@ import java.io.Serializable;
|
||||
* @since 1.2
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public class HashSet extends AbstractSet
|
||||
implements Set, Cloneable, Serializable
|
||||
public class HashSet<T> extends AbstractSet<T>
|
||||
implements Set<T>, Cloneable, Serializable
|
||||
{
|
||||
/**
|
||||
* Compatible with JDK 1.2.
|
||||
@@ -87,7 +87,7 @@ public class HashSet extends AbstractSet
|
||||
/**
|
||||
* The HashMap which backs this Set.
|
||||
*/
|
||||
private transient HashMap map;
|
||||
private transient HashMap<T, String> map;
|
||||
|
||||
/**
|
||||
* Construct a new, empty HashSet whose backing HashMap has the default
|
||||
@@ -133,7 +133,7 @@ public class HashSet extends AbstractSet
|
||||
* @param c a collection of initial set elements
|
||||
* @throws NullPointerException if c is null
|
||||
*/
|
||||
public HashSet(Collection c)
|
||||
public HashSet(Collection<? extends T> c)
|
||||
{
|
||||
this(Math.max(2 * c.size(), HashMap.DEFAULT_CAPACITY));
|
||||
addAll(c);
|
||||
@@ -146,7 +146,7 @@ public class HashSet extends AbstractSet
|
||||
* @param o the Object to add to this Set
|
||||
* @return true if the set did not already contain o
|
||||
*/
|
||||
public boolean add(Object o)
|
||||
public boolean add(T o)
|
||||
{
|
||||
return map.put(o, "") == null;
|
||||
}
|
||||
@@ -167,16 +167,16 @@ public class HashSet extends AbstractSet
|
||||
*/
|
||||
public Object clone()
|
||||
{
|
||||
HashSet copy = null;
|
||||
HashSet<T> copy = null;
|
||||
try
|
||||
{
|
||||
copy = (HashSet) super.clone();
|
||||
copy = (HashSet<T>) super.clone();
|
||||
}
|
||||
catch (CloneNotSupportedException x)
|
||||
{
|
||||
// Impossible to get here.
|
||||
}
|
||||
copy.map = (HashMap) map.clone();
|
||||
copy.map = (HashMap<T, String>) map.clone();
|
||||
return copy;
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ public class HashSet extends AbstractSet
|
||||
* @return a set iterator
|
||||
* @see ConcurrentModificationException
|
||||
*/
|
||||
public Iterator iterator()
|
||||
public Iterator<T> iterator()
|
||||
{
|
||||
// Avoid creating intermediate keySet() object by using non-public API.
|
||||
return map.iterator(HashMap.KEYS);
|
||||
@@ -263,7 +263,7 @@ public class HashSet extends AbstractSet
|
||||
{
|
||||
s.defaultWriteObject();
|
||||
// Avoid creating intermediate keySet() object by using non-public API.
|
||||
Iterator it = map.iterator(HashMap.KEYS);
|
||||
Iterator<T> it = map.iterator(HashMap.KEYS);
|
||||
s.writeInt(map.buckets.length);
|
||||
s.writeFloat(map.loadFactor);
|
||||
s.writeInt(map.size);
|
||||
@@ -288,6 +288,6 @@ public class HashSet extends AbstractSet
|
||||
|
||||
map = init(s.readInt(), s.readFloat());
|
||||
for (int size = s.readInt(); size > 0; size--)
|
||||
map.put(s.readObject(), "");
|
||||
map.put((T) s.readObject(), "");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,8 +100,8 @@ import java.io.Serializable;
|
||||
* @since 1.0
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public class Hashtable extends Dictionary
|
||||
implements Map, Cloneable, Serializable
|
||||
public class Hashtable<K, V> extends Dictionary<K, V>
|
||||
implements Map<K, V>, Cloneable, Serializable
|
||||
{
|
||||
// WARNING: Hashtable is a CORE class in the bootstrap cycle. See the
|
||||
// comments in vm/reference/java/lang/Runtime for implications of this fact.
|
||||
@@ -139,7 +139,7 @@ public class Hashtable extends Dictionary
|
||||
* Array containing the actual key-value mappings.
|
||||
*/
|
||||
// Package visible for use by nested classes.
|
||||
transient HashEntry[] buckets;
|
||||
transient HashEntry<K, V>[] buckets;
|
||||
|
||||
/**
|
||||
* Counts the number of modifications this Hashtable has undergone, used
|
||||
@@ -157,34 +157,35 @@ public class Hashtable extends Dictionary
|
||||
/**
|
||||
* The cache for {@link #keySet()}.
|
||||
*/
|
||||
private transient Set keys;
|
||||
private transient Set<K> keys;
|
||||
|
||||
/**
|
||||
* The cache for {@link #values()}.
|
||||
*/
|
||||
private transient Collection values;
|
||||
private transient Collection<V> values;
|
||||
|
||||
/**
|
||||
* The cache for {@link #entrySet()}.
|
||||
*/
|
||||
private transient Set entries;
|
||||
private transient Set<Map.Entry<K, V>> entries;
|
||||
|
||||
/**
|
||||
* Class to represent an entry in the hash table. Holds a single key-value
|
||||
* pair. A Hashtable Entry is identical to a HashMap Entry, except that
|
||||
* `null' is not allowed for keys and values.
|
||||
*/
|
||||
private static final class HashEntry extends AbstractMap.BasicMapEntry
|
||||
private static final class HashEntry<K, V>
|
||||
extends AbstractMap.SimpleEntry<K, V>
|
||||
{
|
||||
/** The next entry in the linked list. */
|
||||
HashEntry next;
|
||||
HashEntry<K, V> next;
|
||||
|
||||
/**
|
||||
* Simple constructor.
|
||||
* @param key the key, already guaranteed non-null
|
||||
* @param value the value, already guaranteed non-null
|
||||
*/
|
||||
HashEntry(Object key, Object value)
|
||||
HashEntry(K key, V value)
|
||||
{
|
||||
super(key, value);
|
||||
}
|
||||
@@ -195,7 +196,7 @@ public class Hashtable extends Dictionary
|
||||
* @return the prior value
|
||||
* @throws NullPointerException if <code>newVal</code> is null
|
||||
*/
|
||||
public Object setValue(Object newVal)
|
||||
public V setValue(V newVal)
|
||||
{
|
||||
if (newVal == null)
|
||||
throw new NullPointerException();
|
||||
@@ -226,7 +227,7 @@ public class Hashtable extends Dictionary
|
||||
* to or from `null'.
|
||||
* @since 1.2
|
||||
*/
|
||||
public Hashtable(Map m)
|
||||
public Hashtable(Map<? extends K, ? extends V> m)
|
||||
{
|
||||
this(Math.max(m.size() * 2, DEFAULT_CAPACITY), DEFAULT_LOAD_FACTOR);
|
||||
putAll(m);
|
||||
@@ -263,7 +264,7 @@ public class Hashtable extends Dictionary
|
||||
|
||||
if (initialCapacity == 0)
|
||||
initialCapacity = 1;
|
||||
buckets = new HashEntry[initialCapacity];
|
||||
buckets = (HashEntry<K, V>[]) new HashEntry[initialCapacity];
|
||||
this.loadFactor = loadFactor;
|
||||
threshold = (int) (initialCapacity * loadFactor);
|
||||
}
|
||||
@@ -295,7 +296,7 @@ public class Hashtable extends Dictionary
|
||||
* @see #elements()
|
||||
* @see #keySet()
|
||||
*/
|
||||
public Enumeration keys()
|
||||
public Enumeration<K> keys()
|
||||
{
|
||||
return new KeyEnumerator();
|
||||
}
|
||||
@@ -309,7 +310,7 @@ public class Hashtable extends Dictionary
|
||||
* @see #keys()
|
||||
* @see #values()
|
||||
*/
|
||||
public Enumeration elements()
|
||||
public Enumeration<V> elements()
|
||||
{
|
||||
return new ValueEnumerator();
|
||||
}
|
||||
@@ -333,7 +334,7 @@ public class Hashtable extends Dictionary
|
||||
|
||||
for (int i = buckets.length - 1; i >= 0; i--)
|
||||
{
|
||||
HashEntry e = buckets[i];
|
||||
HashEntry<K, V> e = buckets[i];
|
||||
while (e != null)
|
||||
{
|
||||
if (e.value.equals(value))
|
||||
@@ -341,7 +342,7 @@ public class Hashtable extends Dictionary
|
||||
e = e.next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -376,7 +377,7 @@ public class Hashtable extends Dictionary
|
||||
public synchronized boolean containsKey(Object key)
|
||||
{
|
||||
int idx = hash(key);
|
||||
HashEntry e = buckets[idx];
|
||||
HashEntry<K, V> e = buckets[idx];
|
||||
while (e != null)
|
||||
{
|
||||
if (e.key.equals(key))
|
||||
@@ -396,10 +397,10 @@ public class Hashtable extends Dictionary
|
||||
* @see #put(Object, Object)
|
||||
* @see #containsKey(Object)
|
||||
*/
|
||||
public synchronized Object get(Object key)
|
||||
public synchronized V get(Object key)
|
||||
{
|
||||
int idx = hash(key);
|
||||
HashEntry e = buckets[idx];
|
||||
HashEntry<K, V> e = buckets[idx];
|
||||
while (e != null)
|
||||
{
|
||||
if (e.key.equals(key))
|
||||
@@ -421,10 +422,10 @@ public class Hashtable extends Dictionary
|
||||
* @see #get(Object)
|
||||
* @see Object#equals(Object)
|
||||
*/
|
||||
public synchronized Object put(Object key, Object value)
|
||||
public synchronized V put(K key, V value)
|
||||
{
|
||||
int idx = hash(key);
|
||||
HashEntry e = buckets[idx];
|
||||
HashEntry<K, V> e = buckets[idx];
|
||||
|
||||
// Check if value is null since it is not permitted.
|
||||
if (value == null)
|
||||
@@ -435,7 +436,7 @@ public class Hashtable extends Dictionary
|
||||
if (e.key.equals(key))
|
||||
{
|
||||
// Bypass e.setValue, since we already know value is non-null.
|
||||
Object r = e.value;
|
||||
V r = e.value;
|
||||
e.value = value;
|
||||
return r;
|
||||
}
|
||||
@@ -454,7 +455,7 @@ public class Hashtable extends Dictionary
|
||||
idx = hash(key);
|
||||
}
|
||||
|
||||
e = new HashEntry(key, value);
|
||||
e = new HashEntry<K, V>(key, value);
|
||||
|
||||
e.next = buckets[idx];
|
||||
buckets[idx] = e;
|
||||
@@ -470,11 +471,11 @@ public class Hashtable extends Dictionary
|
||||
* @param key the key used to locate the value to remove
|
||||
* @return whatever the key mapped to, if present
|
||||
*/
|
||||
public synchronized Object remove(Object key)
|
||||
public synchronized V remove(Object key)
|
||||
{
|
||||
int idx = hash(key);
|
||||
HashEntry e = buckets[idx];
|
||||
HashEntry last = null;
|
||||
HashEntry<K, V> e = buckets[idx];
|
||||
HashEntry<K, V> last = null;
|
||||
|
||||
while (e != null)
|
||||
{
|
||||
@@ -502,17 +503,19 @@ public class Hashtable extends Dictionary
|
||||
* @param m the map to be hashed into this
|
||||
* @throws NullPointerException if m is null, or contains null keys or values
|
||||
*/
|
||||
public synchronized void putAll(Map m)
|
||||
public synchronized void putAll(Map<? extends K, ? extends V> m)
|
||||
{
|
||||
Iterator itr = m.entrySet().iterator();
|
||||
Map<K,V> addMap;
|
||||
|
||||
addMap = (Map<K,V>) m;
|
||||
|
||||
while (itr.hasNext())
|
||||
for (Map.Entry<K,V> e : addMap.entrySet())
|
||||
{
|
||||
Map.Entry e = (Map.Entry) itr.next();
|
||||
// Optimize in case the Entry is one of our own.
|
||||
if (e instanceof AbstractMap.BasicMapEntry)
|
||||
if (e instanceof AbstractMap.SimpleEntry)
|
||||
{
|
||||
AbstractMap.BasicMapEntry entry = (AbstractMap.BasicMapEntry) e;
|
||||
AbstractMap.SimpleEntry<? extends K, ? extends V> entry
|
||||
= (AbstractMap.SimpleEntry<? extends K, ? extends V>) e;
|
||||
put(entry.key, entry.value);
|
||||
}
|
||||
else
|
||||
@@ -543,16 +546,16 @@ public class Hashtable extends Dictionary
|
||||
*/
|
||||
public synchronized Object clone()
|
||||
{
|
||||
Hashtable copy = null;
|
||||
Hashtable<K, V> copy = null;
|
||||
try
|
||||
{
|
||||
copy = (Hashtable) super.clone();
|
||||
copy = (Hashtable<K, V>) super.clone();
|
||||
}
|
||||
catch (CloneNotSupportedException x)
|
||||
{
|
||||
// This is impossible.
|
||||
}
|
||||
copy.buckets = new HashEntry[buckets.length];
|
||||
copy.buckets = (HashEntry<K, V>[]) new HashEntry[buckets.length];
|
||||
copy.putAllInternal(this);
|
||||
// Clear the caches.
|
||||
copy.keys = null;
|
||||
@@ -576,7 +579,7 @@ public class Hashtable extends Dictionary
|
||||
// Since we are already synchronized, and entrySet().iterator()
|
||||
// would repeatedly re-lock/release the monitor, we directly use the
|
||||
// unsynchronized EntryIterator instead.
|
||||
Iterator entries = new EntryIterator();
|
||||
Iterator<Map.Entry<K, V>> entries = new EntryIterator();
|
||||
StringBuffer r = new StringBuffer("{");
|
||||
for (int pos = size; pos > 0; pos--)
|
||||
{
|
||||
@@ -603,20 +606,20 @@ public class Hashtable extends Dictionary
|
||||
* @see #entrySet()
|
||||
* @since 1.2
|
||||
*/
|
||||
public Set keySet()
|
||||
public Set<K> keySet()
|
||||
{
|
||||
if (keys == null)
|
||||
{
|
||||
// Create a synchronized AbstractSet with custom implementations of
|
||||
// those methods that can be overridden easily and efficiently.
|
||||
Set r = new AbstractSet()
|
||||
Set<K> r = new AbstractSet<K>()
|
||||
{
|
||||
public int size()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
public Iterator iterator()
|
||||
public Iterator<K> iterator()
|
||||
{
|
||||
return new KeyIterator();
|
||||
}
|
||||
@@ -640,7 +643,7 @@ public class Hashtable extends Dictionary
|
||||
};
|
||||
// We must specify the correct object to synchronize upon, hence the
|
||||
// use of a non-public API
|
||||
keys = new Collections.SynchronizedSet(this, r);
|
||||
keys = new Collections.SynchronizedSet<K>(this, r);
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
@@ -661,20 +664,20 @@ public class Hashtable extends Dictionary
|
||||
* @see #entrySet()
|
||||
* @since 1.2
|
||||
*/
|
||||
public Collection values()
|
||||
public Collection<V> values()
|
||||
{
|
||||
if (values == null)
|
||||
{
|
||||
// We don't bother overriding many of the optional methods, as doing so
|
||||
// wouldn't provide any significant performance advantage.
|
||||
Collection r = new AbstractCollection()
|
||||
Collection<V> r = new AbstractCollection<V>()
|
||||
{
|
||||
public int size()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
public Iterator iterator()
|
||||
public Iterator<V> iterator()
|
||||
{
|
||||
return new ValueIterator();
|
||||
}
|
||||
@@ -686,7 +689,7 @@ public class Hashtable extends Dictionary
|
||||
};
|
||||
// We must specify the correct object to synchronize upon, hence the
|
||||
// use of a non-public API
|
||||
values = new Collections.SynchronizedCollection(this, r);
|
||||
values = new Collections.SynchronizedCollection<V>(this, r);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
@@ -713,20 +716,20 @@ public class Hashtable extends Dictionary
|
||||
* @see Map.Entry
|
||||
* @since 1.2
|
||||
*/
|
||||
public Set entrySet()
|
||||
public Set<Map.Entry<K, V>> entrySet()
|
||||
{
|
||||
if (entries == null)
|
||||
{
|
||||
// Create an AbstractSet with custom implementations of those methods
|
||||
// that can be overridden easily and efficiently.
|
||||
Set r = new AbstractSet()
|
||||
Set<Map.Entry<K, V>> r = new AbstractSet<Map.Entry<K, V>>()
|
||||
{
|
||||
public int size()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
public Iterator iterator()
|
||||
public Iterator<Map.Entry<K, V>> iterator()
|
||||
{
|
||||
return new EntryIterator();
|
||||
}
|
||||
@@ -743,7 +746,7 @@ public class Hashtable extends Dictionary
|
||||
|
||||
public boolean remove(Object o)
|
||||
{
|
||||
HashEntry e = getEntry(o);
|
||||
HashEntry<K, V> e = getEntry(o);
|
||||
if (e != null)
|
||||
{
|
||||
Hashtable.this.remove(e.key);
|
||||
@@ -754,7 +757,7 @@ public class Hashtable extends Dictionary
|
||||
};
|
||||
// We must specify the correct object to synchronize upon, hence the
|
||||
// use of a non-public API
|
||||
entries = new Collections.SynchronizedSet(this, r);
|
||||
entries = new Collections.SynchronizedSet<Map.Entry<K, V>>(this, r);
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
@@ -772,7 +775,7 @@ public class Hashtable extends Dictionary
|
||||
*/
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
// no need to synchronize, entrySet().equals() does that
|
||||
// no need to synchronize, entrySet().equals() does that.
|
||||
if (o == this)
|
||||
return true;
|
||||
if (!(o instanceof Map))
|
||||
@@ -793,7 +796,7 @@ public class Hashtable extends Dictionary
|
||||
// Since we are already synchronized, and entrySet().iterator()
|
||||
// would repeatedly re-lock/release the monitor, we directly use the
|
||||
// unsynchronized EntryIterator instead.
|
||||
Iterator itr = new EntryIterator();
|
||||
Iterator<Map.Entry<K, V>> itr = new EntryIterator();
|
||||
int hashcode = 0;
|
||||
for (int pos = size; pos > 0; pos--)
|
||||
hashcode += itr.next().hashCode();
|
||||
@@ -826,16 +829,16 @@ public class Hashtable extends Dictionary
|
||||
* @see #entrySet()
|
||||
*/
|
||||
// Package visible, for use in nested classes.
|
||||
HashEntry getEntry(Object o)
|
||||
HashEntry<K, V> getEntry(Object o)
|
||||
{
|
||||
if (! (o instanceof Map.Entry))
|
||||
return null;
|
||||
Object key = ((Map.Entry) o).getKey();
|
||||
K key = ((Map.Entry<K, V>) o).getKey();
|
||||
if (key == null)
|
||||
return null;
|
||||
|
||||
int idx = hash(key);
|
||||
HashEntry e = buckets[idx];
|
||||
HashEntry<K, V> e = buckets[idx];
|
||||
while (e != null)
|
||||
{
|
||||
if (e.equals(o))
|
||||
@@ -852,18 +855,19 @@ public class Hashtable extends Dictionary
|
||||
*
|
||||
* @param m the map to initialize this from
|
||||
*/
|
||||
void putAllInternal(Map m)
|
||||
void putAllInternal(Map<? extends K, ? extends V> m)
|
||||
{
|
||||
Iterator itr = m.entrySet().iterator();
|
||||
Map<K,V> addMap;
|
||||
|
||||
addMap = (Map<K,V>) m;
|
||||
size = 0;
|
||||
|
||||
while (itr.hasNext())
|
||||
for (Map.Entry<K,V> e : addMap.entrySet())
|
||||
{
|
||||
size++;
|
||||
Map.Entry e = (Map.Entry) itr.next();
|
||||
Object key = e.getKey();
|
||||
K key = e.getKey();
|
||||
int idx = hash(key);
|
||||
HashEntry he = new HashEntry(key, e.getValue());
|
||||
HashEntry<K, V> he = new HashEntry<K, V>(key, e.getValue());
|
||||
he.next = buckets[idx];
|
||||
buckets[idx] = he;
|
||||
}
|
||||
@@ -882,19 +886,19 @@ public class Hashtable extends Dictionary
|
||||
*/
|
||||
protected void rehash()
|
||||
{
|
||||
HashEntry[] oldBuckets = buckets;
|
||||
HashEntry<K, V>[] oldBuckets = buckets;
|
||||
|
||||
int newcapacity = (buckets.length * 2) + 1;
|
||||
threshold = (int) (newcapacity * loadFactor);
|
||||
buckets = new HashEntry[newcapacity];
|
||||
buckets = (HashEntry<K, V>[]) new HashEntry[newcapacity];
|
||||
|
||||
for (int i = oldBuckets.length - 1; i >= 0; i--)
|
||||
{
|
||||
HashEntry e = oldBuckets[i];
|
||||
HashEntry<K, V> e = oldBuckets[i];
|
||||
while (e != null)
|
||||
{
|
||||
int idx = hash(e.key);
|
||||
HashEntry dest = buckets[idx];
|
||||
HashEntry<K, V> dest = buckets[idx];
|
||||
|
||||
if (dest != null)
|
||||
{
|
||||
@@ -911,7 +915,7 @@ public class Hashtable extends Dictionary
|
||||
buckets[idx] = e;
|
||||
}
|
||||
|
||||
HashEntry next = e.next;
|
||||
HashEntry<K, V> next = e.next;
|
||||
e.next = null;
|
||||
e = next;
|
||||
}
|
||||
@@ -939,10 +943,10 @@ public class Hashtable extends Dictionary
|
||||
// Since we are already synchronized, and entrySet().iterator()
|
||||
// would repeatedly re-lock/release the monitor, we directly use the
|
||||
// unsynchronized EntryIterator instead.
|
||||
Iterator it = new EntryIterator();
|
||||
Iterator<Map.Entry<K, V>> it = new EntryIterator();
|
||||
while (it.hasNext())
|
||||
{
|
||||
HashEntry entry = (HashEntry) it.next();
|
||||
HashEntry<K, V> entry = (HashEntry<K, V>) it.next();
|
||||
s.writeObject(entry.key);
|
||||
s.writeObject(entry.value);
|
||||
}
|
||||
@@ -966,13 +970,13 @@ public class Hashtable extends Dictionary
|
||||
s.defaultReadObject();
|
||||
|
||||
// Read and use capacity.
|
||||
buckets = new HashEntry[s.readInt()];
|
||||
buckets = (HashEntry<K, V>[]) new HashEntry[s.readInt()];
|
||||
int len = s.readInt();
|
||||
|
||||
// Read and use key/value pairs.
|
||||
// TODO: should we be defensive programmers, and check for illegal nulls?
|
||||
while (--len >= 0)
|
||||
put(s.readObject(), s.readObject());
|
||||
put((K) s.readObject(), (V) s.readObject());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -987,7 +991,8 @@ public class Hashtable extends Dictionary
|
||||
* @author Jon Zeppieri
|
||||
* @author Fridjof Siebert
|
||||
*/
|
||||
private class EntryIterator implements Iterator
|
||||
private class EntryIterator
|
||||
implements Iterator<Entry<K,V>>
|
||||
{
|
||||
/**
|
||||
* The number of modifications to the backing Hashtable that we know about.
|
||||
@@ -998,16 +1003,16 @@ public class Hashtable extends Dictionary
|
||||
/** Current index in the physical hash table. */
|
||||
int idx = buckets.length;
|
||||
/** The last Entry returned by a next() call. */
|
||||
HashEntry last;
|
||||
HashEntry<K, V> last;
|
||||
/**
|
||||
* The next entry that should be returned by next(). It is set to something
|
||||
* if we're iterating through a bucket that contains multiple linked
|
||||
* entries. It is null if next() needs to find a new bucket.
|
||||
*/
|
||||
HashEntry next;
|
||||
HashEntry<K, V> next;
|
||||
|
||||
/**
|
||||
* Construct a new EtryIterator
|
||||
* Construct a new EntryIterator
|
||||
*/
|
||||
EntryIterator()
|
||||
{
|
||||
@@ -1029,14 +1034,14 @@ public class Hashtable extends Dictionary
|
||||
* @throws ConcurrentModificationException if the hashtable was modified
|
||||
* @throws NoSuchElementException if there is none
|
||||
*/
|
||||
public Object next()
|
||||
public Map.Entry<K,V> next()
|
||||
{
|
||||
if (knownMod != modCount)
|
||||
throw new ConcurrentModificationException();
|
||||
if (count == 0)
|
||||
throw new NoSuchElementException();
|
||||
count--;
|
||||
HashEntry e = next;
|
||||
HashEntry<K, V> e = next;
|
||||
|
||||
while (e == null)
|
||||
if (idx <= 0)
|
||||
@@ -1070,12 +1075,43 @@ public class Hashtable extends Dictionary
|
||||
|
||||
/**
|
||||
* A class which implements the Iterator interface and is used for
|
||||
* iterating over keys in Hashtables.
|
||||
* iterating over keys in Hashtables. This class uses an
|
||||
* <code>EntryIterator</code> to obtain the keys of each entry.
|
||||
*
|
||||
* @author Fridtjof Siebert
|
||||
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
|
||||
*/
|
||||
private class KeyIterator extends EntryIterator
|
||||
private class KeyIterator
|
||||
implements Iterator<K>
|
||||
{
|
||||
|
||||
/**
|
||||
* This entry iterator is used for most operations. Only
|
||||
* <code>next()</code> gives a different result, by returning just
|
||||
* the key rather than the whole element.
|
||||
*/
|
||||
private EntryIterator iterator;
|
||||
|
||||
/**
|
||||
* Construct a new KeyIterator
|
||||
*/
|
||||
KeyIterator()
|
||||
{
|
||||
iterator = new EntryIterator();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the entry iterator has more elements.
|
||||
*
|
||||
* @return true if there are more elements
|
||||
* @throws ConcurrentModificationException if the hashtable was modified
|
||||
*/
|
||||
public boolean hasNext()
|
||||
{
|
||||
return iterator.hasNext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next element in the Iterator's sequential view.
|
||||
*
|
||||
@@ -1084,34 +1120,88 @@ public class Hashtable extends Dictionary
|
||||
* @throws ConcurrentModificationException if the hashtable was modified
|
||||
* @throws NoSuchElementException if there is none
|
||||
*/
|
||||
public Object next()
|
||||
public K next()
|
||||
{
|
||||
return ((HashEntry)super.next()).key;
|
||||
return ((HashEntry<K,V>) iterator.next()).key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the last element used by the <code>next()</code> method
|
||||
* using the entry iterator.
|
||||
*
|
||||
* @throws ConcurrentModificationException if the hashtable was modified
|
||||
* @throws IllegalStateException if called when there is no last element
|
||||
*/
|
||||
public void remove()
|
||||
{
|
||||
iterator.remove();
|
||||
}
|
||||
} // class KeyIterator
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A class which implements the Iterator interface and is used for
|
||||
* iterating over values in Hashtables.
|
||||
* iterating over values in Hashtables. This class uses an
|
||||
* <code>EntryIterator</code> to obtain the values of each entry.
|
||||
*
|
||||
* @author Fridtjof Siebert
|
||||
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
|
||||
*/
|
||||
private class ValueIterator extends EntryIterator
|
||||
private class ValueIterator
|
||||
implements Iterator<V>
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns the next element in the Iterator's sequential view.
|
||||
* This entry iterator is used for most operations. Only
|
||||
* <code>next()</code> gives a different result, by returning just
|
||||
* the value rather than the whole element.
|
||||
*/
|
||||
private EntryIterator iterator;
|
||||
|
||||
/**
|
||||
* Construct a new KeyIterator
|
||||
*/
|
||||
ValueIterator()
|
||||
{
|
||||
iterator = new EntryIterator();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the entry iterator has more elements.
|
||||
*
|
||||
* @return the next element
|
||||
* @return true if there are more elements
|
||||
* @throws ConcurrentModificationException if the hashtable was modified
|
||||
*/
|
||||
public boolean hasNext()
|
||||
{
|
||||
return iterator.hasNext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the next element in the iterator's sequential view.
|
||||
*
|
||||
* @return the next value
|
||||
*
|
||||
* @throws ConcurrentModificationException if the hashtable was modified
|
||||
* @throws NoSuchElementException if there is none
|
||||
*/
|
||||
public Object next()
|
||||
public V next()
|
||||
{
|
||||
return ((HashEntry)super.next()).value;
|
||||
return ((HashEntry<K,V>) iterator.next()).value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the last element used by the <code>next()</code> method
|
||||
* using the entry iterator.
|
||||
*
|
||||
* @throws ConcurrentModificationException if the hashtable was modified
|
||||
* @throws IllegalStateException if called when there is no last element
|
||||
*/
|
||||
public void remove()
|
||||
{
|
||||
iterator.remove();
|
||||
}
|
||||
|
||||
} // class ValueIterator
|
||||
|
||||
/**
|
||||
@@ -1128,7 +1218,8 @@ public class Hashtable extends Dictionary
|
||||
* @author Jon Zeppieri
|
||||
* @author Fridjof Siebert
|
||||
*/
|
||||
private class EntryEnumerator implements Enumeration
|
||||
private class EntryEnumerator
|
||||
implements Enumeration<Entry<K,V>>
|
||||
{
|
||||
/** The number of elements remaining to be returned by next(). */
|
||||
int count = size;
|
||||
@@ -1139,7 +1230,7 @@ public class Hashtable extends Dictionary
|
||||
* set if we are iterating through a bucket with multiple entries, or null
|
||||
* if we must look in the next bucket.
|
||||
*/
|
||||
HashEntry next;
|
||||
HashEntry<K, V> next;
|
||||
|
||||
/**
|
||||
* Construct the enumeration.
|
||||
@@ -1163,12 +1254,12 @@ public class Hashtable extends Dictionary
|
||||
* @return the next element
|
||||
* @throws NoSuchElementException if there is none.
|
||||
*/
|
||||
public Object nextElement()
|
||||
public Map.Entry<K,V> nextElement()
|
||||
{
|
||||
if (count == 0)
|
||||
throw new NoSuchElementException("Hashtable Enumerator");
|
||||
count--;
|
||||
HashEntry e = next;
|
||||
HashEntry<K, V> e = next;
|
||||
|
||||
while (e == null)
|
||||
if (idx <= 0)
|
||||
@@ -1195,18 +1286,47 @@ public class Hashtable extends Dictionary
|
||||
*
|
||||
* @author Jon Zeppieri
|
||||
* @author Fridjof Siebert
|
||||
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
|
||||
*/
|
||||
private final class KeyEnumerator extends EntryEnumerator
|
||||
private final class KeyEnumerator
|
||||
implements Enumeration<K>
|
||||
{
|
||||
/**
|
||||
* This entry enumerator is used for most operations. Only
|
||||
* <code>nextElement()</code> gives a different result, by returning just
|
||||
* the key rather than the whole element.
|
||||
*/
|
||||
private EntryEnumerator enumerator;
|
||||
|
||||
/**
|
||||
* Construct a new KeyEnumerator
|
||||
*/
|
||||
KeyEnumerator()
|
||||
{
|
||||
enumerator = new EntryEnumerator();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the entry enumerator has more elements.
|
||||
*
|
||||
* @return true if there are more elements
|
||||
* @throws ConcurrentModificationException if the hashtable was modified
|
||||
*/
|
||||
public boolean hasMoreElements()
|
||||
{
|
||||
return enumerator.hasMoreElements();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next element.
|
||||
* @return the next element
|
||||
* @throws NoSuchElementException if there is none.
|
||||
*/
|
||||
public Object nextElement()
|
||||
public K nextElement()
|
||||
{
|
||||
HashEntry entry = (HashEntry) super.nextElement();
|
||||
Object retVal = null;
|
||||
HashEntry<K,V> entry = (HashEntry<K,V>) enumerator.nextElement();
|
||||
K retVal = null;
|
||||
if (entry != null)
|
||||
retVal = entry.key;
|
||||
return retVal;
|
||||
@@ -1227,18 +1347,47 @@ public class Hashtable extends Dictionary
|
||||
*
|
||||
* @author Jon Zeppieri
|
||||
* @author Fridjof Siebert
|
||||
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
|
||||
*/
|
||||
private final class ValueEnumerator extends EntryEnumerator
|
||||
private final class ValueEnumerator
|
||||
implements Enumeration<V>
|
||||
{
|
||||
/**
|
||||
* This entry enumerator is used for most operations. Only
|
||||
* <code>nextElement()</code> gives a different result, by returning just
|
||||
* the value rather than the whole element.
|
||||
*/
|
||||
private EntryEnumerator enumerator;
|
||||
|
||||
/**
|
||||
* Construct a new ValueEnumerator
|
||||
*/
|
||||
ValueEnumerator()
|
||||
{
|
||||
enumerator = new EntryEnumerator();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the entry enumerator has more elements.
|
||||
*
|
||||
* @return true if there are more elements
|
||||
* @throws ConcurrentModificationException if the hashtable was modified
|
||||
*/
|
||||
public boolean hasMoreElements()
|
||||
{
|
||||
return enumerator.hasMoreElements();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next element.
|
||||
* @return the next element
|
||||
* @throws NoSuchElementException if there is none.
|
||||
*/
|
||||
public Object nextElement()
|
||||
public V nextElement()
|
||||
{
|
||||
HashEntry entry = (HashEntry) super.nextElement();
|
||||
Object retVal = null;
|
||||
HashEntry<K,V> entry = (HashEntry<K,V>) enumerator.nextElement();
|
||||
V retVal = null;
|
||||
if (entry != null)
|
||||
retVal = entry.value;
|
||||
return retVal;
|
||||
|
||||
@@ -90,23 +90,20 @@ import java.io.Serializable;
|
||||
* @since 1.4
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public class IdentityHashMap extends AbstractMap
|
||||
implements Map, Serializable, Cloneable
|
||||
public class IdentityHashMap<K,V> extends AbstractMap<K,V>
|
||||
implements Map<K,V>, Serializable, Cloneable
|
||||
{
|
||||
/** The default capacity. */
|
||||
private static final int DEFAULT_CAPACITY = 21;
|
||||
|
||||
/**
|
||||
* This object is used to mark deleted items. Package visible for use by
|
||||
* nested classes.
|
||||
* This object is used to mark a slot whose key or value is 'null'.
|
||||
* This is more efficient than using a special value to mark an empty
|
||||
* slot, because null entries are rare, empty slots are common, and
|
||||
* the JVM will clear new arrays for us.
|
||||
* Package visible for use by nested classes.
|
||||
*/
|
||||
static final Object tombstone = new Object();
|
||||
|
||||
/**
|
||||
* This object is used to mark empty slots. We need this because
|
||||
* using null is ambiguous. Package visible for use by nested classes.
|
||||
*/
|
||||
static final Object emptyslot = new Object();
|
||||
static final Object nullslot = new Object();
|
||||
|
||||
/**
|
||||
* Compatible with JDK 1.4.
|
||||
@@ -134,7 +131,7 @@ public class IdentityHashMap extends AbstractMap
|
||||
/**
|
||||
* The cache for {@link #entrySet()}.
|
||||
*/
|
||||
private transient Set entries;
|
||||
private transient Set<Map.Entry<K,V>> entries;
|
||||
|
||||
/**
|
||||
* The threshold for rehashing, which is 75% of (table.length / 2).
|
||||
@@ -166,7 +163,6 @@ public class IdentityHashMap extends AbstractMap
|
||||
if (max < 2)
|
||||
max = 2;
|
||||
table = new Object[max << 1];
|
||||
Arrays.fill(table, emptyslot);
|
||||
threshold = (max >> 2) * 3;
|
||||
}
|
||||
|
||||
@@ -177,7 +173,7 @@ public class IdentityHashMap extends AbstractMap
|
||||
* @param m The map whose elements are to be put in this map
|
||||
* @throws NullPointerException if m is null
|
||||
*/
|
||||
public IdentityHashMap(Map m)
|
||||
public IdentityHashMap(Map<? extends K, ? extends V> m)
|
||||
{
|
||||
this(Math.max(m.size() << 1, DEFAULT_CAPACITY));
|
||||
putAll(m);
|
||||
@@ -191,7 +187,7 @@ public class IdentityHashMap extends AbstractMap
|
||||
if (size != 0)
|
||||
{
|
||||
modCount++;
|
||||
Arrays.fill(table, emptyslot);
|
||||
Arrays.fill(table, null);
|
||||
size = 0;
|
||||
}
|
||||
}
|
||||
@@ -227,6 +223,7 @@ public class IdentityHashMap extends AbstractMap
|
||||
*/
|
||||
public boolean containsKey(Object key)
|
||||
{
|
||||
key = xform(key);
|
||||
return key == table[hash(key)];
|
||||
}
|
||||
|
||||
@@ -241,6 +238,7 @@ public class IdentityHashMap extends AbstractMap
|
||||
*/
|
||||
public boolean containsValue(Object value)
|
||||
{
|
||||
value = xform(value);
|
||||
for (int i = table.length - 1; i > 0; i -= 2)
|
||||
if (table[i] == value)
|
||||
return true;
|
||||
@@ -274,19 +272,19 @@ public class IdentityHashMap extends AbstractMap
|
||||
* @see #values()
|
||||
* @see Map.Entry
|
||||
*/
|
||||
public Set entrySet()
|
||||
public Set<Map.Entry<K,V>> entrySet()
|
||||
{
|
||||
if (entries == null)
|
||||
entries = new AbstractSet()
|
||||
entries = new AbstractSet<Map.Entry<K,V>>()
|
||||
{
|
||||
public int size()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
public Iterator iterator()
|
||||
public Iterator<Map.Entry<K,V>> iterator()
|
||||
{
|
||||
return new IdentityIterator(ENTRIES);
|
||||
return new IdentityIterator<Map.Entry<K,V>>(ENTRIES);
|
||||
}
|
||||
|
||||
public void clear()
|
||||
@@ -299,7 +297,9 @@ public class IdentityHashMap extends AbstractMap
|
||||
if (! (o instanceof Map.Entry))
|
||||
return false;
|
||||
Map.Entry m = (Map.Entry) o;
|
||||
return m.getValue() == table[hash(m.getKey()) + 1];
|
||||
Object value = xform(m.getValue());
|
||||
Object key = xform(m.getKey());
|
||||
return value == table[hash(key) + 1];
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
@@ -311,14 +311,13 @@ public class IdentityHashMap extends AbstractMap
|
||||
{
|
||||
if (! (o instanceof Map.Entry))
|
||||
return false;
|
||||
Object key = ((Map.Entry) o).getKey();
|
||||
Object key = xform(((Map.Entry) o).getKey());
|
||||
int h = hash(key);
|
||||
if (table[h] == key)
|
||||
{
|
||||
size--;
|
||||
modCount++;
|
||||
table[h] = tombstone;
|
||||
table[h + 1] = tombstone;
|
||||
IdentityHashMap.this.removeAtIndex(h);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -358,10 +357,11 @@ public class IdentityHashMap extends AbstractMap
|
||||
* @see #put(Object, Object)
|
||||
* @see #containsKey(Object)
|
||||
*/
|
||||
public Object get(Object key)
|
||||
public V get(Object key)
|
||||
{
|
||||
key = xform(key);
|
||||
int h = hash(key);
|
||||
return table[h] == key ? table[h + 1] : null;
|
||||
return (V) (table[h] == key ? unxform(table[h + 1]) : null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -378,10 +378,11 @@ public class IdentityHashMap extends AbstractMap
|
||||
for (int i = table.length - 2; i >= 0; i -= 2)
|
||||
{
|
||||
Object key = table[i];
|
||||
if (key == emptyslot || key == tombstone)
|
||||
if (key == null)
|
||||
continue;
|
||||
hash += (System.identityHashCode(key)
|
||||
^ System.identityHashCode(table[i + 1]));
|
||||
// FIXME: this is a lame computation.
|
||||
hash += (System.identityHashCode(unxform(key))
|
||||
^ System.identityHashCode(unxform(table[i + 1])));
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
@@ -414,19 +415,19 @@ public class IdentityHashMap extends AbstractMap
|
||||
* @see #values()
|
||||
* @see #entrySet()
|
||||
*/
|
||||
public Set keySet()
|
||||
public Set<K> keySet()
|
||||
{
|
||||
if (keys == null)
|
||||
keys = new AbstractSet()
|
||||
keys = new AbstractSet<K>()
|
||||
{
|
||||
public int size()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
public Iterator iterator()
|
||||
public Iterator<K> iterator()
|
||||
{
|
||||
return new IdentityIterator(KEYS);
|
||||
return new IdentityIterator<K>(KEYS);
|
||||
}
|
||||
|
||||
public void clear()
|
||||
@@ -445,23 +446,22 @@ public class IdentityHashMap extends AbstractMap
|
||||
for (int i = table.length - 2; i >= 0; i -= 2)
|
||||
{
|
||||
Object key = table[i];
|
||||
if (key == emptyslot || key == tombstone)
|
||||
if (key == null)
|
||||
continue;
|
||||
hash += System.identityHashCode(key);
|
||||
hash += System.identityHashCode(unxform(key));
|
||||
}
|
||||
return hash;
|
||||
|
||||
}
|
||||
|
||||
public boolean remove(Object o)
|
||||
{
|
||||
o = xform(o);
|
||||
int h = hash(o);
|
||||
if (table[h] == o)
|
||||
{
|
||||
size--;
|
||||
modCount++;
|
||||
table[h] = tombstone;
|
||||
table[h + 1] = tombstone;
|
||||
removeAtIndex(h);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -484,8 +484,20 @@ public class IdentityHashMap extends AbstractMap
|
||||
* @return the prior mapping of the key, or null if there was none
|
||||
* @see #get(Object)
|
||||
*/
|
||||
public Object put(Object key, Object value)
|
||||
public V put(K key, V value)
|
||||
{
|
||||
key = (K) xform(key);
|
||||
value = (V) xform(value);
|
||||
|
||||
// We don't want to rehash if we're overwriting an existing slot.
|
||||
int h = hash(key);
|
||||
if (table[h] == key)
|
||||
{
|
||||
V r = (V) unxform(table[h + 1]);
|
||||
table[h + 1] = value;
|
||||
return r;
|
||||
}
|
||||
|
||||
// Rehash if the load factor is too high.
|
||||
if (size > threshold)
|
||||
{
|
||||
@@ -493,25 +505,25 @@ public class IdentityHashMap extends AbstractMap
|
||||
// This isn't necessarily prime, but it is an odd number of key/value
|
||||
// slots, which has a higher probability of fewer collisions.
|
||||
table = new Object[(old.length * 2) + 2];
|
||||
Arrays.fill(table, emptyslot);
|
||||
size = 0;
|
||||
threshold = (table.length >>> 3) * 3;
|
||||
|
||||
for (int i = old.length - 2; i >= 0; i -= 2)
|
||||
{
|
||||
Object oldkey = old[i];
|
||||
if (oldkey != tombstone && oldkey != emptyslot)
|
||||
// Just use put. This isn't very efficient, but it is ok.
|
||||
put(oldkey, old[i + 1]);
|
||||
K oldkey = (K) old[i];
|
||||
if (oldkey != null)
|
||||
{
|
||||
h = hash(oldkey);
|
||||
table[h] = oldkey;
|
||||
table[h + 1] = old[i + 1];
|
||||
++size;
|
||||
// No need to update modCount here, we'll do it
|
||||
// just after the loop.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int h = hash(key);
|
||||
if (table[h] == key)
|
||||
{
|
||||
Object r = table[h + 1];
|
||||
table[h + 1] = value;
|
||||
return r;
|
||||
// Now that we've resize, recompute the hash value.
|
||||
h = hash(key);
|
||||
}
|
||||
|
||||
// At this point, we add a new mapping.
|
||||
@@ -529,12 +541,46 @@ public class IdentityHashMap extends AbstractMap
|
||||
* @param m the map to copy
|
||||
* @throws NullPointerException if m is null
|
||||
*/
|
||||
public void putAll(Map m)
|
||||
public void putAll(Map<? extends K, ? extends V> m)
|
||||
{
|
||||
// Why did Sun specify this one? The superclass does the right thing.
|
||||
super.putAll(m);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the element at index and update the table to compensate.
|
||||
* This is package-private for use by inner classes.
|
||||
* @param i index of the removed element
|
||||
*/
|
||||
final void removeAtIndex(int i)
|
||||
{
|
||||
// This is Algorithm R from Knuth, section 6.4.
|
||||
// Variable names are taken directly from the text.
|
||||
while (true)
|
||||
{
|
||||
table[i] = null;
|
||||
table[i + 1] = null;
|
||||
int j = i;
|
||||
int r;
|
||||
do
|
||||
{
|
||||
i -= 2;
|
||||
if (i < 0)
|
||||
i = table.length - 2;
|
||||
Object key = table[i];
|
||||
if (key == null)
|
||||
return;
|
||||
r = Math.abs(System.identityHashCode(key)
|
||||
% (table.length >> 1)) << 1;
|
||||
}
|
||||
while ((i <= r && r < j)
|
||||
|| (r < j && j < i)
|
||||
|| (j < i && i <= r));
|
||||
table[j] = table[i];
|
||||
table[j + 1] = table[i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes from the HashMap and returns the value which is mapped by
|
||||
* the supplied key. If the key maps to nothing, then the HashMap
|
||||
@@ -549,17 +595,17 @@ public class IdentityHashMap extends AbstractMap
|
||||
* @param key the key used to locate the value to remove
|
||||
* @return whatever the key mapped to, if present
|
||||
*/
|
||||
public Object remove(Object key)
|
||||
public V remove(Object key)
|
||||
{
|
||||
key = xform(key);
|
||||
int h = hash(key);
|
||||
if (table[h] == key)
|
||||
{
|
||||
modCount++;
|
||||
size--;
|
||||
Object r = table[h + 1];
|
||||
table[h] = tombstone;
|
||||
table[h + 1] = tombstone;
|
||||
return r;
|
||||
Object r = unxform(table[h + 1]);
|
||||
removeAtIndex(h);
|
||||
return (V) r;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -591,19 +637,19 @@ public class IdentityHashMap extends AbstractMap
|
||||
* @see #keySet()
|
||||
* @see #entrySet()
|
||||
*/
|
||||
public Collection values()
|
||||
public Collection<V> values()
|
||||
{
|
||||
if (values == null)
|
||||
values = new AbstractCollection()
|
||||
values = new AbstractCollection<V>()
|
||||
{
|
||||
public int size()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
public Iterator iterator()
|
||||
public Iterator<V> iterator()
|
||||
{
|
||||
return new IdentityIterator(VALUES);
|
||||
return new IdentityIterator<V>(VALUES);
|
||||
}
|
||||
|
||||
public void clear()
|
||||
@@ -613,13 +659,14 @@ public class IdentityHashMap extends AbstractMap
|
||||
|
||||
public boolean remove(Object o)
|
||||
{
|
||||
o = xform(o);
|
||||
// This approach may look strange, but it is ok.
|
||||
for (int i = table.length - 1; i > 0; i -= 2)
|
||||
if (table[i] == o)
|
||||
{
|
||||
modCount++;
|
||||
table[i - 1] = tombstone;
|
||||
table[i] = tombstone;
|
||||
size--;
|
||||
IdentityHashMap.this.removeAtIndex(i - 1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -628,9 +675,32 @@ public class IdentityHashMap extends AbstractMap
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform a reference from its external form to its internal form.
|
||||
* This is package-private for use by inner classes.
|
||||
*/
|
||||
final Object xform(Object o)
|
||||
{
|
||||
if (o == null)
|
||||
o = nullslot;
|
||||
return o;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform a reference from its internal form to its external form.
|
||||
* This is package-private for use by inner classes.
|
||||
*/
|
||||
final Object unxform(Object o)
|
||||
{
|
||||
if (o == nullslot)
|
||||
o = null;
|
||||
return o;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method which computes the hash code, then traverses the table
|
||||
* until it finds the key, or the spot where the key would go.
|
||||
* until it finds the key, or the spot where the key would go. the key
|
||||
* must already be in its internal form.
|
||||
*
|
||||
* @param key the key to check
|
||||
* @return the index where the key belongs
|
||||
@@ -638,36 +708,23 @@ public class IdentityHashMap extends AbstractMap
|
||||
* @see #put(Object, Object)
|
||||
*/
|
||||
// Package visible for use by nested classes.
|
||||
int hash(Object key)
|
||||
final int hash(Object key)
|
||||
{
|
||||
// Implementation note: it is feasible for the table to have no
|
||||
// emptyslots, if it is full with entries and tombstones, so we must
|
||||
// remember where we started. If we encounter the key or an emptyslot,
|
||||
// we are done. If we encounter a tombstone, the key may still be in
|
||||
// the array. If we don't encounter the key, we use the first emptyslot
|
||||
// or tombstone we encountered as the location where the key would go.
|
||||
// By requiring at least 2 key/value slots, and rehashing at 75%
|
||||
// capacity, we guarantee that there will always be either an emptyslot
|
||||
// or a tombstone somewhere in the table.
|
||||
int h = Math.abs(System.identityHashCode(key) % (table.length >> 1)) << 1;
|
||||
int del = -1;
|
||||
int save = h;
|
||||
|
||||
do
|
||||
while (true)
|
||||
{
|
||||
if (table[h] == key)
|
||||
// By requiring at least 2 key/value slots, and rehashing at 75%
|
||||
// capacity, we guarantee that there will always be either an empty
|
||||
// slot somewhere in the table.
|
||||
if (table[h] == key || table[h] == null)
|
||||
return h;
|
||||
if (table[h] == emptyslot)
|
||||
break;
|
||||
if (table[h] == tombstone && del < 0)
|
||||
del = h;
|
||||
// We use linear probing as it is friendlier to the cache and
|
||||
// it lets us efficiently remove entries.
|
||||
h -= 2;
|
||||
if (h < 0)
|
||||
h = table.length - 2;
|
||||
}
|
||||
while (h != save);
|
||||
|
||||
return del < 0 ? h : del;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -679,7 +736,7 @@ public class IdentityHashMap extends AbstractMap
|
||||
* @author Tom Tromey (tromey@redhat.com)
|
||||
* @author Eric Blake (ebb9@email.byu.edu)
|
||||
*/
|
||||
private class IdentityIterator implements Iterator
|
||||
private class IdentityIterator<I> implements Iterator<I>
|
||||
{
|
||||
/**
|
||||
* The type of this Iterator: {@link #KEYS}, {@link #VALUES},
|
||||
@@ -717,7 +774,7 @@ public class IdentityHashMap extends AbstractMap
|
||||
* @throws ConcurrentModificationException if the Map was modified
|
||||
* @throws NoSuchElementException if there is none
|
||||
*/
|
||||
public Object next()
|
||||
public I next()
|
||||
{
|
||||
if (knownMod != modCount)
|
||||
throw new ConcurrentModificationException();
|
||||
@@ -731,10 +788,11 @@ public class IdentityHashMap extends AbstractMap
|
||||
loc -= 2;
|
||||
key = table[loc];
|
||||
}
|
||||
while (key == emptyslot || key == tombstone);
|
||||
|
||||
return type == KEYS ? key : (type == VALUES ? table[loc + 1]
|
||||
: new IdentityEntry(loc));
|
||||
while (key == null);
|
||||
|
||||
return (I) (type == KEYS ? unxform(key)
|
||||
: (type == VALUES ? unxform(table[loc + 1])
|
||||
: new IdentityEntry(loc)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -748,12 +806,11 @@ public class IdentityHashMap extends AbstractMap
|
||||
{
|
||||
if (knownMod != modCount)
|
||||
throw new ConcurrentModificationException();
|
||||
if (loc == table.length || table[loc] == tombstone)
|
||||
if (loc == table.length)
|
||||
throw new IllegalStateException();
|
||||
modCount++;
|
||||
size--;
|
||||
table[loc] = tombstone;
|
||||
table[loc + 1] = tombstone;
|
||||
removeAtIndex(loc);
|
||||
knownMod++;
|
||||
}
|
||||
} // class IdentityIterator
|
||||
@@ -768,7 +825,7 @@ public class IdentityHashMap extends AbstractMap
|
||||
*
|
||||
* @author Eric Blake (ebb9@email.byu.edu)
|
||||
*/
|
||||
private final class IdentityEntry implements Map.Entry
|
||||
private final class IdentityEntry<EK,EV> implements Map.Entry<EK,EV>
|
||||
{
|
||||
/** The location of this entry. */
|
||||
final int loc;
|
||||
@@ -797,12 +854,13 @@ public class IdentityHashMap extends AbstractMap
|
||||
*/
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (knownMod != modCount || table[loc] == tombstone)
|
||||
if (knownMod != modCount)
|
||||
throw new ConcurrentModificationException();
|
||||
if (! (o instanceof Map.Entry))
|
||||
return false;
|
||||
Map.Entry e = (Map.Entry) o;
|
||||
return table[loc] == e.getKey() && table[loc + 1] == e.getValue();
|
||||
return table[loc] == xform(e.getKey())
|
||||
&& table[loc + 1] == xform(e.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -812,11 +870,11 @@ public class IdentityHashMap extends AbstractMap
|
||||
* @throws ConcurrentModificationException if the entry was invalidated
|
||||
* by modifying the Map or calling Iterator.remove()
|
||||
*/
|
||||
public Object getKey()
|
||||
public EK getKey()
|
||||
{
|
||||
if (knownMod != modCount || table[loc] == tombstone)
|
||||
if (knownMod != modCount)
|
||||
throw new ConcurrentModificationException();
|
||||
return table[loc];
|
||||
return (EK) unxform(table[loc]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -826,11 +884,11 @@ public class IdentityHashMap extends AbstractMap
|
||||
* @throws ConcurrentModificationException if the entry was invalidated
|
||||
* by modifying the Map or calling Iterator.remove()
|
||||
*/
|
||||
public Object getValue()
|
||||
public EV getValue()
|
||||
{
|
||||
if (knownMod != modCount || table[loc] == tombstone)
|
||||
if (knownMod != modCount)
|
||||
throw new ConcurrentModificationException();
|
||||
return table[loc + 1];
|
||||
return (EV) unxform(table[loc + 1]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -844,10 +902,10 @@ public class IdentityHashMap extends AbstractMap
|
||||
*/
|
||||
public int hashCode()
|
||||
{
|
||||
if (knownMod != modCount || table[loc] == tombstone)
|
||||
if (knownMod != modCount)
|
||||
throw new ConcurrentModificationException();
|
||||
return (System.identityHashCode(table[loc])
|
||||
^ System.identityHashCode(table[loc + 1]));
|
||||
return (System.identityHashCode(unxform(table[loc]))
|
||||
^ System.identityHashCode(unxform(table[loc + 1])));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -858,12 +916,12 @@ public class IdentityHashMap extends AbstractMap
|
||||
* @throws ConcurrentModificationException if the entry was invalidated
|
||||
* by modifying the Map or calling Iterator.remove()
|
||||
*/
|
||||
public Object setValue(Object value)
|
||||
public EV setValue(EV value)
|
||||
{
|
||||
if (knownMod != modCount || table[loc] == tombstone)
|
||||
if (knownMod != modCount)
|
||||
throw new ConcurrentModificationException();
|
||||
Object r = table[loc + 1];
|
||||
table[loc + 1] = value;
|
||||
EV r = (EV) unxform(table[loc + 1]);
|
||||
table[loc + 1] = xform(value);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -877,9 +935,9 @@ public class IdentityHashMap extends AbstractMap
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
if (knownMod != modCount || table[loc] == tombstone)
|
||||
if (knownMod != modCount)
|
||||
throw new ConcurrentModificationException();
|
||||
return table[loc] + "=" + table[loc + 1];
|
||||
return unxform(table[loc]) + "=" + unxform(table[loc + 1]);
|
||||
}
|
||||
} // class IdentityEntry
|
||||
|
||||
@@ -902,7 +960,7 @@ public class IdentityHashMap extends AbstractMap
|
||||
table = new Object[Math.max(num << 1, DEFAULT_CAPACITY) << 1];
|
||||
// Read key/value pairs.
|
||||
while (--num >= 0)
|
||||
put(s.readObject(), s.readObject());
|
||||
put((K) s.readObject(), (V) s.readObject());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -922,10 +980,10 @@ public class IdentityHashMap extends AbstractMap
|
||||
for (int i = table.length - 2; i >= 0; i -= 2)
|
||||
{
|
||||
Object key = table[i];
|
||||
if (key != tombstone && key != emptyslot)
|
||||
if (key != null)
|
||||
{
|
||||
s.writeObject(key);
|
||||
s.writeObject(table[i + 1]);
|
||||
s.writeObject(unxform(key));
|
||||
s.writeObject(unxform(table[i + 1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ public class IllegalFormatConversionException
|
||||
* @serial the mismatching argument type.
|
||||
*/
|
||||
// Note: name fixed by serialization.
|
||||
Class arg;
|
||||
Class<?> arg;
|
||||
|
||||
/**
|
||||
* Constructs a new <code>IllegalFormatConversionException</code>
|
||||
@@ -78,7 +78,7 @@ public class IllegalFormatConversionException
|
||||
* @param arg the type which doesn't match the conversion character.
|
||||
* @throws NullPointerException if <code>arg</code> is null.
|
||||
*/
|
||||
public IllegalFormatConversionException(char c, Class arg)
|
||||
public IllegalFormatConversionException(char c, Class<?> arg)
|
||||
{
|
||||
super("The type, " + arg + ", is invalid for the conversion character, " +
|
||||
c + ".");
|
||||
@@ -103,7 +103,7 @@ public class IllegalFormatConversionException
|
||||
*
|
||||
* @return the type of the mismatched argument.
|
||||
*/
|
||||
public Class getArgumentClass()
|
||||
public Class<?> getArgumentClass()
|
||||
{
|
||||
return arg;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Iterator.java -- Interface for iterating over collections
|
||||
Copyright (C) 1998, 2001, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 2001, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -54,7 +54,7 @@ package java.util;
|
||||
* @since 1.2
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public interface Iterator
|
||||
public interface Iterator<E>
|
||||
{
|
||||
/**
|
||||
* Tests whether there are elements remaining in the collection. In other
|
||||
@@ -70,7 +70,7 @@ public interface Iterator
|
||||
* @return the next element in the collection
|
||||
* @throws NoSuchElementException if there are no more elements
|
||||
*/
|
||||
Object next();
|
||||
E next();
|
||||
|
||||
/**
|
||||
* Remove from the underlying collection the last element returned by next
|
||||
|
||||
@@ -97,6 +97,8 @@ package java.util;
|
||||
* non-deterministic behavior.
|
||||
*
|
||||
* @author Eric Blake (ebb9@email.byu.edu)
|
||||
* @author Tom Tromey (tromey@redhat.com)
|
||||
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
|
||||
* @see Object#hashCode()
|
||||
* @see Collection
|
||||
* @see Map
|
||||
@@ -106,7 +108,7 @@ package java.util;
|
||||
* @since 1.4
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public class LinkedHashMap extends HashMap
|
||||
public class LinkedHashMap<K,V> extends HashMap<K,V>
|
||||
{
|
||||
/**
|
||||
* Compatible with JDK 1.4.
|
||||
@@ -130,16 +132,16 @@ public class LinkedHashMap extends HashMap
|
||||
* Class to represent an entry in the hash table. Holds a single key-value
|
||||
* pair and the doubly-linked insertion order list.
|
||||
*/
|
||||
class LinkedHashEntry extends HashEntry
|
||||
class LinkedHashEntry<K,V> extends HashEntry<K,V>
|
||||
{
|
||||
/**
|
||||
* The predecessor in the iteration list. If this entry is the root
|
||||
* (eldest), pred points to the newest entry.
|
||||
*/
|
||||
LinkedHashEntry pred;
|
||||
LinkedHashEntry<K,V> pred;
|
||||
|
||||
/** The successor in the iteration list, null if this is the newest. */
|
||||
LinkedHashEntry succ;
|
||||
LinkedHashEntry<K,V> succ;
|
||||
|
||||
/**
|
||||
* Simple constructor.
|
||||
@@ -147,7 +149,7 @@ public class LinkedHashMap extends HashMap
|
||||
* @param key the key
|
||||
* @param value the value
|
||||
*/
|
||||
LinkedHashEntry(Object key, Object value)
|
||||
LinkedHashEntry(K key, V value)
|
||||
{
|
||||
super(key, value);
|
||||
if (root == null)
|
||||
@@ -186,7 +188,7 @@ public class LinkedHashMap extends HashMap
|
||||
succ = null;
|
||||
pred = root.pred;
|
||||
pred.succ = this;
|
||||
root.pred = this;
|
||||
root.pred = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -197,7 +199,7 @@ public class LinkedHashMap extends HashMap
|
||||
*
|
||||
* @return the value of this key as it is removed
|
||||
*/
|
||||
Object cleanup()
|
||||
V cleanup()
|
||||
{
|
||||
if (this == root)
|
||||
{
|
||||
@@ -243,7 +245,7 @@ public class LinkedHashMap extends HashMap
|
||||
* are not cloned in this constructor.</b>
|
||||
* @throws NullPointerException if m is null
|
||||
*/
|
||||
public LinkedHashMap(Map m)
|
||||
public LinkedHashMap(Map<? extends K, ? extends V> m)
|
||||
{
|
||||
super(m);
|
||||
accessOrder = false;
|
||||
@@ -335,10 +337,10 @@ public class LinkedHashMap extends HashMap
|
||||
* @see #put(Object, Object)
|
||||
* @see #containsKey(Object)
|
||||
*/
|
||||
public Object get(Object key)
|
||||
public V get(Object key)
|
||||
{
|
||||
int idx = hash(key);
|
||||
HashEntry e = buckets[idx];
|
||||
HashEntry<K,V> e = buckets[idx];
|
||||
while (e != null)
|
||||
{
|
||||
if (equals(key, e.key))
|
||||
@@ -390,7 +392,7 @@ public class LinkedHashMap extends HashMap
|
||||
* earliest element inserted.
|
||||
* @return true if <code>eldest</code> should be removed
|
||||
*/
|
||||
protected boolean removeEldestEntry(Map.Entry eldest)
|
||||
protected boolean removeEldestEntry(Map.Entry<K,V> eldest)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -407,7 +409,7 @@ public class LinkedHashMap extends HashMap
|
||||
* @see #removeEldestEntry(Map.Entry)
|
||||
* @see LinkedHashEntry#LinkedHashEntry(Object, Object)
|
||||
*/
|
||||
void addEntry(Object key, Object value, int idx, boolean callRemove)
|
||||
void addEntry(K key, V value, int idx, boolean callRemove)
|
||||
{
|
||||
LinkedHashEntry e = new LinkedHashEntry(key, value);
|
||||
e.next = buckets[idx];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* LinkedHashSet.java -- a set backed by a LinkedHashMap, for linked
|
||||
list traversal.
|
||||
Copyright (C) 2001, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 2001, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -88,8 +88,8 @@ import java.io.Serializable;
|
||||
* @since 1.4
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public class LinkedHashSet extends HashSet
|
||||
implements Set, Cloneable, Serializable
|
||||
public class LinkedHashSet<T> extends HashSet<T>
|
||||
implements Set<T>, Cloneable, Serializable
|
||||
{
|
||||
/**
|
||||
* Compatible with JDK 1.4.
|
||||
@@ -140,7 +140,7 @@ public class LinkedHashSet extends HashSet
|
||||
* @param c a collection of initial set elements
|
||||
* @throws NullPointerException if c is null
|
||||
*/
|
||||
public LinkedHashSet(Collection c)
|
||||
public LinkedHashSet(Collection<? extends T> c)
|
||||
{
|
||||
super(c);
|
||||
}
|
||||
@@ -152,9 +152,8 @@ public class LinkedHashSet extends HashSet
|
||||
* @param load the initial load factor
|
||||
* @return the backing HashMap
|
||||
*/
|
||||
HashMap init(int capacity, float load)
|
||||
HashMap<T, String> init(int capacity, float load)
|
||||
{
|
||||
return new LinkedHashMap(capacity, load);
|
||||
return new LinkedHashMap<T, String>(capacity, load);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -71,8 +71,8 @@ import java.lang.reflect.Array;
|
||||
* @since 1.2
|
||||
* @status missing javadoc, but complete to 1.4
|
||||
*/
|
||||
public class LinkedList extends AbstractSequentialList
|
||||
implements List, Cloneable, Serializable
|
||||
public class LinkedList<T> extends AbstractSequentialList<T>
|
||||
implements List<T>, Queue<T>, Cloneable, Serializable
|
||||
{
|
||||
/**
|
||||
* Compatible with JDK 1.2.
|
||||
@@ -82,12 +82,12 @@ public class LinkedList extends AbstractSequentialList
|
||||
/**
|
||||
* The first element in the list.
|
||||
*/
|
||||
transient Entry first;
|
||||
transient Entry<T> first;
|
||||
|
||||
/**
|
||||
* The last element in the list.
|
||||
*/
|
||||
transient Entry last;
|
||||
transient Entry<T> last;
|
||||
|
||||
/**
|
||||
* The current length of the list.
|
||||
@@ -97,22 +97,22 @@ public class LinkedList extends AbstractSequentialList
|
||||
/**
|
||||
* Class to represent an entry in the list. Holds a single element.
|
||||
*/
|
||||
private static final class Entry
|
||||
private static final class Entry<T>
|
||||
{
|
||||
/** The element in the list. */
|
||||
Object data;
|
||||
T data;
|
||||
|
||||
/** The next list entry, null if this is last. */
|
||||
Entry next;
|
||||
Entry<T> next;
|
||||
|
||||
/** The previous list entry, null if this is first. */
|
||||
Entry previous;
|
||||
Entry<T> previous;
|
||||
|
||||
/**
|
||||
* Construct an entry.
|
||||
* @param data the list element
|
||||
*/
|
||||
Entry(Object data)
|
||||
Entry(T data)
|
||||
{
|
||||
this.data = data;
|
||||
}
|
||||
@@ -131,9 +131,9 @@ public class LinkedList extends AbstractSequentialList
|
||||
* @return the entry at position n
|
||||
*/
|
||||
// Package visible for use in nested classes.
|
||||
Entry getEntry(int n)
|
||||
Entry<T> getEntry(int n)
|
||||
{
|
||||
Entry e;
|
||||
Entry<T> e;
|
||||
if (n < size / 2)
|
||||
{
|
||||
e = first;
|
||||
@@ -158,7 +158,7 @@ public class LinkedList extends AbstractSequentialList
|
||||
* @param e the entry to remove
|
||||
*/
|
||||
// Package visible for use in nested classes.
|
||||
void removeEntry(Entry e)
|
||||
void removeEntry(Entry<T> e)
|
||||
{
|
||||
modCount++;
|
||||
size--;
|
||||
@@ -224,7 +224,7 @@ public class LinkedList extends AbstractSequentialList
|
||||
* @param c the collection to populate this list from
|
||||
* @throws NullPointerException if c is null
|
||||
*/
|
||||
public LinkedList(Collection c)
|
||||
public LinkedList(Collection<? extends T> c)
|
||||
{
|
||||
addAll(c);
|
||||
}
|
||||
@@ -235,7 +235,7 @@ public class LinkedList extends AbstractSequentialList
|
||||
* @return the first list element
|
||||
* @throws NoSuchElementException if the list is empty
|
||||
*/
|
||||
public Object getFirst()
|
||||
public T getFirst()
|
||||
{
|
||||
if (size == 0)
|
||||
throw new NoSuchElementException();
|
||||
@@ -248,7 +248,7 @@ public class LinkedList extends AbstractSequentialList
|
||||
* @return the last list element
|
||||
* @throws NoSuchElementException if the list is empty
|
||||
*/
|
||||
public Object getLast()
|
||||
public T getLast()
|
||||
{
|
||||
if (size == 0)
|
||||
throw new NoSuchElementException();
|
||||
@@ -261,13 +261,13 @@ public class LinkedList extends AbstractSequentialList
|
||||
* @return the former first element in the list
|
||||
* @throws NoSuchElementException if the list is empty
|
||||
*/
|
||||
public Object removeFirst()
|
||||
public T removeFirst()
|
||||
{
|
||||
if (size == 0)
|
||||
throw new NoSuchElementException();
|
||||
modCount++;
|
||||
size--;
|
||||
Object r = first.data;
|
||||
T r = first.data;
|
||||
|
||||
if (first.next != null)
|
||||
first.next.previous = null;
|
||||
@@ -285,13 +285,13 @@ public class LinkedList extends AbstractSequentialList
|
||||
* @return the former last element in the list
|
||||
* @throws NoSuchElementException if the list is empty
|
||||
*/
|
||||
public Object removeLast()
|
||||
public T removeLast()
|
||||
{
|
||||
if (size == 0)
|
||||
throw new NoSuchElementException();
|
||||
modCount++;
|
||||
size--;
|
||||
Object r = last.data;
|
||||
T r = last.data;
|
||||
|
||||
if (last.previous != null)
|
||||
last.previous.next = null;
|
||||
@@ -308,9 +308,9 @@ public class LinkedList extends AbstractSequentialList
|
||||
*
|
||||
* @param o the element to insert
|
||||
*/
|
||||
public void addFirst(Object o)
|
||||
public void addFirst(T o)
|
||||
{
|
||||
Entry e = new Entry(o);
|
||||
Entry<T> e = new Entry(o);
|
||||
|
||||
modCount++;
|
||||
if (size == 0)
|
||||
@@ -329,9 +329,9 @@ public class LinkedList extends AbstractSequentialList
|
||||
*
|
||||
* @param o the element to insert
|
||||
*/
|
||||
public void addLast(Object o)
|
||||
public void addLast(T o)
|
||||
{
|
||||
addLastEntry(new Entry(o));
|
||||
addLastEntry(new Entry<T>(o));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -339,7 +339,7 @@ public class LinkedList extends AbstractSequentialList
|
||||
*
|
||||
* @param e the entry to add
|
||||
*/
|
||||
private void addLastEntry(Entry e)
|
||||
private void addLastEntry(Entry<T> e)
|
||||
{
|
||||
modCount++;
|
||||
if (size == 0)
|
||||
@@ -362,7 +362,7 @@ public class LinkedList extends AbstractSequentialList
|
||||
*/
|
||||
public boolean contains(Object o)
|
||||
{
|
||||
Entry e = first;
|
||||
Entry<T> e = first;
|
||||
while (e != null)
|
||||
{
|
||||
if (equals(o, e.data))
|
||||
@@ -388,9 +388,9 @@ public class LinkedList extends AbstractSequentialList
|
||||
* @param o the entry to add
|
||||
* @return true, as it always succeeds
|
||||
*/
|
||||
public boolean add(Object o)
|
||||
public boolean add(T o)
|
||||
{
|
||||
addLastEntry(new Entry(o));
|
||||
addLastEntry(new Entry<T>(o));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -403,7 +403,7 @@ public class LinkedList extends AbstractSequentialList
|
||||
*/
|
||||
public boolean remove(Object o)
|
||||
{
|
||||
Entry e = first;
|
||||
Entry<T> e = first;
|
||||
while (e != null)
|
||||
{
|
||||
if (equals(o, e.data))
|
||||
@@ -425,7 +425,7 @@ public class LinkedList extends AbstractSequentialList
|
||||
* @return true if the list was modified
|
||||
* @throws NullPointerException if c is null
|
||||
*/
|
||||
public boolean addAll(Collection c)
|
||||
public boolean addAll(Collection<? extends T> c)
|
||||
{
|
||||
return addAll(size, c);
|
||||
}
|
||||
@@ -440,7 +440,7 @@ public class LinkedList extends AbstractSequentialList
|
||||
* @throws NullPointerException if c is null
|
||||
* @throws IndexOutOfBoundsException if index < 0 || index > size()
|
||||
*/
|
||||
public boolean addAll(int index, Collection c)
|
||||
public boolean addAll(int index, Collection<? extends T> c)
|
||||
{
|
||||
checkBoundsInclusive(index);
|
||||
int csize = c.size();
|
||||
@@ -448,13 +448,13 @@ public class LinkedList extends AbstractSequentialList
|
||||
if (csize == 0)
|
||||
return false;
|
||||
|
||||
Iterator itr = c.iterator();
|
||||
Iterator<? extends T> itr = c.iterator();
|
||||
|
||||
// Get the entries just before and after index. If index is at the start
|
||||
// of the list, BEFORE is null. If index is at the end of the list, AFTER
|
||||
// is null. If the list is empty, both are null.
|
||||
Entry after = null;
|
||||
Entry before = null;
|
||||
Entry<T> after = null;
|
||||
Entry<T> before = null;
|
||||
if (index != size)
|
||||
{
|
||||
after = getEntry(index);
|
||||
@@ -467,15 +467,15 @@ public class LinkedList extends AbstractSequentialList
|
||||
// to the first entry, in order to deal with the case where (c == this).
|
||||
// [Actually, we don't have to handle this case to fufill the
|
||||
// contract for addAll(), but Sun's implementation appears to.]
|
||||
Entry e = new Entry(itr.next());
|
||||
Entry<T> e = new Entry<T>(itr.next());
|
||||
e.previous = before;
|
||||
Entry prev = e;
|
||||
Entry firstNew = e;
|
||||
Entry<T> prev = e;
|
||||
Entry<T> firstNew = e;
|
||||
|
||||
// Create and link all the remaining entries.
|
||||
for (int pos = 1; pos < csize; pos++)
|
||||
{
|
||||
e = new Entry(itr.next());
|
||||
e = new Entry<T>(itr.next());
|
||||
e.previous = prev;
|
||||
prev.next = e;
|
||||
prev = e;
|
||||
@@ -518,7 +518,7 @@ public class LinkedList extends AbstractSequentialList
|
||||
* @return the element at index
|
||||
* @throws IndexOutOfBoundsException if index < 0 || index >= size()
|
||||
*/
|
||||
public Object get(int index)
|
||||
public T get(int index)
|
||||
{
|
||||
checkBoundsExclusive(index);
|
||||
return getEntry(index).data;
|
||||
@@ -532,11 +532,11 @@ public class LinkedList extends AbstractSequentialList
|
||||
* @return the prior element
|
||||
* @throws IndexOutOfBoundsException if index < 0 || index >= size()
|
||||
*/
|
||||
public Object set(int index, Object o)
|
||||
public T set(int index, T o)
|
||||
{
|
||||
checkBoundsExclusive(index);
|
||||
Entry e = getEntry(index);
|
||||
Object old = e.data;
|
||||
Entry<T> e = getEntry(index);
|
||||
T old = e.data;
|
||||
e.data = o;
|
||||
return old;
|
||||
}
|
||||
@@ -548,15 +548,15 @@ public class LinkedList extends AbstractSequentialList
|
||||
* @param o the element to insert
|
||||
* @throws IndexOutOfBoundsException if index < 0 || index > size()
|
||||
*/
|
||||
public void add(int index, Object o)
|
||||
public void add(int index, T o)
|
||||
{
|
||||
checkBoundsInclusive(index);
|
||||
Entry e = new Entry(o);
|
||||
Entry<T> e = new Entry<T>(o);
|
||||
|
||||
if (index < size)
|
||||
{
|
||||
modCount++;
|
||||
Entry after = getEntry(index);
|
||||
Entry<T> after = getEntry(index);
|
||||
e.next = after;
|
||||
e.previous = after.previous;
|
||||
if (after.previous == null)
|
||||
@@ -577,10 +577,10 @@ public class LinkedList extends AbstractSequentialList
|
||||
* @return the removed element
|
||||
* @throws IndexOutOfBoundsException if index < 0 || index > size()
|
||||
*/
|
||||
public Object remove(int index)
|
||||
public T remove(int index)
|
||||
{
|
||||
checkBoundsExclusive(index);
|
||||
Entry e = getEntry(index);
|
||||
Entry<T> e = getEntry(index);
|
||||
removeEntry(e);
|
||||
return e.data;
|
||||
}
|
||||
@@ -594,7 +594,7 @@ public class LinkedList extends AbstractSequentialList
|
||||
public int indexOf(Object o)
|
||||
{
|
||||
int index = 0;
|
||||
Entry e = first;
|
||||
Entry<T> e = first;
|
||||
while (e != null)
|
||||
{
|
||||
if (equals(o, e.data))
|
||||
@@ -614,7 +614,7 @@ public class LinkedList extends AbstractSequentialList
|
||||
public int lastIndexOf(Object o)
|
||||
{
|
||||
int index = size - 1;
|
||||
Entry e = last;
|
||||
Entry<T> e = last;
|
||||
while (e != null)
|
||||
{
|
||||
if (equals(o, e.data))
|
||||
@@ -634,10 +634,10 @@ public class LinkedList extends AbstractSequentialList
|
||||
* next(), or size() to be initially positioned at the end of the list
|
||||
* @throws IndexOutOfBoundsException if index < 0 || index > size()
|
||||
*/
|
||||
public ListIterator listIterator(int index)
|
||||
public ListIterator<T> listIterator(int index)
|
||||
{
|
||||
checkBoundsInclusive(index);
|
||||
return new LinkedListItr(index);
|
||||
return new LinkedListItr<T>(index);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -648,10 +648,10 @@ public class LinkedList extends AbstractSequentialList
|
||||
*/
|
||||
public Object clone()
|
||||
{
|
||||
LinkedList copy = null;
|
||||
LinkedList<T> copy = null;
|
||||
try
|
||||
{
|
||||
copy = (LinkedList) super.clone();
|
||||
copy = (LinkedList<T>) super.clone();
|
||||
}
|
||||
catch (CloneNotSupportedException ex)
|
||||
{
|
||||
@@ -669,7 +669,7 @@ public class LinkedList extends AbstractSequentialList
|
||||
public Object[] toArray()
|
||||
{
|
||||
Object[] array = new Object[size];
|
||||
Entry e = first;
|
||||
Entry<T> e = first;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
array[i] = e.data;
|
||||
@@ -692,21 +692,65 @@ public class LinkedList extends AbstractSequentialList
|
||||
* an element in this list
|
||||
* @throws NullPointerException if a is null
|
||||
*/
|
||||
public Object[] toArray(Object[] a)
|
||||
public <S> S[] toArray(S[] a)
|
||||
{
|
||||
if (a.length < size)
|
||||
a = (Object[]) Array.newInstance(a.getClass().getComponentType(), size);
|
||||
a = (S[]) Array.newInstance(a.getClass().getComponentType(), size);
|
||||
else if (a.length > size)
|
||||
a[size] = null;
|
||||
Entry e = first;
|
||||
Entry<T> e = first;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
a[i] = e.data;
|
||||
a[i] = (S) e.data;
|
||||
e = e.next;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.5
|
||||
*/
|
||||
public boolean offer(T value)
|
||||
{
|
||||
return add(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.5
|
||||
*/
|
||||
public T element()
|
||||
{
|
||||
return getFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.5
|
||||
*/
|
||||
public T peek()
|
||||
{
|
||||
if (size == 0)
|
||||
return null;
|
||||
return getFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.5
|
||||
*/
|
||||
public T poll()
|
||||
{
|
||||
if (size == 0)
|
||||
return null;
|
||||
return removeFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.5
|
||||
*/
|
||||
public T remove()
|
||||
{
|
||||
return removeFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes this object to the given stream.
|
||||
*
|
||||
@@ -719,7 +763,7 @@ public class LinkedList extends AbstractSequentialList
|
||||
{
|
||||
s.defaultWriteObject();
|
||||
s.writeInt(size);
|
||||
Entry e = first;
|
||||
Entry<T> e = first;
|
||||
while (e != null)
|
||||
{
|
||||
s.writeObject(e.data);
|
||||
@@ -742,7 +786,7 @@ public class LinkedList extends AbstractSequentialList
|
||||
s.defaultReadObject();
|
||||
int i = s.readInt();
|
||||
while (--i >= 0)
|
||||
addLastEntry(new Entry(s.readObject()));
|
||||
addLastEntry(new Entry<T>((T) s.readObject()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -752,19 +796,20 @@ public class LinkedList extends AbstractSequentialList
|
||||
* @author Original author unknown
|
||||
* @author Eric Blake (ebb9@email.byu.edu)
|
||||
*/
|
||||
private final class LinkedListItr implements ListIterator
|
||||
private final class LinkedListItr<I>
|
||||
implements ListIterator<I>
|
||||
{
|
||||
/** Number of modifications we know about. */
|
||||
private int knownMod = modCount;
|
||||
|
||||
/** Entry that will be returned by next(). */
|
||||
private Entry next;
|
||||
private Entry<I> next;
|
||||
|
||||
/** Entry that will be returned by previous(). */
|
||||
private Entry previous;
|
||||
private Entry<I> previous;
|
||||
|
||||
/** Entry that will be affected by remove() or set(). */
|
||||
private Entry lastReturned;
|
||||
private Entry<I> lastReturned;
|
||||
|
||||
/** Index of `next'. */
|
||||
private int position;
|
||||
@@ -779,11 +824,11 @@ public class LinkedList extends AbstractSequentialList
|
||||
if (index == size)
|
||||
{
|
||||
next = null;
|
||||
previous = last;
|
||||
previous = (Entry<I>) last;
|
||||
}
|
||||
else
|
||||
{
|
||||
next = getEntry(index);
|
||||
next = (Entry<I>) getEntry(index);
|
||||
previous = next.previous;
|
||||
}
|
||||
position = index;
|
||||
@@ -847,7 +892,7 @@ public class LinkedList extends AbstractSequentialList
|
||||
* @throws ConcurrentModificationException if the list was modified
|
||||
* @throws NoSuchElementException if there is no next
|
||||
*/
|
||||
public Object next()
|
||||
public I next()
|
||||
{
|
||||
checkMod();
|
||||
if (next == null)
|
||||
@@ -865,7 +910,7 @@ public class LinkedList extends AbstractSequentialList
|
||||
* @throws ConcurrentModificationException if the list was modified
|
||||
* @throws NoSuchElementException if there is no previous
|
||||
*/
|
||||
public Object previous()
|
||||
public I previous()
|
||||
{
|
||||
checkMod();
|
||||
if (previous == null)
|
||||
@@ -895,7 +940,7 @@ public class LinkedList extends AbstractSequentialList
|
||||
|
||||
next = lastReturned.next;
|
||||
previous = lastReturned.previous;
|
||||
removeEntry(lastReturned);
|
||||
removeEntry((Entry<T>) lastReturned);
|
||||
knownMod++;
|
||||
|
||||
lastReturned = null;
|
||||
@@ -907,26 +952,26 @@ public class LinkedList extends AbstractSequentialList
|
||||
* @param o the element to add
|
||||
* @throws ConcurrentModificationException if the list was modified
|
||||
*/
|
||||
public void add(Object o)
|
||||
public void add(I o)
|
||||
{
|
||||
checkMod();
|
||||
modCount++;
|
||||
knownMod++;
|
||||
size++;
|
||||
position++;
|
||||
Entry e = new Entry(o);
|
||||
Entry<I> e = new Entry<I>(o);
|
||||
e.previous = previous;
|
||||
e.next = next;
|
||||
|
||||
if (previous != null)
|
||||
previous.next = e;
|
||||
else
|
||||
first = e;
|
||||
first = (Entry<T>) e;
|
||||
|
||||
if (next != null)
|
||||
next.previous = e;
|
||||
else
|
||||
last = e;
|
||||
last = (Entry<T>) e;
|
||||
|
||||
previous = e;
|
||||
lastReturned = null;
|
||||
@@ -939,7 +984,7 @@ public class LinkedList extends AbstractSequentialList
|
||||
* @throws ConcurrentModificationException if the list was modified
|
||||
* @throws IllegalStateException if there was no last element
|
||||
*/
|
||||
public void set(Object o)
|
||||
public void set(I o)
|
||||
{
|
||||
checkMod();
|
||||
if (lastReturned == null)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* List.java -- An ordered collection which allows indexed access
|
||||
Copyright (C) 1998, 2001, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 2001, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -80,7 +80,7 @@ package java.util;
|
||||
* @since 1.2
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public interface List extends Collection
|
||||
public interface List<E> extends Collection<E>
|
||||
{
|
||||
/**
|
||||
* Insert an element into the list at a given position (optional operation).
|
||||
@@ -100,7 +100,7 @@ public interface List extends Collection
|
||||
* @throws NullPointerException if o is null and this list doesn't support
|
||||
* the addition of null values.
|
||||
*/
|
||||
void add(int index, Object o);
|
||||
void add(int index, E o);
|
||||
|
||||
/**
|
||||
* Add an element to the end of the list (optional operation). If the list
|
||||
@@ -118,7 +118,7 @@ public interface List extends Collection
|
||||
* @throws NullPointerException if o is null and this list doesn't support
|
||||
* the addition of null values.
|
||||
*/
|
||||
boolean add(Object o);
|
||||
boolean add(E o);
|
||||
|
||||
/**
|
||||
* Insert the contents of a collection into the list at a given position
|
||||
@@ -143,7 +143,7 @@ public interface List extends Collection
|
||||
* @throws NullPointerException if the specified collection is null
|
||||
* @see #add(int, Object)
|
||||
*/
|
||||
boolean addAll(int index, Collection c);
|
||||
boolean addAll(int index, Collection<? extends E> c);
|
||||
|
||||
/**
|
||||
* Add the contents of a collection to the end of the list (optional
|
||||
@@ -165,7 +165,7 @@ public interface List extends Collection
|
||||
* doesn't support the addition of null values.
|
||||
* @see #add(Object)
|
||||
*/
|
||||
boolean addAll(Collection c);
|
||||
boolean addAll(Collection<? extends E> c);
|
||||
|
||||
/**
|
||||
* Clear the list, such that a subsequent call to isEmpty() would return
|
||||
@@ -202,7 +202,7 @@ public interface List extends Collection
|
||||
* list does not support null values.
|
||||
* @see #contains(Object)
|
||||
*/
|
||||
boolean containsAll(Collection c);
|
||||
boolean containsAll(Collection<?> c);
|
||||
|
||||
/**
|
||||
* Test whether this list is equal to another object. A List is defined to be
|
||||
@@ -226,7 +226,7 @@ public interface List extends Collection
|
||||
* @return the element at index index in this list
|
||||
* @throws IndexOutOfBoundsException if index < 0 || index >= size()
|
||||
*/
|
||||
Object get(int index);
|
||||
E get(int index);
|
||||
|
||||
/**
|
||||
* Obtains a hash code for this list. In order to obey the general
|
||||
@@ -276,7 +276,7 @@ while (i.hasNext())
|
||||
*
|
||||
* @return an Iterator over the elements of this list, in order
|
||||
*/
|
||||
Iterator iterator();
|
||||
Iterator<E> iterator();
|
||||
|
||||
/**
|
||||
* Obtain the last index at which a given object is to be found in this
|
||||
@@ -297,7 +297,7 @@ while (i.hasNext())
|
||||
* @return a ListIterator over the elements of this list, in order, starting
|
||||
* at the beginning
|
||||
*/
|
||||
ListIterator listIterator();
|
||||
ListIterator<E> listIterator();
|
||||
|
||||
/**
|
||||
* Obtain a ListIterator over this list, starting at a given position.
|
||||
@@ -310,7 +310,7 @@ while (i.hasNext())
|
||||
* at index
|
||||
* @throws IndexOutOfBoundsException if index < 0 || index > size()
|
||||
*/
|
||||
ListIterator listIterator(int index);
|
||||
ListIterator<E> listIterator(int index);
|
||||
|
||||
/**
|
||||
* Remove the element at a given position in this list (optional operation).
|
||||
@@ -322,7 +322,7 @@ while (i.hasNext())
|
||||
* remove operation
|
||||
* @throws IndexOutOfBoundsException if index < 0 || index >= size()
|
||||
*/
|
||||
Object remove(int index);
|
||||
E remove(int index);
|
||||
|
||||
/**
|
||||
* Remove the first occurence of an object from this list (optional
|
||||
@@ -357,7 +357,7 @@ while (i.hasNext())
|
||||
* @see #remove(Object)
|
||||
* @see #contains(Object)
|
||||
*/
|
||||
boolean removeAll(Collection c);
|
||||
boolean removeAll(Collection<?> c);
|
||||
|
||||
/**
|
||||
* Remove all elements of this list that are not contained in a given
|
||||
@@ -376,7 +376,7 @@ while (i.hasNext())
|
||||
* @see #remove(Object)
|
||||
* @see #contains(Object)
|
||||
*/
|
||||
boolean retainAll(Collection c);
|
||||
boolean retainAll(Collection<?> c);
|
||||
|
||||
/**
|
||||
* Replace an element of this list with another object (optional operation).
|
||||
@@ -394,7 +394,7 @@ while (i.hasNext())
|
||||
* @throws NullPointerException if o is null and this
|
||||
* list does not support null values.
|
||||
*/
|
||||
Object set(int index, Object o);
|
||||
E set(int index, E o);
|
||||
|
||||
/**
|
||||
* Get the number of elements in this list. If the list contains more
|
||||
@@ -420,7 +420,7 @@ while (i.hasNext())
|
||||
* @throws IndexOutOfBoundsException if fromIndex < 0
|
||||
* || toIndex > size() || fromIndex > toIndex
|
||||
*/
|
||||
List subList(int fromIndex, int toIndex);
|
||||
List<E> subList(int fromIndex, int toIndex);
|
||||
|
||||
/**
|
||||
* Copy the current contents of this list into an array.
|
||||
@@ -447,5 +447,5 @@ while (i.hasNext())
|
||||
* collection is not a subtype of the element type of a
|
||||
* @throws NullPointerException if the specified array is null
|
||||
*/
|
||||
Object[] toArray(Object[] a);
|
||||
<T> T[] toArray(T[] a);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* ListIterator.java -- Extended Iterator for iterating over ordered lists
|
||||
Copyright (C) 1998, 1999, 2001, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 1999, 2001, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -59,7 +59,7 @@ package java.util;
|
||||
* @since 1.2
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public interface ListIterator extends Iterator
|
||||
public interface ListIterator<E> extends Iterator<E>
|
||||
{
|
||||
/**
|
||||
* Tests whether there are elements remaining in the list in the forward
|
||||
@@ -88,7 +88,7 @@ public interface ListIterator extends Iterator
|
||||
* @return the next element in the list in the forward direction
|
||||
* @throws NoSuchElementException if there are no more elements
|
||||
*/
|
||||
Object next();
|
||||
E next();
|
||||
|
||||
/**
|
||||
* Obtain the next element in the list in the reverse direction. Repeated
|
||||
@@ -100,7 +100,7 @@ public interface ListIterator extends Iterator
|
||||
* @return the next element in the list in the reverse direction
|
||||
* @throws NoSuchElementException if there are no more elements
|
||||
*/
|
||||
Object previous();
|
||||
E previous();
|
||||
|
||||
/**
|
||||
* Find the index of the element that would be returned by a call to next.
|
||||
@@ -134,7 +134,7 @@ public interface ListIterator extends Iterator
|
||||
* @throws UnsupportedOperationException if this ListIterator does not
|
||||
* support the add operation.
|
||||
*/
|
||||
void add(Object o);
|
||||
void add(E o);
|
||||
|
||||
/**
|
||||
* Remove from the list the element last returned by a call to next or
|
||||
@@ -166,5 +166,5 @@ public interface ListIterator extends Iterator
|
||||
* @throws UnsupportedOperationException if this ListIterator does not
|
||||
* support the set operation
|
||||
*/
|
||||
void set(Object o);
|
||||
void set(E o);
|
||||
}
|
||||
|
||||
@@ -108,21 +108,21 @@ public abstract class ListResourceBundle extends ResourceBundle
|
||||
*
|
||||
* @return an enumeration of the keys
|
||||
*/
|
||||
public Enumeration getKeys()
|
||||
public Enumeration<String> getKeys()
|
||||
{
|
||||
// We make a new Set that holds all the keys, then return an enumeration
|
||||
// for that. This prevents modifications from ruining the enumeration,
|
||||
// as well as ignoring duplicates.
|
||||
final Object[][] contents = getContents();
|
||||
Set s = new HashSet();
|
||||
Set<String> s = new HashSet<String>();
|
||||
int i = contents.length;
|
||||
while (--i >= 0)
|
||||
s.add(contents[i][0]);
|
||||
s.add((String) contents[i][0]);
|
||||
ResourceBundle bundle = parent;
|
||||
// Eliminate tail recursion.
|
||||
while (bundle != null)
|
||||
{
|
||||
Enumeration e = bundle.getKeys();
|
||||
Enumeration<String> e = bundle.getKeys();
|
||||
while (e.hasMoreElements())
|
||||
s.add(e.nextElement());
|
||||
bundle = bundle.parent;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Locale.java -- i18n locales
|
||||
Copyright (C) 1998, 1999, 2001, 2002, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 1999, 2001, 2002, 2005, 2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -192,7 +192,7 @@ public final class Locale implements Serializable, Cloneable
|
||||
*
|
||||
* @serial should be -1 in serial streams
|
||||
*/
|
||||
private transient int hashcode;
|
||||
private int hashcode;
|
||||
|
||||
/**
|
||||
* Array storing all available locales.
|
||||
@@ -917,8 +917,8 @@ public final class Locale implements Serializable, Cloneable
|
||||
return false;
|
||||
Locale l = (Locale) obj;
|
||||
|
||||
return (language == l.language
|
||||
&& country == l.country
|
||||
return (language == l.language
|
||||
&& country == l.country
|
||||
&& variant == l.variant);
|
||||
}
|
||||
|
||||
@@ -935,11 +935,9 @@ public final class Locale implements Serializable, Cloneable
|
||||
private void writeObject(ObjectOutputStream s)
|
||||
throws IOException
|
||||
{
|
||||
s.writeObject(language);
|
||||
s.writeObject(country);
|
||||
s.writeObject(variant);
|
||||
// Hashcode field is always written as -1.
|
||||
s.writeInt(-1);
|
||||
ObjectOutputStream.PutField fields = s.putFields();
|
||||
fields.put("hashcode", -1);
|
||||
s.defaultWriteObject();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -953,10 +951,10 @@ public final class Locale implements Serializable, Cloneable
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
language = ((String) s.readObject()).intern();
|
||||
country = ((String) s.readObject()).intern();
|
||||
variant = ((String) s.readObject()).intern();
|
||||
// Recompute hashcode.
|
||||
s.defaultReadObject();
|
||||
language = language.intern();
|
||||
country = country.intern();
|
||||
variant = variant.intern();
|
||||
hashcode = language.hashCode() ^ country.hashCode() ^ variant.hashCode();
|
||||
}
|
||||
} // class Locale
|
||||
|
||||
@@ -78,7 +78,7 @@ package java.util;
|
||||
* @since 1.2
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public interface Map
|
||||
public interface Map<K, V>
|
||||
{
|
||||
/**
|
||||
* Remove all entries from this Map (optional operation).
|
||||
@@ -127,7 +127,7 @@ public interface Map
|
||||
* @return the set view of all mapping entries
|
||||
* @see Map.Entry
|
||||
*/
|
||||
Set entrySet();
|
||||
Set<Map.Entry<K, V>> entrySet();
|
||||
|
||||
/**
|
||||
* Compares the specified object with this map for equality. Returns
|
||||
@@ -153,7 +153,7 @@ public interface Map
|
||||
* @throws NullPointerException if this map does not accept null keys
|
||||
* @see #containsKey(Object)
|
||||
*/
|
||||
Object get(Object key);
|
||||
V get(Object key);
|
||||
|
||||
/**
|
||||
* Associates the given key to the given value (optional operation). If the
|
||||
@@ -172,7 +172,7 @@ public interface Map
|
||||
* and the map forbids null keys or values
|
||||
* @see #containsKey(Object)
|
||||
*/
|
||||
Object put(Object key, Object value);
|
||||
V put(K key, V value);
|
||||
|
||||
/**
|
||||
* Returns the hash code for this map. This is the sum of all hashcodes
|
||||
@@ -204,7 +204,7 @@ public interface Map
|
||||
*
|
||||
* @return the set view of all keys
|
||||
*/
|
||||
Set keySet();
|
||||
Set<K> keySet();
|
||||
|
||||
/**
|
||||
* Copies all entries of the given map to this one (optional operation). If
|
||||
@@ -219,7 +219,7 @@ public interface Map
|
||||
* if <code>m</code> is null.
|
||||
* @see #put(Object, Object)
|
||||
*/
|
||||
void putAll(Map m);
|
||||
void putAll(Map<? extends K, ? extends V> m);
|
||||
|
||||
/**
|
||||
* Removes the mapping for this key if present (optional operation). If
|
||||
@@ -234,7 +234,7 @@ public interface Map
|
||||
* @throws ClassCastException if the type of the key is not a valid type
|
||||
* for this map.
|
||||
*/
|
||||
Object remove(Object key);
|
||||
V remove(Object o);
|
||||
|
||||
/**
|
||||
* Returns the number of key-value mappings in the map. If there are more
|
||||
@@ -257,7 +257,7 @@ public interface Map
|
||||
*
|
||||
* @return the collection view of all values
|
||||
*/
|
||||
Collection values();
|
||||
Collection<V> values();
|
||||
|
||||
/**
|
||||
* A map entry (key-value pair). The Map.entrySet() method returns a set
|
||||
@@ -273,14 +273,14 @@ public interface Map
|
||||
* @since 1.2
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
interface Entry
|
||||
interface Entry<K, V>
|
||||
{
|
||||
/**
|
||||
* Get the key corresponding to this entry.
|
||||
*
|
||||
* @return the key
|
||||
*/
|
||||
Object getKey();
|
||||
K getKey();
|
||||
|
||||
/**
|
||||
* Get the value corresponding to this entry. If you already called
|
||||
@@ -288,7 +288,7 @@ public interface Map
|
||||
*
|
||||
* @return the value
|
||||
*/
|
||||
Object getValue();
|
||||
V getValue();
|
||||
|
||||
/**
|
||||
* Replaces the value with the specified object (optional operation).
|
||||
@@ -303,7 +303,7 @@ public interface Map
|
||||
* prevents it from existing in this map
|
||||
* @throws NullPointerException if the map forbids null values
|
||||
*/
|
||||
Object setValue(Object value);
|
||||
V setValue(V value);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,335 @@
|
||||
/* PriorityQueue.java -- Unbounded priority queue
|
||||
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.util;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author Tom Tromey (tromey@redhat.com)
|
||||
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class PriorityQueue<E> extends AbstractQueue<E> implements Serializable
|
||||
{
|
||||
private static final int DEFAULT_CAPACITY = 11;
|
||||
|
||||
private static final long serialVersionUID = -7720805057305804111L;
|
||||
|
||||
/** Number of elements actually used in the storage array. */
|
||||
int used;
|
||||
|
||||
/**
|
||||
* This is the storage for the underlying binomial heap.
|
||||
* The idea is, each node is less than or equal to its children.
|
||||
* A node at index N (0-based) has two direct children, at
|
||||
* nodes 2N+1 and 2N+2.
|
||||
*/
|
||||
E[] storage;
|
||||
|
||||
/**
|
||||
* The comparator we're using, or null for natural ordering.
|
||||
*/
|
||||
Comparator<? super E> comparator;
|
||||
|
||||
public PriorityQueue()
|
||||
{
|
||||
this(DEFAULT_CAPACITY, null);
|
||||
}
|
||||
|
||||
public PriorityQueue(Collection<? extends E> c)
|
||||
{
|
||||
this(Math.max(1, (int) (1.1 * c.size())), null);
|
||||
|
||||
// Special case where we can find the comparator to use.
|
||||
if (c instanceof SortedSet)
|
||||
{
|
||||
SortedSet<? extends E> ss = (SortedSet<? extends E>) c;
|
||||
this.comparator = (Comparator<? super E>) ss.comparator();
|
||||
// We can insert the elements directly, since they are sorted.
|
||||
int i = 0;
|
||||
for (E val : ss)
|
||||
{
|
||||
if (val == null)
|
||||
throw new NullPointerException();
|
||||
storage[i++] = val;
|
||||
}
|
||||
}
|
||||
else if (c instanceof PriorityQueue)
|
||||
{
|
||||
PriorityQueue<? extends E> pq = (PriorityQueue<? extends E>) c;
|
||||
this.comparator = (Comparator<? super E>)pq.comparator();
|
||||
// We can just copy the contents.
|
||||
System.arraycopy(pq.storage, 0, storage, 0, pq.storage.length);
|
||||
}
|
||||
|
||||
addAll(c);
|
||||
}
|
||||
|
||||
public PriorityQueue(int cap)
|
||||
{
|
||||
this(cap, null);
|
||||
}
|
||||
|
||||
public PriorityQueue(int cap, Comparator<? super E> comp)
|
||||
{
|
||||
if (cap < 1)
|
||||
throw new IllegalArgumentException();
|
||||
this.used = 0;
|
||||
this.storage = (E[]) new Object[cap];
|
||||
this.comparator = comp;
|
||||
}
|
||||
|
||||
public PriorityQueue(PriorityQueue<? extends E> c)
|
||||
{
|
||||
this(Math.max(1, (int) (1.1 * c.size())),
|
||||
(Comparator<? super E>)c.comparator());
|
||||
// We can just copy the contents.
|
||||
System.arraycopy(c.storage, 0, storage, 0, c.storage.length);
|
||||
}
|
||||
|
||||
public PriorityQueue(SortedSet<? extends E> c)
|
||||
{
|
||||
this(Math.max(1, (int) (1.1 * c.size())),
|
||||
(Comparator<? super E>)c.comparator());
|
||||
// We can insert the elements directly, since they are sorted.
|
||||
int i = 0;
|
||||
for (E val : c)
|
||||
{
|
||||
if (val == null)
|
||||
throw new NullPointerException();
|
||||
storage[i++] = val;
|
||||
}
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
Arrays.fill(storage, null);
|
||||
used = 0;
|
||||
}
|
||||
|
||||
public Comparator<? super E> comparator()
|
||||
{
|
||||
return comparator;
|
||||
}
|
||||
|
||||
public Iterator<E> iterator()
|
||||
{
|
||||
return new Iterator<E>()
|
||||
{
|
||||
int index = -1;
|
||||
int count = 0;
|
||||
|
||||
public boolean hasNext()
|
||||
{
|
||||
return count < used;
|
||||
}
|
||||
|
||||
public E next()
|
||||
{
|
||||
while (storage[++index] == null)
|
||||
;
|
||||
++count;
|
||||
return storage[index];
|
||||
}
|
||||
|
||||
public void remove()
|
||||
{
|
||||
PriorityQueue.this.remove(index);
|
||||
index--;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public boolean offer(E o)
|
||||
{
|
||||
if (o == null)
|
||||
throw new NullPointerException();
|
||||
|
||||
int slot = findSlot(-1);
|
||||
|
||||
storage[slot] = o;
|
||||
++used;
|
||||
bubbleUp(slot);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public E peek()
|
||||
{
|
||||
return used == 0 ? null : storage[0];
|
||||
}
|
||||
|
||||
public E poll()
|
||||
{
|
||||
if (used == 0)
|
||||
return null;
|
||||
E result = storage[0];
|
||||
remove(0);
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean remove(Object o)
|
||||
{
|
||||
if (o != null)
|
||||
{
|
||||
for (int i = 0; i < storage.length; ++i)
|
||||
{
|
||||
if (o.equals(storage[i]))
|
||||
{
|
||||
remove(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int size()
|
||||
{
|
||||
return used;
|
||||
}
|
||||
|
||||
// It is more efficient to implement this locally -- less searching
|
||||
// for free slots.
|
||||
public boolean addAll(Collection<? extends E> c)
|
||||
{
|
||||
if (c == this)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
int newSlot = -1;
|
||||
int save = used;
|
||||
for (E val : c)
|
||||
{
|
||||
if (val == null)
|
||||
throw new NullPointerException();
|
||||
newSlot = findSlot(newSlot);
|
||||
storage[newSlot] = val;
|
||||
++used;
|
||||
bubbleUp(newSlot);
|
||||
}
|
||||
|
||||
return save != used;
|
||||
}
|
||||
|
||||
int findSlot(int start)
|
||||
{
|
||||
int slot;
|
||||
if (used == storage.length)
|
||||
{
|
||||
resize();
|
||||
slot = used;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (slot = start + 1; slot < storage.length; ++slot)
|
||||
{
|
||||
if (storage[slot] == null)
|
||||
break;
|
||||
}
|
||||
// We'll always find a slot.
|
||||
}
|
||||
return slot;
|
||||
}
|
||||
|
||||
void remove(int index)
|
||||
{
|
||||
// Remove the element at INDEX. We do this by finding the least
|
||||
// child and moving it into place, then iterating until we reach
|
||||
// the bottom of the tree.
|
||||
while (storage[index] != null)
|
||||
{
|
||||
int child = 2 * index + 1;
|
||||
|
||||
// See if we went off the end.
|
||||
if (child >= storage.length)
|
||||
{
|
||||
storage[index] = null;
|
||||
break;
|
||||
}
|
||||
|
||||
// Find which child we want to promote. If one is not null,
|
||||
// we pick it. If both are null, it doesn't matter, we're
|
||||
// about to leave. If neither is null, pick the lesser.
|
||||
if (child + 1 >= storage.length || storage[child + 1] == null)
|
||||
{
|
||||
// Nothing.
|
||||
}
|
||||
else if (storage[child] == null
|
||||
|| (Collections.compare(storage[child], storage[child + 1],
|
||||
comparator) > 0))
|
||||
++child;
|
||||
storage[index] = storage[child];
|
||||
index = child;
|
||||
}
|
||||
--used;
|
||||
}
|
||||
|
||||
void bubbleUp(int index)
|
||||
{
|
||||
// The element at INDEX was inserted into a blank spot. Now move
|
||||
// it up the tree to its natural resting place.
|
||||
while (index > 0)
|
||||
{
|
||||
// This works regardless of whether we're at 2N+1 or 2N+2.
|
||||
int parent = (index - 1) / 2;
|
||||
if (Collections.compare(storage[parent], storage[index], comparator)
|
||||
<= 0)
|
||||
{
|
||||
// Parent is the same or smaller than this element, so the
|
||||
// invariant is preserved. Note that if the new element
|
||||
// is smaller than the parent, then it is necessarily
|
||||
// smaller than the parent's other child.
|
||||
break;
|
||||
}
|
||||
|
||||
E temp = storage[index];
|
||||
storage[index] = storage[parent];
|
||||
storage[parent] = temp;
|
||||
|
||||
index = parent;
|
||||
}
|
||||
}
|
||||
|
||||
void resize()
|
||||
{
|
||||
E[] new_data = (E[]) new Object[2 * storage.length];
|
||||
System.arraycopy(storage, 0, new_data, 0, storage.length);
|
||||
storage = new_data;
|
||||
}
|
||||
}
|
||||
@@ -104,7 +104,7 @@ s16=1,3</pre>
|
||||
* @see PropertyResourceBundle
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public class Properties extends Hashtable
|
||||
public class Properties extends Hashtable<Object, Object>
|
||||
{
|
||||
// WARNING: Properties is a CORE class in the bootstrap cycle. See the
|
||||
// comments in vm/reference/java/lang/Runtime for implications of this fact.
|
||||
@@ -370,6 +370,7 @@ label = Name:\\u0020</pre>
|
||||
* value that are not strings
|
||||
* @deprecated use {@link #store(OutputStream, String)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public void save(OutputStream out, String header)
|
||||
{
|
||||
try
|
||||
@@ -489,7 +490,7 @@ label = Name:\\u0020</pre>
|
||||
*
|
||||
* @return an Enumeration of all defined keys
|
||||
*/
|
||||
public Enumeration propertyNames()
|
||||
public Enumeration<?> propertyNames()
|
||||
{
|
||||
// We make a new Set that holds all the keys, then return an enumeration
|
||||
// for that. This prevents modifications from ruining the enumeration,
|
||||
|
||||
@@ -126,15 +126,17 @@ public class PropertyResourceBundle extends ResourceBundle
|
||||
*
|
||||
* @return an enumeration of the keys
|
||||
*/
|
||||
public Enumeration getKeys()
|
||||
public Enumeration<String> getKeys()
|
||||
{
|
||||
if (parent == null)
|
||||
return properties.propertyNames();
|
||||
// FIXME: bogus cast.
|
||||
return (Enumeration<String>) properties.propertyNames();
|
||||
// We make a new Set that holds all the keys, then return an enumeration
|
||||
// for that. This prevents modifications from ruining the enumeration,
|
||||
// as well as ignoring duplicates.
|
||||
Set s = new HashSet();
|
||||
Enumeration e = properties.propertyNames();
|
||||
Set<String> s = new HashSet<String>();
|
||||
// FIXME: bogus cast.
|
||||
Enumeration<String> e = (Enumeration<String>) properties.propertyNames();
|
||||
while (e.hasMoreElements())
|
||||
s.add(e.nextElement());
|
||||
ResourceBundle bundle = parent;
|
||||
|
||||
@@ -90,6 +90,14 @@ baseName</pre>
|
||||
*/
|
||||
public abstract class ResourceBundle
|
||||
{
|
||||
/**
|
||||
* Maximum size of our cache of <code>ResourceBundle</code>s keyed by
|
||||
* {@link BundleKey} instances.
|
||||
*
|
||||
* @see BundleKey
|
||||
*/
|
||||
private static final int CACHE_SIZE = 100;
|
||||
|
||||
/**
|
||||
* The parent bundle. This is consulted when you call getObject and there
|
||||
* is no such resource in the current bundle. This field may be null.
|
||||
@@ -104,21 +112,22 @@ public abstract class ResourceBundle
|
||||
private Locale locale;
|
||||
|
||||
/**
|
||||
* The resource bundle cache.
|
||||
* A VM-wide cache of resource bundles already fetched.
|
||||
* <p>
|
||||
* This {@link Map} is a Least Recently Used (LRU) cache, of the last
|
||||
* {@link #CACHE_SIZE} accessed <code>ResourceBundle</code>s keyed by the
|
||||
* tuple: default locale, resource-bundle name, resource-bundle locale, and
|
||||
* classloader.
|
||||
*
|
||||
* @see BundleKey
|
||||
*/
|
||||
private static Map bundleCache;
|
||||
|
||||
/**
|
||||
* The last default Locale we saw. If this ever changes then we have to
|
||||
* reset our caches.
|
||||
*/
|
||||
private static Locale lastDefaultLocale;
|
||||
|
||||
/**
|
||||
* The `empty' locale is created once in order to optimize
|
||||
* tryBundle().
|
||||
*/
|
||||
private static final Locale emptyLocale = new Locale("");
|
||||
private static Map bundleCache = new LinkedHashMap(CACHE_SIZE + 1, 0.75F, true)
|
||||
{
|
||||
public boolean removeEldestEntry(Map.Entry entry)
|
||||
{
|
||||
return size() > CACHE_SIZE;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The constructor. It does nothing special.
|
||||
@@ -246,6 +255,7 @@ public abstract class ResourceBundle
|
||||
by the combination of bundle name, locale, and class loader. */
|
||||
private static class BundleKey
|
||||
{
|
||||
Locale defaultLocale;
|
||||
String baseName;
|
||||
Locale locale;
|
||||
ClassLoader classLoader;
|
||||
@@ -253,18 +263,19 @@ public abstract class ResourceBundle
|
||||
|
||||
BundleKey() {}
|
||||
|
||||
BundleKey(String s, Locale l, ClassLoader cl)
|
||||
BundleKey(Locale dl, String s, Locale l, ClassLoader cl)
|
||||
{
|
||||
set(s, l, cl);
|
||||
set(dl, s, l, cl);
|
||||
}
|
||||
|
||||
void set(String s, Locale l, ClassLoader cl)
|
||||
void set(Locale dl, String s, Locale l, ClassLoader cl)
|
||||
{
|
||||
defaultLocale = dl;
|
||||
baseName = s;
|
||||
locale = l;
|
||||
classLoader = cl;
|
||||
hashcode = baseName.hashCode() ^ locale.hashCode() ^
|
||||
classLoader.hashCode();
|
||||
hashcode = defaultLocale.hashCode() ^ baseName.hashCode()
|
||||
^ locale.hashCode() ^ classLoader.hashCode();
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
@@ -277,10 +288,11 @@ public abstract class ResourceBundle
|
||||
if (! (o instanceof BundleKey))
|
||||
return false;
|
||||
BundleKey key = (BundleKey) o;
|
||||
return hashcode == key.hashcode &&
|
||||
baseName.equals(key.baseName) &&
|
||||
locale.equals(key.locale) &&
|
||||
classLoader.equals(key.classLoader);
|
||||
return hashcode == key.hashcode
|
||||
&& defaultLocale.equals(key.defaultLocale)
|
||||
&& baseName.equals(key.baseName)
|
||||
&& locale.equals(key.locale)
|
||||
&& classLoader.equals(key.classLoader);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -370,61 +382,39 @@ public abstract class ResourceBundle
|
||||
public static synchronized ResourceBundle getBundle
|
||||
(String baseName, Locale locale, ClassLoader classLoader)
|
||||
{
|
||||
// If the default locale changed since the last time we were called,
|
||||
// all cache entries are invalidated.
|
||||
Locale defaultLocale = Locale.getDefault();
|
||||
if (defaultLocale != lastDefaultLocale)
|
||||
{
|
||||
bundleCache = new HashMap();
|
||||
lastDefaultLocale = defaultLocale;
|
||||
}
|
||||
|
||||
// This will throw NullPointerException if any arguments are null.
|
||||
lookupKey.set(baseName, locale, classLoader);
|
||||
|
||||
lookupKey.set(defaultLocale, baseName, locale, classLoader);
|
||||
Object obj = bundleCache.get(lookupKey);
|
||||
ResourceBundle rb = null;
|
||||
|
||||
if (obj instanceof ResourceBundle)
|
||||
{
|
||||
return (ResourceBundle) obj;
|
||||
}
|
||||
else if (obj == nullEntry)
|
||||
{
|
||||
// Lookup has failed previously. Fall through.
|
||||
}
|
||||
else
|
||||
{
|
||||
// First, look for a bundle for the specified locale. We don't want
|
||||
// the base bundle this time.
|
||||
boolean wantBase = locale.equals(defaultLocale);
|
||||
ResourceBundle bundle = tryBundle(baseName, locale, classLoader,
|
||||
wantBase);
|
||||
return (ResourceBundle) obj;
|
||||
|
||||
// Try the default locale if neccessary.
|
||||
if (bundle == null && !locale.equals(defaultLocale))
|
||||
bundle = tryBundle(baseName, defaultLocale, classLoader, true);
|
||||
if (obj == nullEntry)
|
||||
throw new MissingResourceException("Bundle " + baseName
|
||||
+ " not found for locale " + locale
|
||||
+ " by classloader " + classLoader,
|
||||
baseName, "");
|
||||
// First, look for a bundle for the specified locale. We don't want
|
||||
// the base bundle this time.
|
||||
boolean wantBase = locale.equals(defaultLocale);
|
||||
ResourceBundle bundle = tryBundle(baseName, locale, classLoader, wantBase);
|
||||
// Try the default locale if neccessary.
|
||||
if (bundle == null && ! wantBase)
|
||||
bundle = tryBundle(baseName, defaultLocale, classLoader, true);
|
||||
|
||||
BundleKey key = new BundleKey(baseName, locale, classLoader);
|
||||
if (bundle == null)
|
||||
{
|
||||
// Cache the fact that this lookup has previously failed.
|
||||
bundleCache.put(key, nullEntry);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Cache the result and return it.
|
||||
bundleCache.put(key, bundle);
|
||||
return bundle;
|
||||
}
|
||||
BundleKey key = new BundleKey(defaultLocale, baseName, locale, classLoader);
|
||||
if (bundle == null)
|
||||
{
|
||||
// Cache the fact that this lookup has previously failed.
|
||||
bundleCache.put(key, nullEntry);
|
||||
throw new MissingResourceException("Bundle " + baseName
|
||||
+ " not found for locale " + locale
|
||||
+ " by classloader " + classLoader,
|
||||
baseName, "");
|
||||
}
|
||||
|
||||
throw new MissingResourceException("Bundle " + baseName
|
||||
+ " not found for locale "
|
||||
+ locale
|
||||
+ " by classloader "
|
||||
+ classLoader,
|
||||
baseName, "");
|
||||
// Cache the result and return it.
|
||||
bundleCache.put(key, bundle);
|
||||
return bundle;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -447,7 +437,7 @@ public abstract class ResourceBundle
|
||||
*
|
||||
* @return an enumeration of the keys
|
||||
*/
|
||||
public abstract Enumeration getKeys();
|
||||
public abstract Enumeration<String> getKeys();
|
||||
|
||||
/**
|
||||
* Tries to load a class or a property file with the specified name.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* Set.java -- A collection that prohibits duplicates
|
||||
Copyright (C) 1998, 2001, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 2001, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -66,7 +67,7 @@ package java.util;
|
||||
* @since 1.2
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public interface Set extends Collection
|
||||
public interface Set<E> extends Collection<E>
|
||||
{
|
||||
/**
|
||||
* Adds the specified element to the set if it is not already present
|
||||
@@ -83,7 +84,7 @@ public interface Set extends Collection
|
||||
* being added
|
||||
* @throws NullPointerException if null is not permitted in this set
|
||||
*/
|
||||
boolean add(Object o);
|
||||
boolean add(E o);
|
||||
|
||||
/**
|
||||
* Adds all of the elements of the given collection to this set (optional
|
||||
@@ -102,7 +103,7 @@ public interface Set extends Collection
|
||||
* if the argument c is null
|
||||
* @see #add(Object)
|
||||
*/
|
||||
boolean addAll(Collection c);
|
||||
boolean addAll(Collection<? extends E> c);
|
||||
|
||||
/**
|
||||
* Removes all elements from this set (optional operation). This set will
|
||||
@@ -139,7 +140,7 @@ public interface Set extends Collection
|
||||
* set doesn't support null values.
|
||||
* @see #contains(Object)
|
||||
*/
|
||||
boolean containsAll(Collection c);
|
||||
boolean containsAll(Collection<?> c);
|
||||
|
||||
/**
|
||||
* Compares the specified object to this for equality. For sets, the object
|
||||
@@ -173,7 +174,7 @@ public interface Set extends Collection
|
||||
*
|
||||
* @return a set iterator
|
||||
*/
|
||||
Iterator iterator();
|
||||
Iterator<E> iterator();
|
||||
|
||||
/**
|
||||
* Removes the specified element from this set (optional operation). If
|
||||
@@ -205,7 +206,7 @@ public interface Set extends Collection
|
||||
* set doesn't support removing null values.
|
||||
* @see #remove(Object)
|
||||
*/
|
||||
boolean removeAll(Collection c);
|
||||
boolean removeAll(Collection<?> c);
|
||||
|
||||
/**
|
||||
* Retains only the elements in this set that are also in the specified
|
||||
@@ -222,7 +223,7 @@ public interface Set extends Collection
|
||||
* set doesn't support retaining null values.
|
||||
* @see #remove(Object)
|
||||
*/
|
||||
boolean retainAll(Collection c);
|
||||
boolean retainAll(Collection<?> c);
|
||||
|
||||
/**
|
||||
* Returns the number of elements in the set. If there are more
|
||||
@@ -260,5 +261,5 @@ public interface Set extends Collection
|
||||
* @throws NullPointerException if a is null
|
||||
* @see #toArray()
|
||||
*/
|
||||
Object[] toArray(Object[] a);
|
||||
<T> T[] toArray(T[] a);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* SortedMap.java -- A map that makes guarantees about the order of its keys
|
||||
Copyright (C) 1998, 2001, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 2001, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -72,7 +72,7 @@ package java.util;
|
||||
* @since 1.2
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public interface SortedMap extends Map
|
||||
public interface SortedMap<K, V> extends Map<K, V>
|
||||
{
|
||||
/**
|
||||
* Returns the comparator used in sorting this map, or null if it is
|
||||
@@ -80,7 +80,7 @@ public interface SortedMap extends Map
|
||||
*
|
||||
* @return the sorting comparator
|
||||
*/
|
||||
Comparator comparator();
|
||||
Comparator<? super K> comparator();
|
||||
|
||||
/**
|
||||
* Returns the first (lowest sorted) key in the map.
|
||||
@@ -88,7 +88,7 @@ public interface SortedMap extends Map
|
||||
* @return the first key
|
||||
* @throws NoSuchElementException if this map is empty.
|
||||
*/
|
||||
Object firstKey();
|
||||
K firstKey();
|
||||
|
||||
/**
|
||||
* Returns a view of the portion of the map strictly less than toKey. The
|
||||
@@ -110,7 +110,7 @@ public interface SortedMap extends Map
|
||||
* @throws NullPointerException if toKey is null but the map does not allow
|
||||
* null keys
|
||||
*/
|
||||
SortedMap headMap(Object toKey);
|
||||
SortedMap<K, V> headMap(K toKey);
|
||||
|
||||
/**
|
||||
* Returns the last (highest sorted) key in the map.
|
||||
@@ -118,7 +118,7 @@ public interface SortedMap extends Map
|
||||
* @return the last key
|
||||
* @throws NoSuchElementException if this map is empty.
|
||||
*/
|
||||
Object lastKey();
|
||||
K lastKey();
|
||||
|
||||
/**
|
||||
* Returns a view of the portion of the map greater than or equal to
|
||||
@@ -146,7 +146,7 @@ public interface SortedMap extends Map
|
||||
* @throws NullPointerException if fromKey or toKey is null but the map
|
||||
* does not allow null keys
|
||||
*/
|
||||
SortedMap subMap(Object fromKey, Object toKey);
|
||||
SortedMap<K, V> subMap(K fromKey, K toKey);
|
||||
|
||||
/**
|
||||
* Returns a view of the portion of the map greater than or equal to
|
||||
@@ -169,5 +169,5 @@ public interface SortedMap extends Map
|
||||
* @throws NullPointerException if fromKey is null but the map does not allow
|
||||
* null keys
|
||||
*/
|
||||
SortedMap tailMap(Object fromKey);
|
||||
SortedMap<K, V> tailMap(K fromKey);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SortedSet.java -- A set that makes guarantees about the order of its
|
||||
elements
|
||||
Copyright (C) 1998, 2001, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 2001, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -74,7 +74,7 @@ package java.util;
|
||||
* @since 1.2
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public interface SortedSet extends Set
|
||||
public interface SortedSet<E> extends Set<E>
|
||||
{
|
||||
/**
|
||||
* Returns the comparator used in sorting this set, or null if it is
|
||||
@@ -82,7 +82,7 @@ public interface SortedSet extends Set
|
||||
*
|
||||
* @return the sorting comparator
|
||||
*/
|
||||
Comparator comparator();
|
||||
Comparator<? super E> comparator();
|
||||
|
||||
/**
|
||||
* Returns the first (lowest sorted) element in the set.
|
||||
@@ -90,7 +90,7 @@ public interface SortedSet extends Set
|
||||
* @return the first element
|
||||
* @throws NoSuchElementException if the set is empty.
|
||||
*/
|
||||
Object first();
|
||||
E first();
|
||||
|
||||
/**
|
||||
* Returns a view of the portion of the set strictly less than toElement. The
|
||||
@@ -113,7 +113,7 @@ public interface SortedSet extends Set
|
||||
* @throws NullPointerException if toElement is null but the set does not
|
||||
* allow null elements
|
||||
*/
|
||||
SortedSet headSet(Object toElement);
|
||||
SortedSet<E> headSet(E toElement);
|
||||
|
||||
/**
|
||||
* Returns the last (highest sorted) element in the set.
|
||||
@@ -121,7 +121,7 @@ public interface SortedSet extends Set
|
||||
* @return the last element
|
||||
* @throws NoSuchElementException if the set is empty.
|
||||
*/
|
||||
Object last();
|
||||
E last();
|
||||
|
||||
/**
|
||||
* Returns a view of the portion of the set greater than or equal to
|
||||
@@ -149,7 +149,7 @@ public interface SortedSet extends Set
|
||||
* @throws NullPointerException if fromElement or toElement is null but the
|
||||
* set does not allow null elements
|
||||
*/
|
||||
SortedSet subSet(Object fromElement, Object toElement);
|
||||
SortedSet<E> subSet(E fromElement, E toElement);
|
||||
|
||||
/**
|
||||
* Returns a view of the portion of the set greater than or equal to
|
||||
@@ -172,5 +172,5 @@ public interface SortedSet extends Set
|
||||
* @throws NullPointerException if fromElement is null but the set does not
|
||||
* allow null elements
|
||||
*/
|
||||
SortedSet tailSet(Object fromElement);
|
||||
SortedSet<E> tailSet(E fromElement);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* Stack.java - Class that provides a Last In First Out (LIFO)
|
||||
datatype, known more commonly as a Stack
|
||||
Copyright (C) 1998, 1999, 2001, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 1999, 2001, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -58,7 +59,7 @@ package java.util;
|
||||
* @since 1.0
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public class Stack extends Vector
|
||||
public class Stack<T> extends Vector<T>
|
||||
{
|
||||
// We could use Vector methods internally for the following methods,
|
||||
// but have used Vector fields directly for efficiency (i.e. this
|
||||
@@ -84,7 +85,7 @@ public class Stack extends Vector
|
||||
* @return the Object pushed onto the stack
|
||||
* @see Vector#addElement(Object)
|
||||
*/
|
||||
public Object push(Object item)
|
||||
public T push(T item)
|
||||
{
|
||||
// When growing the Stack, use the Vector routines in case more
|
||||
// memory is needed.
|
||||
@@ -101,13 +102,13 @@ public class Stack extends Vector
|
||||
* @return the Object popped from the stack
|
||||
* @throws EmptyStackException if the stack is empty
|
||||
*/
|
||||
public synchronized Object pop()
|
||||
public synchronized T pop()
|
||||
{
|
||||
if (elementCount == 0)
|
||||
throw new EmptyStackException();
|
||||
|
||||
modCount++;
|
||||
Object obj = elementData[--elementCount];
|
||||
T obj = elementData[--elementCount];
|
||||
|
||||
// Set topmost element to null to assist the gc in cleanup.
|
||||
elementData[elementCount] = null;
|
||||
@@ -120,7 +121,7 @@ public class Stack extends Vector
|
||||
* @return the top Object on the stack
|
||||
* @throws EmptyStackException if the stack is empty
|
||||
*/
|
||||
public synchronized Object peek()
|
||||
public synchronized T peek()
|
||||
{
|
||||
if (elementCount == 0)
|
||||
throw new EmptyStackException();
|
||||
|
||||
@@ -58,7 +58,7 @@ package java.util;
|
||||
* @see java.io.StreamTokenizer
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public class StringTokenizer implements Enumeration
|
||||
public class StringTokenizer implements Enumeration<Object>
|
||||
{
|
||||
// WARNING: StringTokenizer is a CORE class in the bootstrap cycle. See the
|
||||
// comments in vm/reference/java/lang/Runtime for implications of this fact.
|
||||
|
||||
@@ -306,50 +306,50 @@ public class Timer
|
||||
// Null out any elements that are canceled. Skip element 0 as
|
||||
// it is the sentinel.
|
||||
for (int i = elements; i > 0; --i)
|
||||
{
|
||||
if (heap[i].scheduled < 0)
|
||||
{
|
||||
++removed;
|
||||
|
||||
// Remove an element by pushing the appropriate child
|
||||
// into place, and then iterating to the bottom of the
|
||||
// tree.
|
||||
int index = i;
|
||||
while (heap[index] != null)
|
||||
{
|
||||
int child = 2 * index;
|
||||
if (child >= heap.length)
|
||||
{
|
||||
// Off end; we're done.
|
||||
heap[index] = null;
|
||||
break;
|
||||
}
|
||||
|
||||
if (child + 1 >= heap.length || heap[child + 1] == null)
|
||||
{
|
||||
// Nothing -- we're done.
|
||||
}
|
||||
else if (heap[child] == null
|
||||
|| (heap[child].scheduled
|
||||
> heap[child + 1].scheduled))
|
||||
++child;
|
||||
heap[index] = heap[child];
|
||||
index = child;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if (heap[i].scheduled < 0)
|
||||
{
|
||||
++removed;
|
||||
|
||||
// Remove an element by pushing the appropriate child
|
||||
// into place, and then iterating to the bottom of the
|
||||
// tree.
|
||||
int index = i;
|
||||
while (heap[index] != null)
|
||||
{
|
||||
int child = 2 * index;
|
||||
if (child >= heap.length)
|
||||
{
|
||||
// Off end; we're done.
|
||||
heap[index] = null;
|
||||
break;
|
||||
}
|
||||
|
||||
if (child + 1 >= heap.length || heap[child + 1] == null)
|
||||
{
|
||||
// Nothing -- we're done.
|
||||
}
|
||||
else if (heap[child] == null
|
||||
|| (heap[child].scheduled
|
||||
> heap[child + 1].scheduled))
|
||||
++child;
|
||||
heap[index] = heap[child];
|
||||
index = child;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make a new heap if we shrank enough.
|
||||
int newLen = heap.length;
|
||||
while (elements - removed + DEFAULT_SIZE / 2 <= newLen / 4)
|
||||
newLen /= 2;
|
||||
newLen /= 2;
|
||||
if (newLen != heap.length)
|
||||
{
|
||||
TimerTask[] newHeap = new TimerTask[newLen];
|
||||
System.arraycopy(heap, 0, newHeap, 0, elements + 1);
|
||||
heap = newHeap;
|
||||
}
|
||||
|
||||
{
|
||||
TimerTask[] newHeap = new TimerTask[newLen];
|
||||
System.arraycopy(heap, 0, newHeap, 0, elements + 1);
|
||||
heap = newHeap;
|
||||
}
|
||||
|
||||
return removed;
|
||||
}
|
||||
} // TaskQueue
|
||||
@@ -474,11 +474,11 @@ public class Timer
|
||||
this(daemon, Thread.NORM_PRIORITY);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Create a new Timer whose Thread has the indicated name. It will have
|
||||
* normal priority and will not be a daemon thread.
|
||||
* @param name the name of the Thread
|
||||
* @since 1.5
|
||||
* @since 1.5
|
||||
*/
|
||||
public Timer(String name)
|
||||
{
|
||||
@@ -691,7 +691,7 @@ public class Timer
|
||||
{
|
||||
queue.setNullOnEmpty(true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes all cancelled tasks from the queue.
|
||||
* @return the number of tasks removed
|
||||
|
||||
@@ -90,8 +90,8 @@ import java.io.Serializable;
|
||||
* @since 1.2
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public class TreeMap extends AbstractMap
|
||||
implements SortedMap, Cloneable, Serializable
|
||||
public class TreeMap<K, V> extends AbstractMap<K, V>
|
||||
implements SortedMap<K, V>, Cloneable, Serializable
|
||||
{
|
||||
// Implementation note:
|
||||
// A red-black tree is a binary search tree with the additional properties
|
||||
@@ -140,7 +140,7 @@ public class TreeMap extends AbstractMap
|
||||
/**
|
||||
* The cache for {@link #entrySet()}.
|
||||
*/
|
||||
private transient Set entries;
|
||||
private transient Set<Map.Entry<K,V>> entries;
|
||||
|
||||
/**
|
||||
* Counts the number of modifications this TreeMap has undergone, used
|
||||
@@ -154,7 +154,7 @@ public class TreeMap extends AbstractMap
|
||||
* Package visible for use by nested classes.
|
||||
* @serial the comparator ordering this tree, or null
|
||||
*/
|
||||
final Comparator comparator;
|
||||
final Comparator<? super K> comparator;
|
||||
|
||||
/**
|
||||
* Class to represent an entry in the tree. Holds a single key-value pair,
|
||||
@@ -162,25 +162,25 @@ public class TreeMap extends AbstractMap
|
||||
*
|
||||
* @author Eric Blake (ebb9@email.byu.edu)
|
||||
*/
|
||||
private static final class Node extends AbstractMap.BasicMapEntry
|
||||
private static final class Node<K, V> extends AbstractMap.SimpleEntry<K, V>
|
||||
{
|
||||
// All fields package visible for use by nested classes.
|
||||
/** The color of this node. */
|
||||
int color;
|
||||
|
||||
/** The left child node. */
|
||||
Node left = nil;
|
||||
Node<K, V> left = nil;
|
||||
/** The right child node. */
|
||||
Node right = nil;
|
||||
Node<K, V> right = nil;
|
||||
/** The parent node. */
|
||||
Node parent = nil;
|
||||
Node<K, V> parent = nil;
|
||||
|
||||
/**
|
||||
* Simple constructor.
|
||||
* @param key the key
|
||||
* @param value the value
|
||||
*/
|
||||
Node(Object key, Object value, int color)
|
||||
Node(K key, V value, int color)
|
||||
{
|
||||
super(key, value);
|
||||
this.color = color;
|
||||
@@ -210,7 +210,7 @@ public class TreeMap extends AbstractMap
|
||||
* @param c the sort order for the keys of this map, or null
|
||||
* for the natural order
|
||||
*/
|
||||
public TreeMap(Comparator c)
|
||||
public TreeMap(Comparator<? super K> c)
|
||||
{
|
||||
comparator = c;
|
||||
fabricateTree(0);
|
||||
@@ -230,7 +230,7 @@ public class TreeMap extends AbstractMap
|
||||
* @throws NullPointerException if map is null
|
||||
* @see Comparable
|
||||
*/
|
||||
public TreeMap(Map map)
|
||||
public TreeMap(Map<? extends K, ? extends V> map)
|
||||
{
|
||||
this((Comparator) null);
|
||||
putAll(map);
|
||||
@@ -244,7 +244,7 @@ public class TreeMap extends AbstractMap
|
||||
* @param sm a SortedMap, whose entries will be put into this TreeMap
|
||||
* @throws NullPointerException if sm is null
|
||||
*/
|
||||
public TreeMap(SortedMap sm)
|
||||
public TreeMap(SortedMap<K, ? extends V> sm)
|
||||
{
|
||||
this(sm.comparator());
|
||||
int pos = sm.size();
|
||||
@@ -313,7 +313,7 @@ public class TreeMap extends AbstractMap
|
||||
*
|
||||
* @return the map's comparator
|
||||
*/
|
||||
public Comparator comparator()
|
||||
public Comparator<? super K> comparator()
|
||||
{
|
||||
return comparator;
|
||||
}
|
||||
@@ -329,7 +329,7 @@ public class TreeMap extends AbstractMap
|
||||
*/
|
||||
public boolean containsKey(Object key)
|
||||
{
|
||||
return getNode(key) != nil;
|
||||
return getNode((K) key) != nil;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -364,19 +364,19 @@ public class TreeMap extends AbstractMap
|
||||
* @see #values()
|
||||
* @see Map.Entry
|
||||
*/
|
||||
public Set entrySet()
|
||||
public Set<Map.Entry<K,V>> entrySet()
|
||||
{
|
||||
if (entries == null)
|
||||
// Create an AbstractSet with custom implementations of those methods
|
||||
// that can be overriden easily and efficiently.
|
||||
entries = new AbstractSet()
|
||||
entries = new AbstractSet<Map.Entry<K,V>>()
|
||||
{
|
||||
public int size()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
public Iterator iterator()
|
||||
public Iterator<Map.Entry<K,V>> iterator()
|
||||
{
|
||||
return new TreeIterator(ENTRIES);
|
||||
}
|
||||
@@ -390,8 +390,8 @@ public class TreeMap extends AbstractMap
|
||||
{
|
||||
if (! (o instanceof Map.Entry))
|
||||
return false;
|
||||
Map.Entry me = (Map.Entry) o;
|
||||
Node n = getNode(me.getKey());
|
||||
Map.Entry<K,V> me = (Map.Entry<K,V>) o;
|
||||
Node<K,V> n = getNode(me.getKey());
|
||||
return n != nil && AbstractSet.equals(me.getValue(), n.value);
|
||||
}
|
||||
|
||||
@@ -399,8 +399,8 @@ public class TreeMap extends AbstractMap
|
||||
{
|
||||
if (! (o instanceof Map.Entry))
|
||||
return false;
|
||||
Map.Entry me = (Map.Entry) o;
|
||||
Node n = getNode(me.getKey());
|
||||
Map.Entry<K,V> me = (Map.Entry<K,V>) o;
|
||||
Node<K,V> n = getNode(me.getKey());
|
||||
if (n != nil && AbstractSet.equals(me.getValue(), n.value))
|
||||
{
|
||||
removeNode(n);
|
||||
@@ -418,7 +418,7 @@ public class TreeMap extends AbstractMap
|
||||
* @return the first key
|
||||
* @throws NoSuchElementException if the map is empty
|
||||
*/
|
||||
public Object firstKey()
|
||||
public K firstKey()
|
||||
{
|
||||
if (root == nil)
|
||||
throw new NoSuchElementException();
|
||||
@@ -439,10 +439,10 @@ public class TreeMap extends AbstractMap
|
||||
* @see #put(Object, Object)
|
||||
* @see #containsKey(Object)
|
||||
*/
|
||||
public Object get(Object key)
|
||||
public V get(Object key)
|
||||
{
|
||||
// Exploit fact that nil.value == null.
|
||||
return getNode(key).value;
|
||||
return getNode((K) key).value;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -460,9 +460,9 @@ public class TreeMap extends AbstractMap
|
||||
* @throws NullPointerException if toKey is null, but the comparator does not
|
||||
* tolerate null elements
|
||||
*/
|
||||
public SortedMap headMap(Object toKey)
|
||||
public SortedMap<K, V> headMap(K toKey)
|
||||
{
|
||||
return new SubMap(nil, toKey);
|
||||
return new SubMap((K)(Object)nil, toKey);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -474,19 +474,19 @@ public class TreeMap extends AbstractMap
|
||||
* @see #values()
|
||||
* @see #entrySet()
|
||||
*/
|
||||
public Set keySet()
|
||||
public Set<K> keySet()
|
||||
{
|
||||
if (keys == null)
|
||||
// Create an AbstractSet with custom implementations of those methods
|
||||
// that can be overriden easily and efficiently.
|
||||
keys = new AbstractSet()
|
||||
keys = new AbstractSet<K>()
|
||||
{
|
||||
public int size()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
public Iterator iterator()
|
||||
public Iterator<K> iterator()
|
||||
{
|
||||
return new TreeIterator(KEYS);
|
||||
}
|
||||
@@ -503,7 +503,7 @@ public class TreeMap extends AbstractMap
|
||||
|
||||
public boolean remove(Object key)
|
||||
{
|
||||
Node n = getNode(key);
|
||||
Node<K,V> n = getNode((K) key);
|
||||
if (n == nil)
|
||||
return false;
|
||||
removeNode(n);
|
||||
@@ -519,7 +519,7 @@ public class TreeMap extends AbstractMap
|
||||
* @return the last key
|
||||
* @throws NoSuchElementException if the map is empty
|
||||
*/
|
||||
public Object lastKey()
|
||||
public K lastKey()
|
||||
{
|
||||
if (root == nil)
|
||||
throw new NoSuchElementException("empty");
|
||||
@@ -542,10 +542,10 @@ public class TreeMap extends AbstractMap
|
||||
* @see #get(Object)
|
||||
* @see Object#equals(Object)
|
||||
*/
|
||||
public Object put(Object key, Object value)
|
||||
public V put(K key, V value)
|
||||
{
|
||||
Node current = root;
|
||||
Node parent = nil;
|
||||
Node<K,V> current = root;
|
||||
Node<K,V> parent = nil;
|
||||
int comparison = 0;
|
||||
|
||||
// Find new node's parent.
|
||||
@@ -595,13 +595,13 @@ public class TreeMap extends AbstractMap
|
||||
* @throws NullPointerException if a key in m is null, and the comparator
|
||||
* does not tolerate nulls
|
||||
*/
|
||||
public void putAll(Map m)
|
||||
public void putAll(Map<? extends K, ? extends V> m)
|
||||
{
|
||||
Iterator itr = m.entrySet().iterator();
|
||||
int pos = m.size();
|
||||
while (--pos >= 0)
|
||||
{
|
||||
Map.Entry e = (Map.Entry) itr.next();
|
||||
Map.Entry<K,V> e = (Map.Entry<K,V>) itr.next();
|
||||
put(e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
@@ -619,13 +619,13 @@ public class TreeMap extends AbstractMap
|
||||
* @throws NullPointerException if key is null, but the comparator does
|
||||
* not tolerate nulls
|
||||
*/
|
||||
public Object remove(Object key)
|
||||
public V remove(Object key)
|
||||
{
|
||||
Node n = getNode(key);
|
||||
Node<K, V> n = getNode((K)key);
|
||||
if (n == nil)
|
||||
return null;
|
||||
// Note: removeNode can alter the contents of n, so save value now.
|
||||
Object result = n.value;
|
||||
V result = n.value;
|
||||
removeNode(n);
|
||||
return result;
|
||||
}
|
||||
@@ -659,7 +659,7 @@ public class TreeMap extends AbstractMap
|
||||
* comparator does not tolerate null elements
|
||||
* @throws IllegalArgumentException if fromKey is greater than toKey
|
||||
*/
|
||||
public SortedMap subMap(Object fromKey, Object toKey)
|
||||
public SortedMap<K, V> subMap(K fromKey, K toKey)
|
||||
{
|
||||
return new SubMap(fromKey, toKey);
|
||||
}
|
||||
@@ -679,9 +679,9 @@ public class TreeMap extends AbstractMap
|
||||
* @throws NullPointerException if fromKey is null, but the comparator
|
||||
* does not tolerate null elements
|
||||
*/
|
||||
public SortedMap tailMap(Object fromKey)
|
||||
public SortedMap<K, V> tailMap(K fromKey)
|
||||
{
|
||||
return new SubMap(fromKey, nil);
|
||||
return new SubMap(fromKey, (K)(Object)nil);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -694,19 +694,19 @@ public class TreeMap extends AbstractMap
|
||||
* @see #keySet()
|
||||
* @see #entrySet()
|
||||
*/
|
||||
public Collection values()
|
||||
public Collection<V> values()
|
||||
{
|
||||
if (values == null)
|
||||
// We don't bother overriding many of the optional methods, as doing so
|
||||
// wouldn't provide any significant performance advantage.
|
||||
values = new AbstractCollection()
|
||||
values = new AbstractCollection<V>()
|
||||
{
|
||||
public int size()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
public Iterator iterator()
|
||||
public Iterator<V> iterator()
|
||||
{
|
||||
return new TreeIterator(VALUES);
|
||||
}
|
||||
@@ -729,7 +729,7 @@ public class TreeMap extends AbstractMap
|
||||
* or are not Comparable with natural ordering
|
||||
* @throws NullPointerException if o1 or o2 is null with natural ordering
|
||||
*/
|
||||
final int compare(Object o1, Object o2)
|
||||
final int compare(K o1, K o2)
|
||||
{
|
||||
return (comparator == null
|
||||
? ((Comparable) o1).compareTo(o2)
|
||||
@@ -742,7 +742,7 @@ public class TreeMap extends AbstractMap
|
||||
* @param node the child of the node just deleted, possibly nil
|
||||
* @param parent the parent of the node just deleted, never nil
|
||||
*/
|
||||
private void deleteFixup(Node node, Node parent)
|
||||
private void deleteFixup(Node<K,V> node, Node<K,V> parent)
|
||||
{
|
||||
// if (parent == nil)
|
||||
// throw new InternalError();
|
||||
@@ -754,7 +754,7 @@ public class TreeMap extends AbstractMap
|
||||
if (node == parent.left)
|
||||
{
|
||||
// Rebalance left side.
|
||||
Node sibling = parent.right;
|
||||
Node<K,V> sibling = parent.right;
|
||||
// if (sibling == nil)
|
||||
// throw new InternalError();
|
||||
if (sibling.color == RED)
|
||||
@@ -798,7 +798,7 @@ public class TreeMap extends AbstractMap
|
||||
else
|
||||
{
|
||||
// Symmetric "mirror" of left-side case.
|
||||
Node sibling = parent.left;
|
||||
Node<K,V> sibling = parent.left;
|
||||
// if (sibling == nil)
|
||||
// throw new InternalError();
|
||||
if (sibling.color == RED)
|
||||
@@ -931,7 +931,7 @@ public class TreeMap extends AbstractMap
|
||||
*
|
||||
* @return the first node
|
||||
*/
|
||||
final Node firstNode()
|
||||
final Node<K, V> firstNode()
|
||||
{
|
||||
// Exploit fact that nil.left == nil.
|
||||
Node node = root;
|
||||
@@ -947,9 +947,9 @@ public class TreeMap extends AbstractMap
|
||||
* @param key the key to search for
|
||||
* @return the node where the key is found, or nil
|
||||
*/
|
||||
final Node getNode(Object key)
|
||||
final Node<K, V> getNode(K key)
|
||||
{
|
||||
Node current = root;
|
||||
Node<K,V> current = root;
|
||||
while (current != nil)
|
||||
{
|
||||
int comparison = compare(key, current.key);
|
||||
@@ -970,13 +970,13 @@ public class TreeMap extends AbstractMap
|
||||
* @param key the upper bound, exclusive
|
||||
* @return the previous node
|
||||
*/
|
||||
final Node highestLessThan(Object key)
|
||||
final Node<K,V> highestLessThan(K key)
|
||||
{
|
||||
if (key == nil)
|
||||
return lastNode();
|
||||
|
||||
Node last = nil;
|
||||
Node current = root;
|
||||
Node<K,V> last = nil;
|
||||
Node<K,V> current = root;
|
||||
int comparison = 0;
|
||||
|
||||
while (current != nil)
|
||||
@@ -998,7 +998,7 @@ public class TreeMap extends AbstractMap
|
||||
*
|
||||
* @param n the newly inserted node
|
||||
*/
|
||||
private void insertFixup(Node n)
|
||||
private void insertFixup(Node<K,V> n)
|
||||
{
|
||||
// Only need to rebalance when parent is a RED node, and while at least
|
||||
// 2 levels deep into the tree (ie: node has a grandparent). Remember
|
||||
@@ -1073,7 +1073,7 @@ public class TreeMap extends AbstractMap
|
||||
*
|
||||
* @return the last node
|
||||
*/
|
||||
private Node lastNode()
|
||||
private Node<K,V> lastNode()
|
||||
{
|
||||
// Exploit fact that nil.right == nil.
|
||||
Node node = root;
|
||||
@@ -1091,13 +1091,13 @@ public class TreeMap extends AbstractMap
|
||||
* @param first true to return the first element instead of nil for nil key
|
||||
* @return the next node
|
||||
*/
|
||||
final Node lowestGreaterThan(Object key, boolean first)
|
||||
final Node<K,V> lowestGreaterThan(K key, boolean first)
|
||||
{
|
||||
if (key == nil)
|
||||
return first ? firstNode() : nil;
|
||||
|
||||
Node last = nil;
|
||||
Node current = root;
|
||||
Node<K,V> last = nil;
|
||||
Node<K,V> current = root;
|
||||
int comparison = 0;
|
||||
|
||||
while (current != nil)
|
||||
@@ -1120,7 +1120,7 @@ public class TreeMap extends AbstractMap
|
||||
* @param node the current node, not nil
|
||||
* @return the prior node in sorted order
|
||||
*/
|
||||
private Node predecessor(Node node)
|
||||
private Node<K,V> predecessor(Node<K,V> node)
|
||||
{
|
||||
if (node.left != nil)
|
||||
{
|
||||
@@ -1169,21 +1169,21 @@ public class TreeMap extends AbstractMap
|
||||
|
||||
/**
|
||||
* Construct a tree from sorted keys in linear time, with values of "".
|
||||
* Package visible for use by TreeSet.
|
||||
* Package visible for use by TreeSet, which uses a value type of String.
|
||||
*
|
||||
* @param keys the iterator over the sorted keys
|
||||
* @param count the number of nodes to insert
|
||||
* @see TreeSet#TreeSet(SortedSet)
|
||||
*/
|
||||
final void putKeysLinear(Iterator keys, int count)
|
||||
final void putKeysLinear(Iterator<K> keys, int count)
|
||||
{
|
||||
fabricateTree(count);
|
||||
Node node = firstNode();
|
||||
Node<K,V> node = firstNode();
|
||||
|
||||
while (--count >= 0)
|
||||
{
|
||||
node.key = keys.next();
|
||||
node.value = "";
|
||||
node.value = (V) "";
|
||||
node = successor(node);
|
||||
}
|
||||
}
|
||||
@@ -1211,10 +1211,10 @@ public class TreeMap extends AbstractMap
|
||||
*
|
||||
* @param node the node to remove
|
||||
*/
|
||||
final void removeNode(Node node)
|
||||
final void removeNode(Node<K,V> node)
|
||||
{
|
||||
Node splice;
|
||||
Node child;
|
||||
Node<K,V> splice;
|
||||
Node<K,V> child;
|
||||
|
||||
modCount++;
|
||||
size--;
|
||||
@@ -1268,7 +1268,7 @@ public class TreeMap extends AbstractMap
|
||||
*
|
||||
* @param node the node to rotate
|
||||
*/
|
||||
private void rotateLeft(Node node)
|
||||
private void rotateLeft(Node<K,V> node)
|
||||
{
|
||||
Node child = node.right;
|
||||
// if (node == nil || child == nil)
|
||||
@@ -1301,7 +1301,7 @@ public class TreeMap extends AbstractMap
|
||||
*
|
||||
* @param node the node to rotate
|
||||
*/
|
||||
private void rotateRight(Node node)
|
||||
private void rotateRight(Node<K,V> node)
|
||||
{
|
||||
Node child = node.left;
|
||||
// if (node == nil || child == nil)
|
||||
@@ -1336,7 +1336,7 @@ public class TreeMap extends AbstractMap
|
||||
* @param node the current node, not nil
|
||||
* @return the next node in sorted order
|
||||
*/
|
||||
final Node successor(Node node)
|
||||
final Node<K,V> successor(Node<K,V> node)
|
||||
{
|
||||
if (node.right != nil)
|
||||
{
|
||||
@@ -1346,7 +1346,7 @@ public class TreeMap extends AbstractMap
|
||||
return node;
|
||||
}
|
||||
|
||||
Node parent = node.parent;
|
||||
Node<K,V> parent = node.parent;
|
||||
// Exploit fact that nil.right == nil and node is non-nil.
|
||||
while (node == parent.right)
|
||||
{
|
||||
@@ -1489,24 +1489,26 @@ public class TreeMap extends AbstractMap
|
||||
*
|
||||
* @author Eric Blake (ebb9@email.byu.edu)
|
||||
*/
|
||||
private final class SubMap extends AbstractMap implements SortedMap
|
||||
private final class SubMap<SK extends K,SV extends V>
|
||||
extends AbstractMap<SK,SV>
|
||||
implements SortedMap<SK,SV>
|
||||
{
|
||||
/**
|
||||
* The lower range of this view, inclusive, or nil for unbounded.
|
||||
* Package visible for use by nested classes.
|
||||
*/
|
||||
final Object minKey;
|
||||
final SK minKey;
|
||||
|
||||
/**
|
||||
* The upper range of this view, exclusive, or nil for unbounded.
|
||||
* Package visible for use by nested classes.
|
||||
*/
|
||||
final Object maxKey;
|
||||
final SK maxKey;
|
||||
|
||||
/**
|
||||
* The cache for {@link #entrySet()}.
|
||||
*/
|
||||
private Set entries;
|
||||
private Set<Map.Entry<SK,SV>> entries;
|
||||
|
||||
/**
|
||||
* Create a SubMap representing the elements between minKey (inclusive)
|
||||
@@ -1517,9 +1519,9 @@ public class TreeMap extends AbstractMap
|
||||
* @param maxKey the upper bound
|
||||
* @throws IllegalArgumentException if minKey > maxKey
|
||||
*/
|
||||
SubMap(Object minKey, Object maxKey)
|
||||
SubMap(SK minKey, SK maxKey)
|
||||
{
|
||||
if (minKey != nil && maxKey != nil && compare(minKey, maxKey) > 0)
|
||||
if (minKey != nil && maxKey != nil && compare((K) minKey, (K) maxKey) > 0)
|
||||
throw new IllegalArgumentException("fromKey > toKey");
|
||||
this.minKey = minKey;
|
||||
this.maxKey = maxKey;
|
||||
@@ -1533,10 +1535,10 @@ public class TreeMap extends AbstractMap
|
||||
* @param key the key to check
|
||||
* @return true if the key is in range
|
||||
*/
|
||||
boolean keyInRange(Object key)
|
||||
boolean keyInRange(SK key)
|
||||
{
|
||||
return ((minKey == nil || compare(key, minKey) >= 0)
|
||||
&& (maxKey == nil || compare(key, maxKey) < 0));
|
||||
return ((minKey == nil || compare((K) key, (K) minKey) >= 0)
|
||||
&& (maxKey == nil || compare((K) key, (K) maxKey) < 0));
|
||||
}
|
||||
|
||||
public void clear()
|
||||
@@ -1551,14 +1553,14 @@ public class TreeMap extends AbstractMap
|
||||
}
|
||||
}
|
||||
|
||||
public Comparator comparator()
|
||||
public Comparator<? super SK> comparator()
|
||||
{
|
||||
return comparator;
|
||||
}
|
||||
|
||||
public boolean containsKey(Object key)
|
||||
{
|
||||
return keyInRange(key) && TreeMap.this.containsKey(key);
|
||||
return keyInRange((SK) key) && TreeMap.this.containsKey(key);
|
||||
}
|
||||
|
||||
public boolean containsValue(Object value)
|
||||
@@ -1574,19 +1576,19 @@ public class TreeMap extends AbstractMap
|
||||
return false;
|
||||
}
|
||||
|
||||
public Set entrySet()
|
||||
public Set<Map.Entry<SK,SV>> entrySet()
|
||||
{
|
||||
if (entries == null)
|
||||
// Create an AbstractSet with custom implementations of those methods
|
||||
// that can be overriden easily and efficiently.
|
||||
entries = new AbstractSet()
|
||||
entries = new AbstractSet<Map.Entry<SK,SV>>()
|
||||
{
|
||||
public int size()
|
||||
{
|
||||
return SubMap.this.size();
|
||||
}
|
||||
|
||||
public Iterator iterator()
|
||||
public Iterator<Map.Entry<SK,SV>> iterator()
|
||||
{
|
||||
Node first = lowestGreaterThan(minKey, true);
|
||||
Node max = lowestGreaterThan(maxKey, false);
|
||||
@@ -1602,11 +1604,11 @@ public class TreeMap extends AbstractMap
|
||||
{
|
||||
if (! (o instanceof Map.Entry))
|
||||
return false;
|
||||
Map.Entry me = (Map.Entry) o;
|
||||
Object key = me.getKey();
|
||||
Map.Entry<SK,SV> me = (Map.Entry<SK,SV>) o;
|
||||
SK key = me.getKey();
|
||||
if (! keyInRange(key))
|
||||
return false;
|
||||
Node n = getNode(key);
|
||||
Node<K,V> n = getNode((K) key);
|
||||
return n != nil && AbstractSet.equals(me.getValue(), n.value);
|
||||
}
|
||||
|
||||
@@ -1614,11 +1616,11 @@ public class TreeMap extends AbstractMap
|
||||
{
|
||||
if (! (o instanceof Map.Entry))
|
||||
return false;
|
||||
Map.Entry me = (Map.Entry) o;
|
||||
Object key = me.getKey();
|
||||
Map.Entry<SK,SV> me = (Map.Entry<SK,SV>) o;
|
||||
SK key = me.getKey();
|
||||
if (! keyInRange(key))
|
||||
return false;
|
||||
Node n = getNode(key);
|
||||
Node<K,V> n = getNode((K) key);
|
||||
if (n != nil && AbstractSet.equals(me.getValue(), n.value))
|
||||
{
|
||||
removeNode(n);
|
||||
@@ -1630,29 +1632,29 @@ public class TreeMap extends AbstractMap
|
||||
return entries;
|
||||
}
|
||||
|
||||
public Object firstKey()
|
||||
public SK firstKey()
|
||||
{
|
||||
Node node = lowestGreaterThan(minKey, true);
|
||||
Node<SK,SV> node = (Node<SK,SV>) lowestGreaterThan(minKey, true);
|
||||
if (node == nil || ! keyInRange(node.key))
|
||||
throw new NoSuchElementException();
|
||||
return node.key;
|
||||
}
|
||||
|
||||
public Object get(Object key)
|
||||
public SV get(Object key)
|
||||
{
|
||||
if (keyInRange(key))
|
||||
return TreeMap.this.get(key);
|
||||
if (keyInRange((SK) key))
|
||||
return (SV) TreeMap.this.get(key);
|
||||
return null;
|
||||
}
|
||||
|
||||
public SortedMap headMap(Object toKey)
|
||||
public SortedMap<SK,SV> headMap(SK toKey)
|
||||
{
|
||||
if (! keyInRange(toKey))
|
||||
throw new IllegalArgumentException("key outside range");
|
||||
return new SubMap(minKey, toKey);
|
||||
}
|
||||
|
||||
public Set keySet()
|
||||
public Set<SK> keySet()
|
||||
{
|
||||
if (this.keys == null)
|
||||
// Create an AbstractSet with custom implementations of those methods
|
||||
@@ -1664,7 +1666,7 @@ public class TreeMap extends AbstractMap
|
||||
return SubMap.this.size();
|
||||
}
|
||||
|
||||
public Iterator iterator()
|
||||
public Iterator<SK> iterator()
|
||||
{
|
||||
Node first = lowestGreaterThan(minKey, true);
|
||||
Node max = lowestGreaterThan(maxKey, false);
|
||||
@@ -1678,16 +1680,16 @@ public class TreeMap extends AbstractMap
|
||||
|
||||
public boolean contains(Object o)
|
||||
{
|
||||
if (! keyInRange(o))
|
||||
if (! keyInRange((SK) o))
|
||||
return false;
|
||||
return getNode(o) != nil;
|
||||
return getNode((K) o) != nil;
|
||||
}
|
||||
|
||||
public boolean remove(Object o)
|
||||
{
|
||||
if (! keyInRange(o))
|
||||
if (! keyInRange((SK) o))
|
||||
return false;
|
||||
Node n = getNode(o);
|
||||
Node n = getNode((K) o);
|
||||
if (n != nil)
|
||||
{
|
||||
removeNode(n);
|
||||
@@ -1699,25 +1701,25 @@ public class TreeMap extends AbstractMap
|
||||
return this.keys;
|
||||
}
|
||||
|
||||
public Object lastKey()
|
||||
public SK lastKey()
|
||||
{
|
||||
Node node = highestLessThan(maxKey);
|
||||
Node<SK,SV> node = (Node<SK,SV>) highestLessThan(maxKey);
|
||||
if (node == nil || ! keyInRange(node.key))
|
||||
throw new NoSuchElementException();
|
||||
return node.key;
|
||||
return (SK) node.key;
|
||||
}
|
||||
|
||||
public Object put(Object key, Object value)
|
||||
public SV put(SK key, SV value)
|
||||
{
|
||||
if (! keyInRange(key))
|
||||
throw new IllegalArgumentException("Key outside range");
|
||||
return TreeMap.this.put(key, value);
|
||||
return (SV) TreeMap.this.put(key, value);
|
||||
}
|
||||
|
||||
public Object remove(Object key)
|
||||
public SV remove(Object key)
|
||||
{
|
||||
if (keyInRange(key))
|
||||
return TreeMap.this.remove(key);
|
||||
if (keyInRange((SK)key))
|
||||
return (SV) TreeMap.this.remove(key);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1734,21 +1736,21 @@ public class TreeMap extends AbstractMap
|
||||
return count;
|
||||
}
|
||||
|
||||
public SortedMap subMap(Object fromKey, Object toKey)
|
||||
public SortedMap<SK, SV> subMap(SK fromKey, SK toKey)
|
||||
{
|
||||
if (! keyInRange(fromKey) || ! keyInRange(toKey))
|
||||
throw new IllegalArgumentException("key outside range");
|
||||
return new SubMap(fromKey, toKey);
|
||||
}
|
||||
|
||||
public SortedMap tailMap(Object fromKey)
|
||||
public SortedMap<SK, SV> tailMap(SK fromKey)
|
||||
{
|
||||
if (! keyInRange(fromKey))
|
||||
throw new IllegalArgumentException("key outside range");
|
||||
return new SubMap(fromKey, maxKey);
|
||||
}
|
||||
|
||||
public Collection values()
|
||||
public Collection<SV> values()
|
||||
{
|
||||
if (this.values == null)
|
||||
// Create an AbstractCollection with custom implementations of those
|
||||
@@ -1760,7 +1762,7 @@ public class TreeMap extends AbstractMap
|
||||
return SubMap.this.size();
|
||||
}
|
||||
|
||||
public Iterator iterator()
|
||||
public Iterator<SV> iterator()
|
||||
{
|
||||
Node first = lowestGreaterThan(minKey, true);
|
||||
Node max = lowestGreaterThan(maxKey, false);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* TreeSet.java -- a class providing a TreeMap-backed SortedSet
|
||||
Copyright (C) 1999, 2000, 2001, 2004, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2000, 2001, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -68,6 +68,8 @@ import java.io.Serializable;
|
||||
* @author Jon Zeppieri
|
||||
* @author Bryce McKinlay
|
||||
* @author Eric Blake (ebb9@email.byu.edu)
|
||||
* @author Tom Tromey (tromey@redhat.com)
|
||||
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
|
||||
* @see Collection
|
||||
* @see Set
|
||||
* @see HashSet
|
||||
@@ -79,8 +81,8 @@ import java.io.Serializable;
|
||||
* @since 1.2
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public class TreeSet extends AbstractSet
|
||||
implements SortedSet, Cloneable, Serializable
|
||||
public class TreeSet<T> extends AbstractSet<T>
|
||||
implements SortedSet<T>, Cloneable, Serializable
|
||||
{
|
||||
/**
|
||||
* Compatible with JDK 1.2.
|
||||
@@ -92,7 +94,7 @@ public class TreeSet extends AbstractSet
|
||||
*/
|
||||
// Not final because of readObject. This will always be one of TreeMap or
|
||||
// TreeMap.SubMap, which both extend AbstractMap.
|
||||
private transient SortedMap map;
|
||||
private transient SortedMap<T, String> map;
|
||||
|
||||
/**
|
||||
* Construct a new TreeSet whose backing TreeMap using the "natural"
|
||||
@@ -103,7 +105,7 @@ public class TreeSet extends AbstractSet
|
||||
*/
|
||||
public TreeSet()
|
||||
{
|
||||
map = new TreeMap();
|
||||
map = new TreeMap<T, String>();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,9 +115,9 @@ public class TreeSet extends AbstractSet
|
||||
*
|
||||
* @param comparator the Comparator this Set will use
|
||||
*/
|
||||
public TreeSet(Comparator comparator)
|
||||
public TreeSet(Comparator<? super T> comparator)
|
||||
{
|
||||
map = new TreeMap(comparator);
|
||||
map = new TreeMap<T, String>(comparator);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,9 +132,9 @@ public class TreeSet extends AbstractSet
|
||||
* @throws NullPointerException if the collection is null
|
||||
* @see Comparable
|
||||
*/
|
||||
public TreeSet(Collection collection)
|
||||
public TreeSet(Collection<? extends T> collection)
|
||||
{
|
||||
map = new TreeMap();
|
||||
map = new TreeMap<T, String>();
|
||||
addAll(collection);
|
||||
}
|
||||
|
||||
@@ -145,11 +147,14 @@ public class TreeSet extends AbstractSet
|
||||
* and will initialize itself with all its elements
|
||||
* @throws NullPointerException if sortedSet is null
|
||||
*/
|
||||
public TreeSet(SortedSet sortedSet)
|
||||
public TreeSet(SortedSet<T> sortedSet)
|
||||
{
|
||||
map = new TreeMap(sortedSet.comparator());
|
||||
Iterator itr = sortedSet.iterator();
|
||||
((TreeMap) map).putKeysLinear(itr, sortedSet.size());
|
||||
Iterator<T> itr;
|
||||
|
||||
map = new TreeMap<T, String>
|
||||
((Comparator<? super T>)sortedSet.comparator());
|
||||
itr = ((SortedSet<T>) sortedSet).iterator();
|
||||
((TreeMap<T, String>) map).putKeysLinear(itr, sortedSet.size());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -158,7 +163,7 @@ public class TreeSet extends AbstractSet
|
||||
*
|
||||
* @param backingMap the submap
|
||||
*/
|
||||
private TreeSet(SortedMap backingMap)
|
||||
private TreeSet(SortedMap<T,String> backingMap)
|
||||
{
|
||||
map = backingMap;
|
||||
}
|
||||
@@ -171,7 +176,7 @@ public class TreeSet extends AbstractSet
|
||||
* @throws ClassCastException if the element cannot be compared with objects
|
||||
* already in the set
|
||||
*/
|
||||
public boolean add(Object obj)
|
||||
public boolean add(T obj)
|
||||
{
|
||||
return map.put(obj, "") == null;
|
||||
}
|
||||
@@ -185,11 +190,11 @@ public class TreeSet extends AbstractSet
|
||||
* @throws ClassCastException if an element in c cannot be compared with
|
||||
* objects already in the set
|
||||
*/
|
||||
public boolean addAll(Collection c)
|
||||
public boolean addAll(Collection<? extends T> c)
|
||||
{
|
||||
boolean result = false;
|
||||
int pos = c.size();
|
||||
Iterator itr = c.iterator();
|
||||
Iterator<? extends T> itr = c.iterator();
|
||||
while (--pos >= 0)
|
||||
result |= (map.put(itr.next(), "") == null);
|
||||
return result;
|
||||
@@ -210,12 +215,12 @@ public class TreeSet extends AbstractSet
|
||||
*/
|
||||
public Object clone()
|
||||
{
|
||||
TreeSet copy = null;
|
||||
TreeSet<T> copy = null;
|
||||
try
|
||||
{
|
||||
copy = (TreeSet) super.clone();
|
||||
copy = (TreeSet<T>) super.clone();
|
||||
// Map may be either TreeMap or TreeMap.SubMap, hence the ugly casts.
|
||||
copy.map = (SortedMap) ((AbstractMap) map).clone();
|
||||
copy.map = (SortedMap<T, String>) ((AbstractMap<T, String>) map).clone();
|
||||
}
|
||||
catch (CloneNotSupportedException x)
|
||||
{
|
||||
@@ -229,7 +234,7 @@ public class TreeSet extends AbstractSet
|
||||
*
|
||||
* @return the comparator, or null if the set uses natural ordering
|
||||
*/
|
||||
public Comparator comparator()
|
||||
public Comparator<? super T> comparator()
|
||||
{
|
||||
return map.comparator();
|
||||
}
|
||||
@@ -253,7 +258,7 @@ public class TreeSet extends AbstractSet
|
||||
* @return the first element
|
||||
* @throws NoSuchElementException if the set is empty
|
||||
*/
|
||||
public Object first()
|
||||
public T first()
|
||||
{
|
||||
return map.firstKey();
|
||||
}
|
||||
@@ -273,9 +278,9 @@ public class TreeSet extends AbstractSet
|
||||
* @throws NullPointerException if to is null, but the comparator does not
|
||||
* tolerate null elements
|
||||
*/
|
||||
public SortedSet headSet(Object to)
|
||||
public SortedSet<T> headSet(T to)
|
||||
{
|
||||
return new TreeSet(map.headMap(to));
|
||||
return new TreeSet<T>(map.headMap(to));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -294,7 +299,7 @@ public class TreeSet extends AbstractSet
|
||||
*
|
||||
* @return an iterator
|
||||
*/
|
||||
public Iterator iterator()
|
||||
public Iterator<T> iterator()
|
||||
{
|
||||
return map.keySet().iterator();
|
||||
}
|
||||
@@ -305,7 +310,7 @@ public class TreeSet extends AbstractSet
|
||||
* @return the last element
|
||||
* @throws NoSuchElementException if the set is empty
|
||||
*/
|
||||
public Object last()
|
||||
public T last()
|
||||
{
|
||||
return map.lastKey();
|
||||
}
|
||||
@@ -351,9 +356,9 @@ public class TreeSet extends AbstractSet
|
||||
* does not tolerate null elements
|
||||
* @throws IllegalArgumentException if from is greater than to
|
||||
*/
|
||||
public SortedSet subSet(Object from, Object to)
|
||||
public SortedSet<T> subSet(T from, T to)
|
||||
{
|
||||
return new TreeSet(map.subMap(from, to));
|
||||
return new TreeSet<T>(map.subMap(from, to));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -371,9 +376,9 @@ public class TreeSet extends AbstractSet
|
||||
* @throws NullPointerException if from is null, but the comparator
|
||||
* does not tolerate null elements
|
||||
*/
|
||||
public SortedSet tailSet(Object from)
|
||||
public SortedSet<T> tailSet(T from)
|
||||
{
|
||||
return new TreeSet(map.tailMap(from));
|
||||
return new TreeSet<T>(map.tailMap(from));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -387,7 +392,7 @@ public class TreeSet extends AbstractSet
|
||||
private void writeObject(ObjectOutputStream s) throws IOException
|
||||
{
|
||||
s.defaultWriteObject();
|
||||
Iterator itr = map.keySet().iterator();
|
||||
Iterator<T> itr = map.keySet().iterator();
|
||||
int pos = map.size();
|
||||
s.writeObject(map.comparator());
|
||||
s.writeInt(pos);
|
||||
@@ -408,9 +413,9 @@ public class TreeSet extends AbstractSet
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
s.defaultReadObject();
|
||||
Comparator comparator = (Comparator) s.readObject();
|
||||
Comparator<? super T> comparator = (Comparator<? super T>) s.readObject();
|
||||
int size = s.readInt();
|
||||
map = new TreeMap(comparator);
|
||||
((TreeMap) map).putFromObjStream(s, size, false);
|
||||
map = new TreeMap<T, String>(comparator);
|
||||
((TreeMap<T, String>) map).putFromObjStream(s, size, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ import java.security.NoSuchAlgorithmException;
|
||||
*/
|
||||
public final class UUID
|
||||
extends Object
|
||||
implements Serializable, Comparable // genericizeme!
|
||||
implements Serializable, Comparable<UUID>
|
||||
{
|
||||
private static final long serialVersionUID = -4856846361193249489L;
|
||||
|
||||
@@ -121,17 +121,6 @@ public final class UUID
|
||||
return (int)((leastSigBits & 0x3FFF000000000000L) >> 48);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare this UUID to another.
|
||||
* The comparison is performed as between two 128-bit integers.
|
||||
*
|
||||
* @return -1 if this < val, 0 if they are equal, 1 if this > val.
|
||||
*/
|
||||
public int compareTo(Object val)
|
||||
{
|
||||
return compareTo((UUID)val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare this UUID to another.
|
||||
* The comparison is performed as between two 128-bit integers.
|
||||
|
||||
@@ -82,8 +82,8 @@ import java.lang.reflect.Array;
|
||||
* @since 1.0
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public class Vector extends AbstractList
|
||||
implements List, RandomAccess, Cloneable, Serializable
|
||||
public class Vector<T> extends AbstractList<T>
|
||||
implements List<T>, RandomAccess, Cloneable, Serializable
|
||||
{
|
||||
/**
|
||||
* Compatible with JDK 1.0+.
|
||||
@@ -95,7 +95,7 @@ public class Vector extends AbstractList
|
||||
* in positions 0 through elementCount - 1, and all remaining slots are null.
|
||||
* @serial the elements
|
||||
*/
|
||||
protected Object[] elementData;
|
||||
protected T[] elementData;
|
||||
|
||||
/**
|
||||
* The number of elements currently in the vector, also returned by
|
||||
@@ -130,10 +130,10 @@ public class Vector extends AbstractList
|
||||
* @throws NullPointerException if c is null
|
||||
* @since 1.2
|
||||
*/
|
||||
public Vector(Collection c)
|
||||
public Vector(Collection<? extends T> c)
|
||||
{
|
||||
elementCount = c.size();
|
||||
elementData = c.toArray(new Object[elementCount]);
|
||||
elementData = c.toArray((T[]) new Object[elementCount]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -149,7 +149,7 @@ public class Vector extends AbstractList
|
||||
{
|
||||
if (initialCapacity < 0)
|
||||
throw new IllegalArgumentException();
|
||||
elementData = new Object[initialCapacity];
|
||||
elementData = (T[]) new Object[initialCapacity];
|
||||
this.capacityIncrement = capacityIncrement;
|
||||
}
|
||||
|
||||
@@ -192,7 +192,7 @@ public class Vector extends AbstractList
|
||||
// vector since that is a much less likely case; it's more efficient to
|
||||
// not do the check and lose a bit of performance in that infrequent case
|
||||
|
||||
Object[] newArray = new Object[elementCount];
|
||||
T[] newArray = (T[]) new Object[elementCount];
|
||||
System.arraycopy(elementData, 0, newArray, 0, elementCount);
|
||||
elementData = newArray;
|
||||
}
|
||||
@@ -218,7 +218,7 @@ public class Vector extends AbstractList
|
||||
else
|
||||
newCapacity = elementData.length + capacityIncrement;
|
||||
|
||||
Object[] newArray = new Object[Math.max(newCapacity, minCapacity)];
|
||||
T[] newArray = (T[]) new Object[Math.max(newCapacity, minCapacity)];
|
||||
|
||||
System.arraycopy(elementData, 0, newArray, 0, elementCount);
|
||||
elementData = newArray;
|
||||
@@ -284,9 +284,9 @@ public class Vector extends AbstractList
|
||||
* @see #iterator()
|
||||
*/
|
||||
// No need to synchronize as the Enumeration is not thread-safe!
|
||||
public Enumeration elements()
|
||||
public Enumeration<T> elements()
|
||||
{
|
||||
return new Enumeration()
|
||||
return new Enumeration<T>()
|
||||
{
|
||||
private int i = 0;
|
||||
|
||||
@@ -295,7 +295,7 @@ public class Vector extends AbstractList
|
||||
return i < elementCount;
|
||||
}
|
||||
|
||||
public Object nextElement()
|
||||
public T nextElement()
|
||||
{
|
||||
if (i >= elementCount)
|
||||
throw new NoSuchElementException();
|
||||
@@ -385,7 +385,7 @@ public class Vector extends AbstractList
|
||||
* @throws ArrayIndexOutOfBoundsException index < 0 || index >= size()
|
||||
* @see #get(int)
|
||||
*/
|
||||
public synchronized Object elementAt(int index)
|
||||
public synchronized T elementAt(int index)
|
||||
{
|
||||
checkBoundExclusive(index);
|
||||
return elementData[index];
|
||||
@@ -397,7 +397,7 @@ public class Vector extends AbstractList
|
||||
* @return the first Object in the Vector
|
||||
* @throws NoSuchElementException the Vector is empty
|
||||
*/
|
||||
public synchronized Object firstElement()
|
||||
public synchronized T firstElement()
|
||||
{
|
||||
if (elementCount == 0)
|
||||
throw new NoSuchElementException();
|
||||
@@ -411,7 +411,7 @@ public class Vector extends AbstractList
|
||||
* @return the last Object in the Vector
|
||||
* @throws NoSuchElementException the Vector is empty
|
||||
*/
|
||||
public synchronized Object lastElement()
|
||||
public synchronized T lastElement()
|
||||
{
|
||||
if (elementCount == 0)
|
||||
throw new NoSuchElementException();
|
||||
@@ -427,7 +427,7 @@ public class Vector extends AbstractList
|
||||
* @throws ArrayIndexOutOfBoundsException the index is out of range
|
||||
* @see #set(int, Object)
|
||||
*/
|
||||
public void setElementAt(Object obj, int index)
|
||||
public void setElementAt(T obj, int index)
|
||||
{
|
||||
set(index, obj);
|
||||
}
|
||||
@@ -454,7 +454,7 @@ public class Vector extends AbstractList
|
||||
* @throws ArrayIndexOutOfBoundsException index < 0 || index > size()
|
||||
* @see #add(int, Object)
|
||||
*/
|
||||
public synchronized void insertElementAt(Object obj, int index)
|
||||
public synchronized void insertElementAt(T obj, int index)
|
||||
{
|
||||
checkBoundInclusive(index);
|
||||
if (elementCount == elementData.length)
|
||||
@@ -472,7 +472,7 @@ public class Vector extends AbstractList
|
||||
*
|
||||
* @param obj the object to add to the Vector
|
||||
*/
|
||||
public synchronized void addElement(Object obj)
|
||||
public synchronized void addElement(T obj)
|
||||
{
|
||||
if (elementCount == elementData.length)
|
||||
ensureCapacity(elementCount + 1);
|
||||
@@ -570,11 +570,11 @@ public class Vector extends AbstractList
|
||||
* @throws NullPointerException if <code>a</code> is null
|
||||
* @since 1.2
|
||||
*/
|
||||
public synchronized Object[] toArray(Object[] a)
|
||||
public synchronized <S> S[] toArray(S[] a)
|
||||
{
|
||||
if (a.length < elementCount)
|
||||
a = (Object[]) Array.newInstance(a.getClass().getComponentType(),
|
||||
elementCount);
|
||||
a = (S[]) Array.newInstance(a.getClass().getComponentType(),
|
||||
elementCount);
|
||||
else if (a.length > elementCount)
|
||||
a[elementCount] = null;
|
||||
System.arraycopy(elementData, 0, a, 0, elementCount);
|
||||
@@ -589,7 +589,7 @@ public class Vector extends AbstractList
|
||||
* @throws ArrayIndexOutOfBoundsException index < 0 || index >= size()
|
||||
* @since 1.2
|
||||
*/
|
||||
public Object get(int index)
|
||||
public T get(int index)
|
||||
{
|
||||
return elementAt(index);
|
||||
}
|
||||
@@ -604,10 +604,10 @@ public class Vector extends AbstractList
|
||||
* @throws ArrayIndexOutOfBoundsException index < 0 || index >= size()
|
||||
* @since 1.2
|
||||
*/
|
||||
public synchronized Object set(int index, Object element)
|
||||
public synchronized T set(int index, T element)
|
||||
{
|
||||
checkBoundExclusive(index);
|
||||
Object temp = elementData[index];
|
||||
T temp = elementData[index];
|
||||
elementData[index] = element;
|
||||
return temp;
|
||||
}
|
||||
@@ -619,7 +619,7 @@ public class Vector extends AbstractList
|
||||
* @return true, as specified by List
|
||||
* @since 1.2
|
||||
*/
|
||||
public boolean add(Object o)
|
||||
public boolean add(T o)
|
||||
{
|
||||
addElement(o);
|
||||
return true;
|
||||
@@ -647,7 +647,7 @@ public class Vector extends AbstractList
|
||||
* @throws ArrayIndexOutOfBoundsException index < 0 || index > size()
|
||||
* @since 1.2
|
||||
*/
|
||||
public void add(int index, Object element)
|
||||
public void add(int index, T element)
|
||||
{
|
||||
insertElementAt(element, index);
|
||||
}
|
||||
@@ -660,10 +660,10 @@ public class Vector extends AbstractList
|
||||
* @throws ArrayIndexOutOfBoundsException index < 0 || index >= size()
|
||||
* @since 1.2
|
||||
*/
|
||||
public synchronized Object remove(int index)
|
||||
public synchronized T remove(int index)
|
||||
{
|
||||
checkBoundExclusive(index);
|
||||
Object temp = elementData[index];
|
||||
T temp = elementData[index];
|
||||
modCount++;
|
||||
elementCount--;
|
||||
if (index < elementCount)
|
||||
@@ -689,7 +689,7 @@ public class Vector extends AbstractList
|
||||
* @throws NullPointerException if c is null
|
||||
* @since 1.2
|
||||
*/
|
||||
public synchronized boolean containsAll(Collection c)
|
||||
public synchronized boolean containsAll(Collection<?> c)
|
||||
{
|
||||
// Here just for the sychronization.
|
||||
return super.containsAll(c);
|
||||
@@ -705,7 +705,7 @@ public class Vector extends AbstractList
|
||||
* @throws NullPointerException if c is null
|
||||
* @since 1.2
|
||||
*/
|
||||
public synchronized boolean addAll(Collection c)
|
||||
public synchronized boolean addAll(Collection<? extends T> c)
|
||||
{
|
||||
return addAll(elementCount, c);
|
||||
}
|
||||
@@ -718,10 +718,12 @@ public class Vector extends AbstractList
|
||||
* @throws NullPointerException if c is null
|
||||
* @since 1.2
|
||||
*/
|
||||
public synchronized boolean removeAll(Collection c)
|
||||
public synchronized boolean removeAll(Collection<?> c)
|
||||
{
|
||||
if (c == null)
|
||||
throw new NullPointerException();
|
||||
// The NullPointerException is thrown implicitly when the Vector
|
||||
// is not empty and c is null. The RI allows null arguments when
|
||||
// the vector is empty. See Mauve test:
|
||||
// gnu/testlet/java/util/Vector/removeAll.java
|
||||
|
||||
int i;
|
||||
int j;
|
||||
@@ -747,10 +749,12 @@ public class Vector extends AbstractList
|
||||
* @throws NullPointerException if c is null
|
||||
* @since 1.2
|
||||
*/
|
||||
public synchronized boolean retainAll(Collection c)
|
||||
public synchronized boolean retainAll(Collection<?> c)
|
||||
{
|
||||
if (c == null)
|
||||
throw new NullPointerException();
|
||||
// The NullPointerException is thrown implicitly when the Vector
|
||||
// is not empty and c is null. The RI allows null arguments when
|
||||
// the vector is empty. See Mauve test:
|
||||
// gnu/testlet/java/util/Vector/retainAll.java
|
||||
|
||||
int i;
|
||||
int j;
|
||||
@@ -779,10 +783,10 @@ public class Vector extends AbstractList
|
||||
* @throws ArrayIndexOutOfBoundsException index < 0 || index > size()
|
||||
* @since 1.2
|
||||
*/
|
||||
public synchronized boolean addAll(int index, Collection c)
|
||||
public synchronized boolean addAll(int index, Collection<? extends T> c)
|
||||
{
|
||||
checkBoundInclusive(index);
|
||||
Iterator itr = c.iterator();
|
||||
Iterator<? extends T> itr = c.iterator();
|
||||
int csize = c.size();
|
||||
|
||||
modCount++;
|
||||
@@ -853,12 +857,12 @@ public class Vector extends AbstractList
|
||||
* @see ConcurrentModificationException
|
||||
* @since 1.2
|
||||
*/
|
||||
public synchronized List subList(int fromIndex, int toIndex)
|
||||
public synchronized List<T> subList(int fromIndex, int toIndex)
|
||||
{
|
||||
List sub = super.subList(fromIndex, toIndex);
|
||||
List<T> sub = super.subList(fromIndex, toIndex);
|
||||
// We must specify the correct object to synchronize upon, hence the
|
||||
// use of a non-public API
|
||||
return new Collections.SynchronizedList(this, sub);
|
||||
return new Collections.SynchronizedList<T>(this, sub);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* WeakHashMap -- a hashtable that keeps only weak references
|
||||
to its keys, allowing the virtual machine to reclaim them
|
||||
Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -77,14 +77,16 @@ import java.lang.ref.WeakReference;
|
||||
*
|
||||
* @author Jochen Hoenicke
|
||||
* @author Eric Blake (ebb9@email.byu.edu)
|
||||
* @author Tom Tromey (tromey@redhat.com)
|
||||
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
|
||||
*
|
||||
* @see HashMap
|
||||
* @see WeakReference
|
||||
* @see LinkedHashMap
|
||||
* @since 1.2
|
||||
* @status updated to 1.4
|
||||
* @status updated to 1.4 (partial 1.5)
|
||||
*/
|
||||
public class WeakHashMap extends AbstractMap implements Map
|
||||
public class WeakHashMap<K,V> extends AbstractMap<K,V>
|
||||
{
|
||||
// WARNING: WeakHashMap is a CORE class in the bootstrap cycle. See the
|
||||
// comments in vm/reference/java/lang/Runtime for implications of this fact.
|
||||
@@ -349,19 +351,19 @@ public class WeakHashMap extends AbstractMap implements Map
|
||||
*
|
||||
* @author Jochen Hoenicke
|
||||
*/
|
||||
private static class WeakBucket extends WeakReference
|
||||
private static class WeakBucket<K, V> extends WeakReference<K>
|
||||
{
|
||||
/**
|
||||
* The value of this entry. The key is stored in the weak
|
||||
* reference that we extend.
|
||||
*/
|
||||
Object value;
|
||||
V value;
|
||||
|
||||
/**
|
||||
* The next bucket describing another entry that uses the same
|
||||
* slot.
|
||||
*/
|
||||
WeakBucket next;
|
||||
WeakBucket<K, V> next;
|
||||
|
||||
/**
|
||||
* The slot of this entry. This should be
|
||||
@@ -384,7 +386,7 @@ public class WeakHashMap extends AbstractMap implements Map
|
||||
* @param slot the slot. This must match the slot where this bucket
|
||||
* will be enqueued.
|
||||
*/
|
||||
public WeakBucket(Object key, ReferenceQueue queue, Object value,
|
||||
public WeakBucket(K key, ReferenceQueue queue, V value,
|
||||
int slot)
|
||||
{
|
||||
super(key, queue);
|
||||
@@ -397,18 +399,18 @@ public class WeakHashMap extends AbstractMap implements Map
|
||||
* current bucket. It also keeps a strong reference to the
|
||||
* key; bad things may happen otherwise.
|
||||
*/
|
||||
class WeakEntry implements Map.Entry
|
||||
class WeakEntry implements Map.Entry<K, V>
|
||||
{
|
||||
/**
|
||||
* The strong ref to the key.
|
||||
*/
|
||||
Object key;
|
||||
K key;
|
||||
|
||||
/**
|
||||
* Creates a new entry for the key.
|
||||
* @param key the key
|
||||
*/
|
||||
public WeakEntry(Object key)
|
||||
public WeakEntry(K key)
|
||||
{
|
||||
this.key = key;
|
||||
}
|
||||
@@ -426,7 +428,7 @@ public class WeakHashMap extends AbstractMap implements Map
|
||||
* Returns the key.
|
||||
* @return the key
|
||||
*/
|
||||
public Object getKey()
|
||||
public K getKey()
|
||||
{
|
||||
return key == NULL_KEY ? null : key;
|
||||
}
|
||||
@@ -435,7 +437,7 @@ public class WeakHashMap extends AbstractMap implements Map
|
||||
* Returns the value.
|
||||
* @return the value
|
||||
*/
|
||||
public Object getValue()
|
||||
public V getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
@@ -446,9 +448,9 @@ public class WeakHashMap extends AbstractMap implements Map
|
||||
* @param newVal the new value
|
||||
* @return the old value
|
||||
*/
|
||||
public Object setValue(Object newVal)
|
||||
public V setValue(V newVal)
|
||||
{
|
||||
Object oldVal = value;
|
||||
V oldVal = value;
|
||||
value = newVal;
|
||||
return oldVal;
|
||||
}
|
||||
@@ -491,7 +493,7 @@ public class WeakHashMap extends AbstractMap implements Map
|
||||
*/
|
||||
WeakEntry getEntry()
|
||||
{
|
||||
final Object key = this.get();
|
||||
final K key = this.get();
|
||||
if (key == null)
|
||||
return null;
|
||||
return new WeakEntry(key);
|
||||
@@ -559,7 +561,7 @@ public class WeakHashMap extends AbstractMap implements Map
|
||||
* @throws NullPointerException if m is null
|
||||
* @since 1.3
|
||||
*/
|
||||
public WeakHashMap(Map m)
|
||||
public WeakHashMap(Map<? extends K, ? extends V> m)
|
||||
{
|
||||
this(m.size(), DEFAULT_LOAD_FACTOR);
|
||||
putAll(m);
|
||||
@@ -754,10 +756,10 @@ public class WeakHashMap extends AbstractMap implements Map
|
||||
* the key wasn't in this map, or if the mapped value was
|
||||
* explicitly set to null.
|
||||
*/
|
||||
public Object get(Object key)
|
||||
public V get(Object key)
|
||||
{
|
||||
cleanQueue();
|
||||
WeakBucket.WeakEntry entry = internalGet(key);
|
||||
WeakBucket<K, V>.WeakEntry entry = internalGet(key);
|
||||
return entry == null ? null : entry.getValue();
|
||||
}
|
||||
|
||||
@@ -769,10 +771,10 @@ public class WeakHashMap extends AbstractMap implements Map
|
||||
* null if the key wasn't in this map, or if the mapped value
|
||||
* was explicitly set to null.
|
||||
*/
|
||||
public Object put(Object key, Object value)
|
||||
public V put(K key, V value)
|
||||
{
|
||||
cleanQueue();
|
||||
WeakBucket.WeakEntry entry = internalGet(key);
|
||||
WeakBucket<K, V>.WeakEntry entry = internalGet(key);
|
||||
if (entry != null)
|
||||
return entry.setValue(value);
|
||||
|
||||
@@ -791,10 +793,10 @@ public class WeakHashMap extends AbstractMap implements Map
|
||||
* null if the key wasn't in this map, or if the mapped value was
|
||||
* explicitly set to null.
|
||||
*/
|
||||
public Object remove(Object key)
|
||||
public V remove(Object key)
|
||||
{
|
||||
cleanQueue();
|
||||
WeakBucket.WeakEntry entry = internalGet(key);
|
||||
WeakBucket<K, V>.WeakEntry entry = internalGet(key);
|
||||
if (entry == null)
|
||||
return null;
|
||||
|
||||
@@ -811,7 +813,7 @@ public class WeakHashMap extends AbstractMap implements Map
|
||||
* this weak hash map.
|
||||
* @return a set representation of the entries.
|
||||
*/
|
||||
public Set entrySet()
|
||||
public Set<Map.Entry<K,V>> entrySet()
|
||||
{
|
||||
cleanQueue();
|
||||
return theEntrySet;
|
||||
@@ -846,7 +848,7 @@ public class WeakHashMap extends AbstractMap implements Map
|
||||
* this weak hash map.
|
||||
* @return a set representation of the keys.
|
||||
*/
|
||||
public Set keySet()
|
||||
public Set<K> keySet()
|
||||
{
|
||||
cleanQueue();
|
||||
return super.keySet();
|
||||
@@ -857,7 +859,7 @@ public class WeakHashMap extends AbstractMap implements Map
|
||||
* key already exists in this map, its value is replaced.
|
||||
* @param m the map to copy in
|
||||
*/
|
||||
public void putAll(Map m)
|
||||
public void putAll(Map<? extends K, ? extends V> m)
|
||||
{
|
||||
super.putAll(m);
|
||||
}
|
||||
@@ -870,7 +872,7 @@ public class WeakHashMap extends AbstractMap implements Map
|
||||
* this weak hash map.
|
||||
* @return a collection representation of the values.
|
||||
*/
|
||||
public Collection values()
|
||||
public Collection<V> values()
|
||||
{
|
||||
cleanQueue();
|
||||
return super.values();
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
# This property file contains dependencies of classes, methods, and
|
||||
# field on other methods or classes.
|
||||
#
|
||||
# Syntax:
|
||||
#
|
||||
# <used>: <needed 1> [... <needed N>]
|
||||
#
|
||||
# means that when <used> is included, <needed 1> (... <needed N>) must
|
||||
# be included as well.
|
||||
#
|
||||
# <needed X> and <used> are of the form
|
||||
#
|
||||
# <class.methodOrField(signature)>
|
||||
#
|
||||
# or just
|
||||
#
|
||||
# <class>
|
||||
#
|
||||
# Within dependencies, variables can be used. A variable is defined as
|
||||
# follows:
|
||||
#
|
||||
# {variable}: value1 value2 ... value<n>
|
||||
#
|
||||
# variables can be used on the right side of dependencies as follows:
|
||||
#
|
||||
# <used>: com.bla.blu.{variable}.Class.m()V
|
||||
#
|
||||
# The use of the variable will expand to <n> dependencies of the form
|
||||
#
|
||||
# <used>: com.bla.blu.value1.Class.m()V
|
||||
# <used>: com.bla.blu.value2.Class.m()V
|
||||
# ...
|
||||
# <used>: com.bla.blu.value<n>.Class.m()V
|
||||
#
|
||||
# Variables can be redefined when building a system to select the
|
||||
# required support for features like encodings, protocols, etc.
|
||||
#
|
||||
# Hints:
|
||||
#
|
||||
# - For methods and fields, the signature is mandatory. For
|
||||
# specification, please see the Java Virtual Machine Specification by
|
||||
# SUN. Unlike in the spec, field signatures (types) are in brackets.
|
||||
#
|
||||
# - Package names must be separated by '/' (and not '.'). E.g.,
|
||||
# java/lang/Class (this is necessary, because the '.' is used to
|
||||
# separate method or field names from classes)
|
||||
#
|
||||
# - In case <needed> refers to a class, only the class itself will be
|
||||
# included in the resulting binary, NOT necessarily all its methods
|
||||
# and fields. If you want to refer to all methods and fields, you can
|
||||
# write class.* as an abbreviation.
|
||||
#
|
||||
# - Abbreviations for packages are also possible: my/package/* means all
|
||||
# methods and fields of all classes in my/package.
|
||||
#
|
||||
# - A line with a trailing '\' continues in the next line.
|
||||
|
||||
|
||||
# All calendars supported are loaded via java/util/Calendar.getBundle or
|
||||
# java/util/GregorianCalendar.getBundle from class
|
||||
# gnu/java/locale/Calendar_{locale_id}
|
||||
#
|
||||
# This introduces a dependency for the localized calendars. To allow an easy
|
||||
# selection and addition of locales, the library variable {calendar_locales}
|
||||
# can be set to the set of supported calendar locales.
|
||||
#
|
||||
|
||||
{calendar_locales}: de en nl
|
||||
|
||||
java/util/Calendar.getBundle(Ljava/util/Locale;)Ljava/util/ResourceBundle;: \
|
||||
gnu/java/locale/Calendar.* \
|
||||
gnu/java/locale/Calendar_{calendar_locales}.*
|
||||
|
||||
java/util/GregorianCalendar.getBundle(Ljava/util/Locale;)Ljava/util/ResourceBundle;: \
|
||||
gnu/java/locale/Calendar.* \
|
||||
gnu/java/locale/Calendar_{calendar_locales}.*
|
||||
|
||||
# end of file
|
||||
@@ -0,0 +1,490 @@
|
||||
/* CopyOnWriteArrayList.java
|
||||
Copyright (C) 2006 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package java.util.concurrent;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.AbstractList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.RandomAccess;
|
||||
|
||||
/** @since 1.5 */
|
||||
public class CopyOnWriteArrayList<E> extends AbstractList<E> implements
|
||||
List<E>, RandomAccess, Cloneable, Serializable
|
||||
{
|
||||
/**
|
||||
* Where the data is stored.
|
||||
*/
|
||||
private transient E[] data;
|
||||
|
||||
/**
|
||||
* Construct a new ArrayList with the default capacity (16).
|
||||
*/
|
||||
public CopyOnWriteArrayList()
|
||||
{
|
||||
data = (E[]) new Object[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new ArrayList, and initialize it with the elements in the
|
||||
* supplied Collection. The initial capacity is 110% of the Collection's size.
|
||||
*
|
||||
* @param c
|
||||
* the collection whose elements will initialize this list
|
||||
* @throws NullPointerException
|
||||
* if c is null
|
||||
*/
|
||||
public CopyOnWriteArrayList(Collection< ? extends E> c)
|
||||
{
|
||||
// FIXME ... correct? use c.toArray()
|
||||
data = (E[]) new Object[c.size()];
|
||||
int index = 0;
|
||||
for (E value : c)
|
||||
data[index++] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new ArrayList, and initialize it with the elements in the
|
||||
* supplied array.
|
||||
*
|
||||
* @param array
|
||||
* the array used to initialize this list
|
||||
* @throws NullPointerException
|
||||
* if array is null
|
||||
*/
|
||||
public CopyOnWriteArrayList(E[] array)
|
||||
{
|
||||
data = (E[]) array.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of elements in this list.
|
||||
*
|
||||
* @return the list size
|
||||
*/
|
||||
public int size()
|
||||
{
|
||||
return data.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the list is empty.
|
||||
*
|
||||
* @return true if there are no elements
|
||||
*/
|
||||
public boolean isEmpty()
|
||||
{
|
||||
return data.length == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true iff element is in this ArrayList.
|
||||
*
|
||||
* @param e
|
||||
* the element whose inclusion in the List is being tested
|
||||
* @return true if the list contains e
|
||||
*/
|
||||
public boolean contains(Object e)
|
||||
{
|
||||
return indexOf(e) != -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the lowest index at which element appears in this List, or -1 if it
|
||||
* does not appear.
|
||||
*
|
||||
* @param e
|
||||
* the element whose inclusion in the List is being tested
|
||||
* @return the index where e was found
|
||||
*/
|
||||
public int indexOf(Object e)
|
||||
{
|
||||
E[] data = this.data;
|
||||
for (int i = 0; i < data.length; i++)
|
||||
if (equals(e, data[i]))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the lowest index greater equal <code>index</code> at which
|
||||
* <code>e</code> appears in this List, or -1 if it does not
|
||||
* appear.
|
||||
*
|
||||
* @param e the element whose inclusion in the list is being tested
|
||||
* @param index the index at which the search begins
|
||||
* @return the index where <code>e</code> was found
|
||||
*/
|
||||
public int indexOf(E e, int index)
|
||||
{
|
||||
E[] data = this.data;
|
||||
|
||||
for (int i = index; i < data.length; i++)
|
||||
if (equals(e, data[i]))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the highest index at which element appears in this List, or -1 if
|
||||
* it does not appear.
|
||||
*
|
||||
* @param e
|
||||
* the element whose inclusion in the List is being tested
|
||||
* @return the index where e was found
|
||||
*/
|
||||
public int lastIndexOf(Object e)
|
||||
{
|
||||
E[] data = this.data;
|
||||
for (int i = data.length - 1; i >= 0; i--)
|
||||
if (equals(e, data[i]))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the highest index lesser equal <code>index</code> at
|
||||
* which <code>e</code> appears in this List, or -1 if it does not
|
||||
* appear.
|
||||
*
|
||||
* @param e the element whose inclusion in the list is being tested
|
||||
* @param index the index at which the search begins
|
||||
* @return the index where <code>e</code> was found
|
||||
*/
|
||||
public int lastIndexOf(E e, int index)
|
||||
{
|
||||
E[] data = this.data;
|
||||
|
||||
for (int i = index; i >= 0; i--)
|
||||
if (equals(e, data[i]))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a shallow copy of this ArrayList (elements are not cloned).
|
||||
*
|
||||
* @return the cloned object
|
||||
*/
|
||||
public Object clone()
|
||||
{
|
||||
CopyOnWriteArrayList<E> clone = null;
|
||||
try
|
||||
{
|
||||
clone = (CopyOnWriteArrayList<E>) super.clone();
|
||||
clone.data = (E[]) data.clone();
|
||||
}
|
||||
catch (CloneNotSupportedException e)
|
||||
{
|
||||
// Impossible to get here.
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Object array containing all of the elements in this ArrayList.
|
||||
* The array is independent of this list.
|
||||
*
|
||||
* @return an array representation of this list
|
||||
*/
|
||||
public Object[] toArray()
|
||||
{
|
||||
E[] data = this.data;
|
||||
E[] array = (E[]) new Object[data.length];
|
||||
System.arraycopy(data, 0, array, 0, data.length);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Array whose component type is the runtime component type of the
|
||||
* passed-in Array. The returned Array is populated with all of the elements
|
||||
* in this ArrayList. If the passed-in Array is not large enough to store all
|
||||
* of the elements in this List, a new Array will be created and returned; if
|
||||
* the passed-in Array is <i>larger</i> than the size of this List, then
|
||||
* size() index will be set to null.
|
||||
*
|
||||
* @param a
|
||||
* the passed-in Array
|
||||
* @return an array representation of this list
|
||||
* @throws ArrayStoreException
|
||||
* if the runtime type of a does not allow an element in this list
|
||||
* @throws NullPointerException
|
||||
* if a is null
|
||||
*/
|
||||
public <T> T[] toArray(T[] a)
|
||||
{
|
||||
E[] data = this.data;
|
||||
if (a.length < data.length)
|
||||
a = (T[]) Array.newInstance(a.getClass().getComponentType(), data.length);
|
||||
else if (a.length > data.length)
|
||||
a[data.length] = null;
|
||||
System.arraycopy(data, 0, a, 0, data.length);
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the element at the user-supplied index.
|
||||
*
|
||||
* @param index
|
||||
* the index of the element we are fetching
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if index < 0 || index >= size()
|
||||
*/
|
||||
public E get(int index)
|
||||
{
|
||||
return data[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the element at the specified index. The new element, e, can be an
|
||||
* object of any type or null.
|
||||
*
|
||||
* @param index
|
||||
* the index at which the element is being set
|
||||
* @param e
|
||||
* the element to be set
|
||||
* @return the element previously at the specified index
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if index < 0 || index >= 0
|
||||
*/
|
||||
public synchronized E set(int index, E e)
|
||||
{
|
||||
E result = data[index];
|
||||
E[] newData = (E[]) data.clone();
|
||||
newData[index] = e;
|
||||
data = newData;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the supplied element to the end of this list. The element, e, can
|
||||
* be an object of any type or null.
|
||||
*
|
||||
* @param e
|
||||
* the element to be appended to this list
|
||||
* @return true, the add will always succeed
|
||||
*/
|
||||
public synchronized boolean add(E e)
|
||||
{
|
||||
E[] data = this.data;
|
||||
E[] newData = (E[]) new Object[data.length + 1];
|
||||
System.arraycopy(data, 0, newData, 0, data.length);
|
||||
newData[data.length] = e;
|
||||
this.data = newData;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the supplied element at the specified index, shifting all elements
|
||||
* currently at that index or higher one to the right. The element, e, can be
|
||||
* an object of any type or null.
|
||||
*
|
||||
* @param index
|
||||
* the index at which the element is being added
|
||||
* @param e
|
||||
* the item being added
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if index < 0 || index > size()
|
||||
*/
|
||||
public synchronized void add(int index, E e)
|
||||
{
|
||||
E[] data = this.data;
|
||||
E[] newData = (E[]) new Object[data.length + 1];
|
||||
System.arraycopy(data, 0, newData, 0, index);
|
||||
newData[index] = e;
|
||||
System.arraycopy(data, index, newData, index + 1, data.length - index);
|
||||
this.data = newData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the element at the user-supplied index.
|
||||
*
|
||||
* @param index
|
||||
* the index of the element to be removed
|
||||
* @return the removed Object
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if index < 0 || index >= size()
|
||||
*/
|
||||
public synchronized E remove(int index)
|
||||
{
|
||||
E[] data = this.data;
|
||||
E[] newData = (E[]) new Object[data.length - 1];
|
||||
System.arraycopy(data, 0, newData, 0, index - 1);
|
||||
System.arraycopy(data, index + 1, newData, index,
|
||||
data.length - index - 1);
|
||||
E r = data[index];
|
||||
this.data = newData;
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all elements from this List
|
||||
*/
|
||||
public synchronized void clear()
|
||||
{
|
||||
data = (E[]) new Object[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add each element in the supplied Collection to this List. It is undefined
|
||||
* what happens if you modify the list while this is taking place; for
|
||||
* example, if the collection contains this list. c can contain objects of any
|
||||
* type, as well as null values.
|
||||
*
|
||||
* @param c
|
||||
* a Collection containing elements to be added to this List
|
||||
* @return true if the list was modified, in other words c is not empty
|
||||
* @throws NullPointerException
|
||||
* if c is null
|
||||
*/
|
||||
public synchronized boolean addAll(Collection< ? extends E> c)
|
||||
{
|
||||
return addAll(data.length, c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all elements in the supplied collection, inserting them beginning at
|
||||
* the specified index. c can contain objects of any type, as well as null
|
||||
* values.
|
||||
*
|
||||
* @param index
|
||||
* the index at which the elements will be inserted
|
||||
* @param c
|
||||
* the Collection containing the elements to be inserted
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if index < 0 || index > 0
|
||||
* @throws NullPointerException
|
||||
* if c is null
|
||||
*/
|
||||
public synchronized boolean addAll(int index, Collection< ? extends E> c)
|
||||
{
|
||||
E[] data = this.data;
|
||||
Iterator<? extends E> itr = c.iterator();
|
||||
int csize = c.size();
|
||||
if (csize == 0)
|
||||
return false;
|
||||
|
||||
E[] newData = (E[]) new Object[data.length + csize];
|
||||
System.arraycopy(data, 0, newData, 0, data.length);
|
||||
int end = data.length;
|
||||
for (E value : c)
|
||||
newData[end++] = value;
|
||||
this.data = newData;
|
||||
return true;
|
||||
}
|
||||
|
||||
public synchronized boolean addIfAbsent(E val)
|
||||
{
|
||||
if (contains(val))
|
||||
return false;
|
||||
add(val);
|
||||
return true;
|
||||
}
|
||||
|
||||
public synchronized int addAllAbsent(Collection<? extends E> c)
|
||||
{
|
||||
int result = 0;
|
||||
for (E val : c)
|
||||
{
|
||||
if (addIfAbsent(val))
|
||||
++result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes this object to the given stream.
|
||||
*
|
||||
* @param s
|
||||
* the stream to write to
|
||||
* @throws IOException
|
||||
* if the underlying stream fails
|
||||
* @serialData the size field (int), the length of the backing array (int),
|
||||
* followed by its elements (Objects) in proper order.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s) throws IOException
|
||||
{
|
||||
// The 'size' field.
|
||||
s.defaultWriteObject();
|
||||
// We serialize unused list entries to preserve capacity.
|
||||
int len = data.length;
|
||||
s.writeInt(len);
|
||||
// it would be more efficient to just write "size" items,
|
||||
// this need readObject read "size" items too.
|
||||
for (int i = 0; i < data.length; i++)
|
||||
s.writeObject(data[i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes this object from the given stream.
|
||||
*
|
||||
* @param s
|
||||
* the stream to read from
|
||||
* @throws ClassNotFoundException
|
||||
* if the underlying stream fails
|
||||
* @throws IOException
|
||||
* if the underlying stream fails
|
||||
* @serialData the size field (int), the length of the backing array (int),
|
||||
* followed by its elements (Objects) in proper order.
|
||||
*/
|
||||
private void readObject(ObjectInputStream s) throws IOException,
|
||||
ClassNotFoundException
|
||||
{
|
||||
// the `size' field.
|
||||
s.defaultReadObject();
|
||||
int capacity = s.readInt();
|
||||
data = (E[]) new Object[capacity];
|
||||
for (int i = 0; i < capacity; i++)
|
||||
data[i] = (E) s.readObject();
|
||||
}
|
||||
|
||||
static final boolean equals(Object o1, Object o2)
|
||||
{
|
||||
return o1 == null ? o2 == null : o1.equals(o2);
|
||||
}
|
||||
|
||||
Object[] getArray()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@@ -67,8 +67,8 @@ import java.util.Set;
|
||||
* @see java.util.jar.Attributes.Name
|
||||
* @author Mark Wielaard (mark@klomp.org)
|
||||
*/
|
||||
public class Attributes
|
||||
implements Cloneable, java.util.Map // Fully qualified for jikes 1.22
|
||||
public class Attributes
|
||||
implements Cloneable, Map<Object, Object>
|
||||
{
|
||||
|
||||
// Fields
|
||||
@@ -78,7 +78,7 @@ public class Attributes
|
||||
* implementation it is actually a Hashtable, but that can be different in
|
||||
* other implementations.
|
||||
*/
|
||||
protected Map map;
|
||||
protected Map<Object, Object> map;
|
||||
|
||||
// Inner class
|
||||
|
||||
@@ -492,7 +492,7 @@ public class Attributes
|
||||
*
|
||||
* @return a set of attribute name value pairs
|
||||
*/
|
||||
public Set entrySet()
|
||||
public Set<Map.Entry<Object, Object>> entrySet()
|
||||
{
|
||||
return map.entrySet();
|
||||
}
|
||||
@@ -558,7 +558,7 @@ public class Attributes
|
||||
/**
|
||||
* Gives a Set of all the values of defined attribute names.
|
||||
*/
|
||||
public Set keySet()
|
||||
public Set<Object> keySet()
|
||||
{
|
||||
return map.keySet();
|
||||
}
|
||||
@@ -587,7 +587,7 @@ public class Attributes
|
||||
* @exception ClassCastException if the supplied map is not an instance of
|
||||
* Attributes
|
||||
*/
|
||||
public void putAll(Map attr)
|
||||
public void putAll(Map<?, ?> attr)
|
||||
{
|
||||
if (!(attr instanceof Attributes))
|
||||
{
|
||||
@@ -622,7 +622,7 @@ public class Attributes
|
||||
* Returns all the values of the defined attribute name/value pairs as a
|
||||
* Collection.
|
||||
*/
|
||||
public Collection values()
|
||||
public Collection<Object> values()
|
||||
{
|
||||
return map.values();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* JarEntry.java - Represents an entry in a jar file
|
||||
Copyright (C) 2000 Free Software Foundation, Inc.
|
||||
Copyright (C) 2000, 2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -39,6 +39,7 @@ package java.util.jar;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.cert.Certificate;
|
||||
import java.util.Set;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
/**
|
||||
@@ -60,7 +61,7 @@ public class JarEntry extends ZipEntry
|
||||
// (Package local) fields
|
||||
|
||||
Attributes attr;
|
||||
Certificate certs[];
|
||||
JarFile jarfile;
|
||||
|
||||
// Constructors
|
||||
|
||||
@@ -79,7 +80,7 @@ public class JarEntry extends ZipEntry
|
||||
{
|
||||
super(name);
|
||||
attr = null;
|
||||
certs = null;
|
||||
jarfile = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,7 +94,7 @@ public class JarEntry extends ZipEntry
|
||||
{
|
||||
super(entry);
|
||||
attr = null;
|
||||
certs = null;
|
||||
jarfile = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -112,7 +113,7 @@ public class JarEntry extends ZipEntry
|
||||
catch (IOException _)
|
||||
{
|
||||
}
|
||||
certs = entry.getCertificates();
|
||||
jarfile = entry.jarfile;
|
||||
}
|
||||
|
||||
// Methods
|
||||
@@ -153,13 +154,19 @@ public class JarEntry extends ZipEntry
|
||||
*/
|
||||
public Certificate[] getCertificates()
|
||||
{
|
||||
if (certs != null)
|
||||
if (jarfile != null)
|
||||
{
|
||||
return (Certificate[])certs.clone();
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
synchronized (jarfile)
|
||||
{
|
||||
if (jarfile.entryCerts != null)
|
||||
{
|
||||
Set certs = (Set) jarfile.entryCerts.get(getName());
|
||||
if (certs != null
|
||||
&& jarfile.verified.get(getName()) == Boolean.TRUE)
|
||||
return (Certificate[]) certs.toArray(new Certificate[certs.size()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,8 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipException;
|
||||
import java.util.zip.ZipFile;
|
||||
@@ -149,6 +151,12 @@ public class JarFile extends ZipFile
|
||||
*/
|
||||
HashMap entryCerts;
|
||||
|
||||
/**
|
||||
* A {@link Map} of message digest algorithm names to their implementation.
|
||||
* Used to reduce object (algorithm implementation) instantiation.
|
||||
*/
|
||||
private HashMap digestAlgorithms = new HashMap();
|
||||
|
||||
static boolean DEBUG = false;
|
||||
static void debug(Object msg)
|
||||
{
|
||||
@@ -313,7 +321,7 @@ public class JarFile extends ZipFile
|
||||
*
|
||||
* @exception IllegalStateException when the JarFile is already closed
|
||||
*/
|
||||
public Enumeration entries() throws IllegalStateException
|
||||
public Enumeration<JarEntry> entries() throws IllegalStateException
|
||||
{
|
||||
return new JarEnumeration(super.entries(), this);
|
||||
}
|
||||
@@ -322,13 +330,13 @@ public class JarFile extends ZipFile
|
||||
* Wraps a given Zip Entries Enumeration. For every zip entry a
|
||||
* JarEntry is created and the corresponding Attributes are looked up.
|
||||
*/
|
||||
private static class JarEnumeration implements Enumeration
|
||||
private static class JarEnumeration implements Enumeration<JarEntry>
|
||||
{
|
||||
|
||||
private final Enumeration entries;
|
||||
private final Enumeration<? extends ZipEntry> entries;
|
||||
private final JarFile jarfile;
|
||||
|
||||
JarEnumeration(Enumeration e, JarFile f)
|
||||
JarEnumeration(Enumeration<? extends ZipEntry> e, JarFile f)
|
||||
{
|
||||
entries = e;
|
||||
jarfile = f;
|
||||
@@ -339,7 +347,7 @@ public class JarFile extends ZipFile
|
||||
return entries.hasMoreElements();
|
||||
}
|
||||
|
||||
public Object nextElement()
|
||||
public JarEntry nextElement()
|
||||
{
|
||||
ZipEntry zip = (ZipEntry) entries.nextElement();
|
||||
JarEntry jar = new JarEntry(zip);
|
||||
@@ -374,19 +382,8 @@ public class JarFile extends ZipFile
|
||||
}
|
||||
jarfile.signaturesRead = true; // fudge it.
|
||||
}
|
||||
|
||||
// Include the certificates only if we have asserted that the
|
||||
// signatures are valid. This means the certificates will not be
|
||||
// available if the entry hasn't been read yet.
|
||||
if (jarfile.entryCerts != null
|
||||
&& jarfile.verified.get(zip.getName()) == Boolean.TRUE)
|
||||
{
|
||||
Set certs = (Set) jarfile.entryCerts.get(jar.getName());
|
||||
if (certs != null)
|
||||
jar.certs = (Certificate[])
|
||||
certs.toArray(new Certificate[certs.size()]);
|
||||
}
|
||||
}
|
||||
jar.jarfile = jarfile;
|
||||
return jar;
|
||||
}
|
||||
}
|
||||
@@ -431,18 +428,7 @@ public class JarFile extends ZipFile
|
||||
}
|
||||
signaturesRead = true;
|
||||
}
|
||||
// See the comments in the JarEnumeration for why we do this
|
||||
// check.
|
||||
if (DEBUG)
|
||||
debug("entryCerts=" + entryCerts + " verified " + name
|
||||
+ " ? " + verified.get(name));
|
||||
if (entryCerts != null && verified.get(name) == Boolean.TRUE)
|
||||
{
|
||||
Set certs = (Set) entryCerts.get(name);
|
||||
if (certs != null)
|
||||
jarEntry.certs = (Certificate[])
|
||||
certs.toArray(new Certificate[certs.size()]);
|
||||
}
|
||||
jarEntry.jarfile = this;
|
||||
return jarEntry;
|
||||
}
|
||||
return null;
|
||||
@@ -599,6 +585,31 @@ public class JarFile extends ZipFile
|
||||
validCerts.clear();
|
||||
}
|
||||
|
||||
// Read the manifest into a HashMap (String fileName, String entry)
|
||||
// The fileName might be split into multiple lines in the manifest.
|
||||
// Such additional lines will start with a space.
|
||||
InputStream in = super.getInputStream(super.getEntry(MANIFEST_NAME));
|
||||
ByteArrayOutputStream baStream = new ByteArrayOutputStream();
|
||||
byte[] ba = new byte[1024];
|
||||
while (true)
|
||||
{
|
||||
int len = in.read(ba);
|
||||
if (len < 0)
|
||||
break;
|
||||
baStream.write(ba, 0, len);
|
||||
}
|
||||
in.close();
|
||||
|
||||
HashMap hmManifestEntries = new HashMap();
|
||||
Pattern p = Pattern.compile("Name: (.+?\r?\n(?: .+?\r?\n)*)"
|
||||
+ ".+?-Digest: .+?\r?\n\r?\n");
|
||||
Matcher m = p.matcher(baStream.toString());
|
||||
while (m.find())
|
||||
{
|
||||
String fileName = m.group(1).replaceAll("\r?\n ?", "");
|
||||
hmManifestEntries.put(fileName, m.group());
|
||||
}
|
||||
|
||||
// Phase 3: verify the signature file signatures against the manifest,
|
||||
// mapping the entry name to the target certificates.
|
||||
this.entryCerts = new HashMap();
|
||||
@@ -614,7 +625,7 @@ public class JarFile extends ZipFile
|
||||
Map.Entry e2 = (Map.Entry) it2.next();
|
||||
String entryname = String.valueOf(e2.getKey());
|
||||
Attributes attr = (Attributes) e2.getValue();
|
||||
if (verifyHashes(entryname, attr))
|
||||
if (verifyHashes(entryname, attr, hmManifestEntries))
|
||||
{
|
||||
if (DEBUG)
|
||||
debug("entry " + entryname + " has certificates " + certificates);
|
||||
@@ -721,39 +732,29 @@ public class JarFile extends ZipFile
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the digest(s) in a signature file were, in fact, made
|
||||
* over the manifest entry for ENTRY.
|
||||
*
|
||||
* Verifies that the digest(s) in a signature file were, in fact, made over
|
||||
* the manifest entry for ENTRY.
|
||||
*
|
||||
* @param entry The entry name.
|
||||
* @param attr The attributes from the signature file to verify.
|
||||
* @param hmManifestEntries Mappings of Jar file entry names to their manifest
|
||||
* entry text; i.e. the base-64 encoding of their
|
||||
*/
|
||||
private boolean verifyHashes(String entry, Attributes attr)
|
||||
private boolean verifyHashes(String entry, Attributes attr,
|
||||
HashMap hmManifestEntries)
|
||||
{
|
||||
int verified = 0;
|
||||
|
||||
// The bytes for ENTRY's manifest entry, which are signed in the
|
||||
// signature file.
|
||||
byte[] entryBytes = null;
|
||||
try
|
||||
{
|
||||
ZipEntry e = super.getEntry(entry);
|
||||
if (e == null)
|
||||
{
|
||||
if (DEBUG)
|
||||
debug("verifyHashes: no entry '" + entry + "'");
|
||||
return false;
|
||||
}
|
||||
entryBytes = readManifestEntry(e);
|
||||
}
|
||||
catch (IOException ioe)
|
||||
String stringEntry = (String) hmManifestEntries.get(entry);
|
||||
if (stringEntry == null)
|
||||
{
|
||||
if (DEBUG)
|
||||
{
|
||||
debug(ioe);
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
debug("could not find " + entry + " in manifest");
|
||||
return false;
|
||||
}
|
||||
// The bytes for ENTRY's manifest entry, which are signed in the
|
||||
// signature file.
|
||||
byte[] entryBytes = stringEntry.getBytes();
|
||||
|
||||
for (Iterator it = attr.entrySet().iterator(); it.hasNext(); )
|
||||
{
|
||||
@@ -765,9 +766,14 @@ public class JarFile extends ZipFile
|
||||
try
|
||||
{
|
||||
byte[] hash = Base64InputStream.decode((String) e.getValue());
|
||||
MessageDigest md = MessageDigest.getInstance(alg, provider);
|
||||
md.update(entryBytes);
|
||||
byte[] hash2 = md.digest();
|
||||
MessageDigest md = (MessageDigest) digestAlgorithms.get(alg);
|
||||
if (md == null)
|
||||
{
|
||||
md = MessageDigest.getInstance(alg, provider);
|
||||
digestAlgorithms.put(alg, md);
|
||||
}
|
||||
md.reset();
|
||||
byte[] hash2 = md.digest(entryBytes);
|
||||
if (DEBUG)
|
||||
debug("verifying SF entry " + entry + " alg: " + md.getAlgorithm()
|
||||
+ " expect=" + new java.math.BigInteger(hash).toString(16)
|
||||
@@ -800,100 +806,6 @@ public class JarFile extends ZipFile
|
||||
return verified > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the raw bytes that comprise a manifest entry. We can't use the
|
||||
* Manifest object itself, because that loses information (such as line
|
||||
* endings, and order of entries).
|
||||
*/
|
||||
private byte[] readManifestEntry(ZipEntry entry) throws IOException
|
||||
{
|
||||
InputStream in = super.getInputStream(super.getEntry(MANIFEST_NAME));
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
byte[] target = ("Name: " + entry.getName()).getBytes();
|
||||
int t = 0, c, prev = -1, state = 0, l = -1;
|
||||
|
||||
while ((c = in.read()) != -1)
|
||||
{
|
||||
// if (DEBUG)
|
||||
// debug("read "
|
||||
// + (c == '\n' ? "\\n" : (c == '\r' ? "\\r" : String.valueOf((char) c)))
|
||||
// + " state=" + state + " prev="
|
||||
// + (prev == '\n' ? "\\n" : (prev == '\r' ? "\\r" : String.valueOf((char) prev)))
|
||||
// + " t=" + t + (t < target.length ? (" target[t]=" + (char) target[t]) : "")
|
||||
// + " l=" + l);
|
||||
switch (state)
|
||||
{
|
||||
|
||||
// Step 1: read until we find the "target" bytes: the start
|
||||
// of the entry we need to read.
|
||||
case 0:
|
||||
if (((byte) c) != target[t])
|
||||
t = 0;
|
||||
else
|
||||
{
|
||||
t++;
|
||||
if (t == target.length)
|
||||
{
|
||||
out.write(target);
|
||||
state = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// Step 2: assert that there is a newline character after
|
||||
// the "target" bytes.
|
||||
case 1:
|
||||
if (c != '\n' && c != '\r')
|
||||
{
|
||||
out.reset();
|
||||
t = 0;
|
||||
state = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
out.write(c);
|
||||
state = 2;
|
||||
}
|
||||
break;
|
||||
|
||||
// Step 3: read this whole entry, until we reach an empty
|
||||
// line.
|
||||
case 2:
|
||||
if (c == '\n')
|
||||
{
|
||||
out.write(c);
|
||||
// NL always terminates a line.
|
||||
if (l == 0 || (l == 1 && prev == '\r'))
|
||||
return out.toByteArray();
|
||||
l = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Here we see a blank line terminated by a CR,
|
||||
// followed by the next entry. Technically, `c' should
|
||||
// always be 'N' at this point.
|
||||
if (l == 1 && prev == '\r')
|
||||
return out.toByteArray();
|
||||
out.write(c);
|
||||
l++;
|
||||
}
|
||||
prev = c;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new RuntimeException("this statement should be unreachable");
|
||||
}
|
||||
}
|
||||
|
||||
// The last entry, with a single CR terminating the line.
|
||||
if (state == 2 && prev == '\r' && l == 0)
|
||||
return out.toByteArray();
|
||||
|
||||
// We should not reach this point, we didn't find the entry (or, possibly,
|
||||
// it is the last entry and is malformed).
|
||||
throw new IOException("could not find " + entry + " in manifest");
|
||||
}
|
||||
|
||||
/**
|
||||
* A utility class that verifies jar entries as they are read.
|
||||
*/
|
||||
|
||||
@@ -38,7 +38,7 @@ exception statement from your version. */
|
||||
package java.util.jar;
|
||||
|
||||
import gnu.java.util.jar.JarUtils;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
@@ -60,7 +60,7 @@ public class Manifest implements Cloneable
|
||||
private final Attributes mainAttr;
|
||||
|
||||
/** A map of atrributes for all entries described in this Manifest. */
|
||||
private final Map entries;
|
||||
private final Map<String, Attributes> entries;
|
||||
|
||||
// Constructors
|
||||
|
||||
@@ -70,7 +70,7 @@ public class Manifest implements Cloneable
|
||||
public Manifest()
|
||||
{
|
||||
mainAttr = new Attributes();
|
||||
entries = new Hashtable();
|
||||
entries = new Hashtable<String, Attributes>();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,7 +104,7 @@ public class Manifest implements Cloneable
|
||||
public Manifest(Manifest man)
|
||||
{
|
||||
mainAttr = new Attributes(man.getMainAttributes());
|
||||
entries = new Hashtable(man.getEntries());
|
||||
entries = new Hashtable<String, Attributes>(man.getEntries());
|
||||
}
|
||||
|
||||
// Methods
|
||||
@@ -122,7 +122,7 @@ public class Manifest implements Cloneable
|
||||
* in this manifest. Adding, changing or removing from this entries map
|
||||
* changes the entries of this manifest.
|
||||
*/
|
||||
public Map getEntries()
|
||||
public Map<String, Attributes> getEntries()
|
||||
{
|
||||
return entries;
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ public class LogManager
|
||||
* The registered named loggers; maps the name of a Logger to
|
||||
* a WeakReference to it.
|
||||
*/
|
||||
private Map loggers;
|
||||
private Map<String, WeakReference<Logger>> loggers;
|
||||
|
||||
/**
|
||||
* The properties for the logging framework which have been
|
||||
@@ -150,7 +150,7 @@ public class LogManager
|
||||
* this case.
|
||||
*/
|
||||
private final PropertyChangeSupport pcs = new PropertyChangeSupport( /* source bean */
|
||||
LogManager.class);
|
||||
LogManager.class);
|
||||
|
||||
protected LogManager()
|
||||
{
|
||||
@@ -269,7 +269,7 @@ public class LogManager
|
||||
*/
|
||||
name = logger.getName();
|
||||
|
||||
ref = (WeakReference) loggers.get(name);
|
||||
ref = loggers.get(name);
|
||||
if (ref != null)
|
||||
{
|
||||
if (ref.get() != null)
|
||||
@@ -286,7 +286,7 @@ public class LogManager
|
||||
checkAccess();
|
||||
|
||||
Logger parent = findAncestor(logger);
|
||||
loggers.put(name, new WeakReference(logger));
|
||||
loggers.put(name, new WeakReference<Logger>(logger));
|
||||
if (parent != logger.getParent())
|
||||
logger.setParent(parent);
|
||||
|
||||
@@ -318,26 +318,23 @@ public class LogManager
|
||||
* When adding "foo.bar", the logger "foo.bar.baz" should change
|
||||
* its parent to "foo.bar".
|
||||
*/
|
||||
if (parent != Logger.root)
|
||||
for (Iterator iter = loggers.keySet().iterator(); iter.hasNext();)
|
||||
{
|
||||
for (Iterator iter = loggers.keySet().iterator(); iter.hasNext();)
|
||||
{
|
||||
Logger possChild = (Logger) ((WeakReference) loggers.get(iter.next()))
|
||||
.get();
|
||||
if ((possChild == null) || (possChild == logger)
|
||||
|| (possChild.getParent() != parent))
|
||||
continue;
|
||||
|
||||
if (! possChild.getName().startsWith(name))
|
||||
continue;
|
||||
|
||||
if (possChild.getName().charAt(name.length()) != '.')
|
||||
continue;
|
||||
|
||||
possChild.setParent(logger);
|
||||
}
|
||||
Logger possChild = (Logger) ((WeakReference) loggers.get(iter.next()))
|
||||
.get();
|
||||
if ((possChild == null) || (possChild == logger)
|
||||
|| (possChild.getParent() != parent))
|
||||
continue;
|
||||
|
||||
if (! possChild.getName().startsWith(name))
|
||||
continue;
|
||||
|
||||
if (possChild.getName().charAt(name.length()) != '.')
|
||||
continue;
|
||||
|
||||
possChild.setParent(logger);
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -365,15 +362,13 @@ public class LogManager
|
||||
int bestNameLength = 0;
|
||||
|
||||
Logger cand;
|
||||
String candName;
|
||||
int candNameLength;
|
||||
|
||||
if (child == Logger.root)
|
||||
return null;
|
||||
|
||||
for (Iterator iter = loggers.keySet().iterator(); iter.hasNext();)
|
||||
for (String candName : loggers.keySet())
|
||||
{
|
||||
candName = (String) iter.next();
|
||||
candNameLength = candName.length();
|
||||
|
||||
if (candNameLength > bestNameLength
|
||||
@@ -381,7 +376,7 @@ public class LogManager
|
||||
&& childName.startsWith(candName)
|
||||
&& childName.charAt(candNameLength) == '.')
|
||||
{
|
||||
cand = (Logger) ((WeakReference) loggers.get(candName)).get();
|
||||
cand = loggers.get(candName).get();
|
||||
if ((cand == null) || (cand == child))
|
||||
continue;
|
||||
|
||||
@@ -406,14 +401,14 @@ public class LogManager
|
||||
*/
|
||||
public synchronized Logger getLogger(String name)
|
||||
{
|
||||
WeakReference ref;
|
||||
WeakReference<Logger> ref;
|
||||
|
||||
/* Throw a NullPointerException if name is null. */
|
||||
name.getClass();
|
||||
|
||||
ref = (WeakReference) loggers.get(name);
|
||||
ref = loggers.get(name);
|
||||
if (ref != null)
|
||||
return (Logger) ref.get();
|
||||
return ref.get();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
@@ -426,7 +421,7 @@ public class LogManager
|
||||
* @return an Enumeration with the names of the currently
|
||||
* registered Loggers.
|
||||
*/
|
||||
public synchronized Enumeration getLoggerNames()
|
||||
public synchronized Enumeration<String> getLoggerNames()
|
||||
{
|
||||
return Collections.enumeration(loggers.keySet());
|
||||
}
|
||||
@@ -449,16 +444,16 @@ public class LogManager
|
||||
|
||||
properties = new Properties();
|
||||
|
||||
Iterator iter = loggers.values().iterator();
|
||||
Iterator<WeakReference<Logger>> iter = loggers.values().iterator();
|
||||
while (iter.hasNext())
|
||||
for (WeakReference<Logger> ref : loggers.values())
|
||||
{
|
||||
WeakReference ref;
|
||||
Logger logger;
|
||||
|
||||
ref = (WeakReference) iter.next();
|
||||
ref = iter.next();
|
||||
if (ref != null)
|
||||
{
|
||||
logger = (Logger) ref.get();
|
||||
logger = ref.get();
|
||||
|
||||
if (logger == null)
|
||||
iter.remove();
|
||||
@@ -713,7 +708,11 @@ public class LogManager
|
||||
{
|
||||
try
|
||||
{
|
||||
return Level.parse(getLogManager().getProperty(propertyName));
|
||||
String value = getLogManager().getProperty(propertyName);
|
||||
if (value != null)
|
||||
return Level.parse(getLogManager().getProperty(propertyName));
|
||||
else
|
||||
return defaultValue;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -60,7 +60,7 @@ public interface LoggingMXBean
|
||||
/**
|
||||
* Return a list of all logger names.
|
||||
*/
|
||||
List/*<String>*/ getLoggerNames();
|
||||
List<String> getLoggerNames();
|
||||
|
||||
/**
|
||||
* Return the name of the parent of the indicated logger.
|
||||
|
||||
@@ -251,7 +251,7 @@ public abstract class Preferences {
|
||||
* @exception SecurityException when a security manager is installed and
|
||||
* the caller does not have <code>RuntimePermission("preferences")</code>.
|
||||
*/
|
||||
public static Preferences systemNodeForPackage(Class c)
|
||||
public static Preferences systemNodeForPackage(Class<?> c)
|
||||
throws SecurityException
|
||||
{
|
||||
return nodeForPackage(c, systemRoot());
|
||||
@@ -270,7 +270,7 @@ public abstract class Preferences {
|
||||
* @exception SecurityException when a security manager is installed and
|
||||
* the caller does not have <code>RuntimePermission("preferences")</code>.
|
||||
*/
|
||||
public static Preferences userNodeForPackage(Class c)
|
||||
public static Preferences userNodeForPackage(Class<?> c)
|
||||
throws SecurityException
|
||||
{
|
||||
return nodeForPackage(c, userRoot());
|
||||
|
||||
@@ -218,7 +218,7 @@ public final class Matcher implements MatchResult
|
||||
|
||||
public boolean lookingAt ()
|
||||
{
|
||||
match = pattern.getRE().getMatch(inputCharIndexed, 0);
|
||||
match = pattern.getRE().getMatch(inputCharIndexed, 0, RE.REG_FIX_STARTING_POSITION, null);
|
||||
if (match != null)
|
||||
{
|
||||
if (match.getStartIndex() == 0)
|
||||
@@ -243,7 +243,7 @@ public final class Matcher implements MatchResult
|
||||
*/
|
||||
public boolean matches ()
|
||||
{
|
||||
match = pattern.getRE().getMatch(inputCharIndexed, 0, RE.REG_TRY_ENTIRE_MATCH);
|
||||
match = pattern.getRE().getMatch(inputCharIndexed, 0, RE.REG_TRY_ENTIRE_MATCH|RE.REG_FIX_STARTING_POSITION, null);
|
||||
if (match != null)
|
||||
{
|
||||
if (match.getStartIndex() == 0)
|
||||
@@ -278,6 +278,7 @@ public final class Matcher implements MatchResult
|
||||
public Matcher reset (CharSequence input)
|
||||
{
|
||||
this.input = input;
|
||||
this.inputCharIndexed = RE.makeCharIndexed(input, 0);
|
||||
return reset();
|
||||
}
|
||||
|
||||
@@ -309,6 +310,28 @@ public final class Matcher implements MatchResult
|
||||
return match.getStartIndex(group);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if and only if the matcher hit the end of input.
|
||||
*/
|
||||
public boolean hitEnd()
|
||||
{
|
||||
return inputCharIndexed.hitEnd();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A string expression of this matcher.
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(this.getClass().getName())
|
||||
.append("[pattern=").append(pattern.pattern())
|
||||
.append(" region=").append("0").append(",").append(input.length())
|
||||
.append(" lastmatch=").append(match == null ? "" : match.toString())
|
||||
.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void assertMatchOp()
|
||||
{
|
||||
if (match == null) throw new IllegalStateException();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Deflater.java - Compress a data stream
|
||||
Copyright (C) 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2000, 2001, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -150,7 +150,7 @@ public class Deflater
|
||||
private int state;
|
||||
|
||||
/** The total bytes of output written. */
|
||||
private int totalOut;
|
||||
private long totalOut;
|
||||
|
||||
/** The pending output. */
|
||||
private DeflaterPending pending;
|
||||
@@ -241,7 +241,17 @@ public class Deflater
|
||||
/**
|
||||
* Gets the number of input bytes processed so far.
|
||||
*/
|
||||
@Deprecated
|
||||
public int getTotalIn()
|
||||
{
|
||||
return (int) engine.getTotalIn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of input bytes processed so far.
|
||||
* @since 1.5
|
||||
*/
|
||||
public long getBytesRead()
|
||||
{
|
||||
return engine.getTotalIn();
|
||||
}
|
||||
@@ -249,7 +259,17 @@ public class Deflater
|
||||
/**
|
||||
* Gets the number of output bytes so far.
|
||||
*/
|
||||
@Deprecated
|
||||
public int getTotalOut()
|
||||
{
|
||||
return (int) totalOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of output bytes so far.
|
||||
* @since 1.5
|
||||
*/
|
||||
public long getBytesWritten()
|
||||
{
|
||||
return totalOut;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* DeflaterEngine.java --
|
||||
Copyright (C) 2001, 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 2001, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -92,7 +92,7 @@ class DeflaterEngine implements DeflaterConstants
|
||||
private byte[] inputBuf;
|
||||
|
||||
/** The total bytes of input read. */
|
||||
private int totalIn;
|
||||
private long totalIn;
|
||||
|
||||
/** The offset into inputBuf, where input data starts. */
|
||||
private int inputOff;
|
||||
@@ -163,7 +163,7 @@ class DeflaterEngine implements DeflaterConstants
|
||||
return chksum;
|
||||
}
|
||||
|
||||
public final int getTotalIn()
|
||||
public final long getTotalIn()
|
||||
{
|
||||
return totalIn;
|
||||
}
|
||||
|
||||
@@ -140,13 +140,13 @@ public class Inflater
|
||||
/**
|
||||
* The total number of inflated bytes.
|
||||
*/
|
||||
private int totalOut;
|
||||
private long totalOut;
|
||||
/**
|
||||
* The total number of bytes set with setInput(). This is not the
|
||||
* value returned by getTotalIn(), since this also includes the
|
||||
* unprocessed input.
|
||||
*/
|
||||
private int totalIn;
|
||||
private long totalIn;
|
||||
/**
|
||||
* This variable stores the nowrap flag that was given to the constructor.
|
||||
* True means, that the inflated stream doesn't contain a header nor the
|
||||
@@ -246,7 +246,18 @@ public class Inflater
|
||||
* Gets the total number of processed compressed input bytes.
|
||||
* @return the total number of bytes of processed input bytes.
|
||||
*/
|
||||
@Deprecated
|
||||
public int getTotalIn()
|
||||
{
|
||||
return (int) (totalIn - getRemaining());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the total number of processed compressed input bytes.
|
||||
* @return the total number of bytes of processed input bytes.
|
||||
* @since 1.5
|
||||
*/
|
||||
public long getBytesRead()
|
||||
{
|
||||
return totalIn - getRemaining();
|
||||
}
|
||||
@@ -255,7 +266,18 @@ public class Inflater
|
||||
* Gets the total number of output bytes returned by inflate().
|
||||
* @return the total number of output bytes.
|
||||
*/
|
||||
@Deprecated
|
||||
public int getTotalOut()
|
||||
{
|
||||
return (int) totalOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the total number of output bytes returned by inflate().
|
||||
* @return the total number of output bytes.
|
||||
* @since 1.5
|
||||
*/
|
||||
public long getBytesWritten()
|
||||
{
|
||||
return totalOut;
|
||||
}
|
||||
|
||||
@@ -48,6 +48,9 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -88,7 +91,7 @@ public class ZipFile implements ZipConstants
|
||||
private final RandomAccessFile raf;
|
||||
|
||||
// The entries of this zip file when initialized and not yet closed.
|
||||
private LinkedHashMap entries;
|
||||
private LinkedHashMap<String, ZipEntry> entries;
|
||||
|
||||
private boolean closed = false;
|
||||
|
||||
@@ -250,7 +253,7 @@ public class ZipFile implements ZipConstants
|
||||
throw new EOFException(name);
|
||||
int centralOffset = inp.readLeInt();
|
||||
|
||||
entries = new LinkedHashMap(count+count/2);
|
||||
entries = new LinkedHashMap<String, ZipEntry> (count+count/2);
|
||||
inp.seek(centralOffset);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
@@ -327,7 +330,7 @@ public class ZipFile implements ZipConstants
|
||||
*
|
||||
* @exception IllegalStateException when the ZipFile has already been closed
|
||||
*/
|
||||
public Enumeration entries()
|
||||
public Enumeration<? extends ZipEntry> entries()
|
||||
{
|
||||
checkClosed();
|
||||
|
||||
@@ -347,7 +350,7 @@ public class ZipFile implements ZipConstants
|
||||
* @exception IllegalStateException when the ZipFile has already been closed.
|
||||
* @exception IOException when the entries could not be read.
|
||||
*/
|
||||
private LinkedHashMap getEntries() throws IOException
|
||||
private LinkedHashMap<String, ZipEntry> getEntries() throws IOException
|
||||
{
|
||||
synchronized(raf)
|
||||
{
|
||||
@@ -375,11 +378,11 @@ public class ZipFile implements ZipConstants
|
||||
|
||||
try
|
||||
{
|
||||
LinkedHashMap entries = getEntries();
|
||||
ZipEntry entry = (ZipEntry) entries.get(name);
|
||||
LinkedHashMap<String, ZipEntry> entries = getEntries();
|
||||
ZipEntry entry = entries.get(name);
|
||||
// If we didn't find it, maybe it's a directory.
|
||||
if (entry == null && !name.endsWith("/"))
|
||||
entry = (ZipEntry) entries.get(name + '/');
|
||||
entry = entries.get(name + '/');
|
||||
return entry != null ? new ZipEntry(entry, name) : null;
|
||||
}
|
||||
catch (IOException ioe)
|
||||
@@ -414,9 +417,9 @@ public class ZipFile implements ZipConstants
|
||||
{
|
||||
checkClosed();
|
||||
|
||||
LinkedHashMap entries = getEntries();
|
||||
LinkedHashMap<String, ZipEntry> entries = getEntries();
|
||||
String name = entry.getName();
|
||||
ZipEntry zipEntry = (ZipEntry) entries.get(name);
|
||||
ZipEntry zipEntry = entries.get(name);
|
||||
if (zipEntry == null)
|
||||
return null;
|
||||
|
||||
@@ -491,11 +494,11 @@ public class ZipFile implements ZipConstants
|
||||
}
|
||||
}
|
||||
|
||||
private static class ZipEntryEnumeration implements Enumeration
|
||||
private static class ZipEntryEnumeration implements Enumeration<ZipEntry>
|
||||
{
|
||||
private final Iterator elements;
|
||||
private final Iterator<ZipEntry> elements;
|
||||
|
||||
public ZipEntryEnumeration(Iterator elements)
|
||||
public ZipEntryEnumeration(Iterator<ZipEntry> elements)
|
||||
{
|
||||
this.elements = elements;
|
||||
}
|
||||
@@ -505,17 +508,27 @@ public class ZipFile implements ZipConstants
|
||||
return elements.hasNext();
|
||||
}
|
||||
|
||||
public Object nextElement()
|
||||
public ZipEntry nextElement()
|
||||
{
|
||||
/* We return a clone, just to be safe that the user doesn't
|
||||
* change the entry.
|
||||
*/
|
||||
return ((ZipEntry)elements.next()).clone();
|
||||
return (ZipEntry) (elements.next().clone());
|
||||
}
|
||||
}
|
||||
|
||||
private static final class PartialInputStream extends InputStream
|
||||
{
|
||||
/**
|
||||
* The UTF-8 charset use for decoding the filenames.
|
||||
*/
|
||||
private static final Charset UTF8CHARSET = Charset.forName("UTF-8");
|
||||
|
||||
/**
|
||||
* The actual UTF-8 decoder. Created on demand.
|
||||
*/
|
||||
private CharsetDecoder utf8Decoder;
|
||||
|
||||
private final RandomAccessFile raf;
|
||||
private final byte[] buffer;
|
||||
private long bufferOffset;
|
||||
@@ -652,23 +665,86 @@ public class ZipFile implements ZipConstants
|
||||
|
||||
int readLeShort() throws IOException
|
||||
{
|
||||
int b0 = read();
|
||||
int b1 = read();
|
||||
if (b1 == -1)
|
||||
throw new EOFException();
|
||||
return (b0 & 0xff) | (b1 & 0xff) << 8;
|
||||
int result;
|
||||
if(pos + 1 < buffer.length)
|
||||
{
|
||||
result = ((buffer[pos + 0] & 0xff) | (buffer[pos + 1] & 0xff) << 8);
|
||||
pos += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
int b0 = read();
|
||||
int b1 = read();
|
||||
if (b1 == -1)
|
||||
throw new EOFException();
|
||||
result = (b0 & 0xff) | (b1 & 0xff) << 8;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int readLeInt() throws IOException
|
||||
{
|
||||
int b0 = read();
|
||||
int b1 = read();
|
||||
int b2 = read();
|
||||
int b3 = read();
|
||||
if (b3 == -1)
|
||||
throw new EOFException();
|
||||
return ((b0 & 0xff) | (b1 & 0xff) << 8)
|
||||
| ((b2 & 0xff) | (b3 & 0xff) << 8) << 16;
|
||||
int result;
|
||||
if(pos + 3 < buffer.length)
|
||||
{
|
||||
result = (((buffer[pos + 0] & 0xff) | (buffer[pos + 1] & 0xff) << 8)
|
||||
| ((buffer[pos + 2] & 0xff)
|
||||
| (buffer[pos + 3] & 0xff) << 8) << 16);
|
||||
pos += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
int b0 = read();
|
||||
int b1 = read();
|
||||
int b2 = read();
|
||||
int b3 = read();
|
||||
if (b3 == -1)
|
||||
throw new EOFException();
|
||||
result = (((b0 & 0xff) | (b1 & 0xff) << 8) | ((b2 & 0xff)
|
||||
| (b3 & 0xff) << 8) << 16);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode chars from byte buffer using UTF8 encoding. This
|
||||
* operation is performance-critical since a jar file contains a
|
||||
* large number of strings for the name of each file in the
|
||||
* archive. This routine therefore avoids using the expensive
|
||||
* utf8Decoder when decoding is straightforward.
|
||||
*
|
||||
* @param buffer the buffer that contains the encoded character
|
||||
* data
|
||||
* @param pos the index in buffer of the first byte of the encoded
|
||||
* data
|
||||
* @param length the length of the encoded data in number of
|
||||
* bytes.
|
||||
*
|
||||
* @return a String that contains the decoded characters.
|
||||
*/
|
||||
private String decodeChars(byte[] buffer, int pos, int length)
|
||||
throws IOException
|
||||
{
|
||||
String result;
|
||||
int i=length - 1;
|
||||
while ((i >= 0) && (buffer[i] <= 0x7f))
|
||||
{
|
||||
i--;
|
||||
}
|
||||
if (i < 0)
|
||||
{
|
||||
result = new String(buffer, 0, pos, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteBuffer bufferBuffer = ByteBuffer.wrap(buffer, pos, length);
|
||||
if (utf8Decoder == null)
|
||||
utf8Decoder = UTF8CHARSET.newDecoder();
|
||||
utf8Decoder.reset();
|
||||
char [] characters = utf8Decoder.decode(bufferBuffer).array();
|
||||
result = String.valueOf(characters);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
String readString(int length) throws IOException
|
||||
@@ -676,25 +752,26 @@ public class ZipFile implements ZipConstants
|
||||
if (length > end - (bufferOffset + pos))
|
||||
throw new EOFException();
|
||||
|
||||
String result = null;
|
||||
try
|
||||
{
|
||||
if (buffer.length - pos >= length)
|
||||
{
|
||||
String s = new String(buffer, pos, length, "UTF-8");
|
||||
result = decodeChars(buffer, pos, length);
|
||||
pos += length;
|
||||
return s;
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] b = new byte[length];
|
||||
readFully(b);
|
||||
return new String(b, 0, length, "UTF-8");
|
||||
result = decodeChars(b, 0, length);
|
||||
}
|
||||
}
|
||||
catch (UnsupportedEncodingException uee)
|
||||
{
|
||||
throw new AssertionError(uee);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void addDummyByte()
|
||||
|
||||
Reference in New Issue
Block a user