feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
469
jdkSrc/jdk8/java/util/AbstractCollection.java
Normal file
469
jdkSrc/jdk8/java/util/AbstractCollection.java
Normal file
@@ -0,0 +1,469 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* This class provides a skeletal implementation of the <tt>Collection</tt>
|
||||
* interface, to minimize the effort required to implement this interface. <p>
|
||||
*
|
||||
* To implement an unmodifiable collection, the programmer needs only to
|
||||
* extend this class and provide implementations for the <tt>iterator</tt> and
|
||||
* <tt>size</tt> methods. (The iterator returned by the <tt>iterator</tt>
|
||||
* method must implement <tt>hasNext</tt> and <tt>next</tt>.)<p>
|
||||
*
|
||||
* To implement a modifiable collection, the programmer must additionally
|
||||
* override this class's <tt>add</tt> method (which otherwise throws an
|
||||
* <tt>UnsupportedOperationException</tt>), and the iterator returned by the
|
||||
* <tt>iterator</tt> method must additionally implement its <tt>remove</tt>
|
||||
* method.<p>
|
||||
*
|
||||
* The programmer should generally provide a void (no argument) and
|
||||
* <tt>Collection</tt> constructor, as per the recommendation in the
|
||||
* <tt>Collection</tt> interface specification.<p>
|
||||
*
|
||||
* The documentation for each non-abstract method in this class describes its
|
||||
* implementation in detail. Each of these methods may be overridden if
|
||||
* the collection being implemented admits a more efficient implementation.<p>
|
||||
*
|
||||
* This class is a member of the
|
||||
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
|
||||
* Java Collections Framework</a>.
|
||||
*
|
||||
* @author Josh Bloch
|
||||
* @author Neal Gafter
|
||||
* @see Collection
|
||||
* @since 1.2
|
||||
*/
|
||||
|
||||
public abstract class AbstractCollection<E> implements Collection<E> {
|
||||
/**
|
||||
* Sole constructor. (For invocation by subclass constructors, typically
|
||||
* implicit.)
|
||||
*/
|
||||
protected AbstractCollection() {
|
||||
}
|
||||
|
||||
// Query Operations
|
||||
|
||||
/**
|
||||
* Returns an iterator over the elements contained in this collection.
|
||||
*
|
||||
* @return an iterator over the elements contained in this collection
|
||||
*/
|
||||
public abstract Iterator<E> iterator();
|
||||
|
||||
public abstract int size();
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>This implementation returns <tt>size() == 0</tt>.
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>This implementation iterates over the elements in the collection,
|
||||
* checking each element in turn for equality with the specified element.
|
||||
*
|
||||
* @throws ClassCastException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public boolean contains(Object o) {
|
||||
Iterator<E> it = iterator();
|
||||
if (o==null) {
|
||||
while (it.hasNext())
|
||||
if (it.next()==null)
|
||||
return true;
|
||||
} else {
|
||||
while (it.hasNext())
|
||||
if (o.equals(it.next()))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>This implementation returns an array containing all the elements
|
||||
* returned by this collection's iterator, in the same order, stored in
|
||||
* consecutive elements of the array, starting with index {@code 0}.
|
||||
* The length of the returned array is equal to the number of elements
|
||||
* returned by the iterator, even if the size of this collection changes
|
||||
* during iteration, as might happen if the collection permits
|
||||
* concurrent modification during iteration. The {@code size} method is
|
||||
* called only as an optimization hint; the correct result is returned
|
||||
* even if the iterator returns a different number of elements.
|
||||
*
|
||||
* <p>This method is equivalent to:
|
||||
*
|
||||
* <pre> {@code
|
||||
* List<E> list = new ArrayList<E>(size());
|
||||
* for (E e : this)
|
||||
* list.add(e);
|
||||
* return list.toArray();
|
||||
* }</pre>
|
||||
*/
|
||||
public Object[] toArray() {
|
||||
// Estimate size of array; be prepared to see more or fewer elements
|
||||
Object[] r = new Object[size()];
|
||||
Iterator<E> it = iterator();
|
||||
for (int i = 0; i < r.length; i++) {
|
||||
if (! it.hasNext()) // fewer elements than expected
|
||||
return Arrays.copyOf(r, i);
|
||||
r[i] = it.next();
|
||||
}
|
||||
return it.hasNext() ? finishToArray(r, it) : r;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>This implementation returns an array containing all the elements
|
||||
* returned by this collection's iterator in the same order, stored in
|
||||
* consecutive elements of the array, starting with index {@code 0}.
|
||||
* If the number of elements returned by the iterator is too large to
|
||||
* fit into the specified array, then the elements are returned in a
|
||||
* newly allocated array with length equal to the number of elements
|
||||
* returned by the iterator, even if the size of this collection
|
||||
* changes during iteration, as might happen if the collection permits
|
||||
* concurrent modification during iteration. The {@code size} method is
|
||||
* called only as an optimization hint; the correct result is returned
|
||||
* even if the iterator returns a different number of elements.
|
||||
*
|
||||
* <p>This method is equivalent to:
|
||||
*
|
||||
* <pre> {@code
|
||||
* List<E> list = new ArrayList<E>(size());
|
||||
* for (E e : this)
|
||||
* list.add(e);
|
||||
* return list.toArray(a);
|
||||
* }</pre>
|
||||
*
|
||||
* @throws ArrayStoreException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T[] toArray(T[] a) {
|
||||
// Estimate size of array; be prepared to see more or fewer elements
|
||||
int size = size();
|
||||
T[] r = a.length >= size ? a :
|
||||
(T[])java.lang.reflect.Array
|
||||
.newInstance(a.getClass().getComponentType(), size);
|
||||
Iterator<E> it = iterator();
|
||||
|
||||
for (int i = 0; i < r.length; i++) {
|
||||
if (! it.hasNext()) { // fewer elements than expected
|
||||
if (a == r) {
|
||||
r[i] = null; // null-terminate
|
||||
} else if (a.length < i) {
|
||||
return Arrays.copyOf(r, i);
|
||||
} else {
|
||||
System.arraycopy(r, 0, a, 0, i);
|
||||
if (a.length > i) {
|
||||
a[i] = null;
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
r[i] = (T)it.next();
|
||||
}
|
||||
// more elements than expected
|
||||
return it.hasNext() ? finishToArray(r, it) : r;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum size of array to allocate.
|
||||
* Some VMs reserve some header words in an array.
|
||||
* Attempts to allocate larger arrays may result in
|
||||
* OutOfMemoryError: Requested array size exceeds VM limit
|
||||
*/
|
||||
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
|
||||
|
||||
/**
|
||||
* Reallocates the array being used within toArray when the iterator
|
||||
* returned more elements than expected, and finishes filling it from
|
||||
* the iterator.
|
||||
*
|
||||
* @param r the array, replete with previously stored elements
|
||||
* @param it the in-progress iterator over this collection
|
||||
* @return array containing the elements in the given array, plus any
|
||||
* further elements returned by the iterator, trimmed to size
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> T[] finishToArray(T[] r, Iterator<?> it) {
|
||||
int i = r.length;
|
||||
while (it.hasNext()) {
|
||||
int cap = r.length;
|
||||
if (i == cap) {
|
||||
int newCap = cap + (cap >> 1) + 1;
|
||||
// overflow-conscious code
|
||||
if (newCap - MAX_ARRAY_SIZE > 0)
|
||||
newCap = hugeCapacity(cap + 1);
|
||||
r = Arrays.copyOf(r, newCap);
|
||||
}
|
||||
r[i++] = (T)it.next();
|
||||
}
|
||||
// trim if overallocated
|
||||
return (i == r.length) ? r : Arrays.copyOf(r, i);
|
||||
}
|
||||
|
||||
private static int hugeCapacity(int minCapacity) {
|
||||
if (minCapacity < 0) // overflow
|
||||
throw new OutOfMemoryError
|
||||
("Required array size too large");
|
||||
return (minCapacity > MAX_ARRAY_SIZE) ?
|
||||
Integer.MAX_VALUE :
|
||||
MAX_ARRAY_SIZE;
|
||||
}
|
||||
|
||||
// Modification Operations
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>This implementation always throws an
|
||||
* <tt>UnsupportedOperationException</tt>.
|
||||
*
|
||||
* @throws UnsupportedOperationException {@inheritDoc}
|
||||
* @throws ClassCastException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
* @throws IllegalArgumentException {@inheritDoc}
|
||||
* @throws IllegalStateException {@inheritDoc}
|
||||
*/
|
||||
public boolean add(E e) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>This implementation iterates over the collection looking for the
|
||||
* specified element. If it finds the element, it removes the element
|
||||
* from the collection using the iterator's remove method.
|
||||
*
|
||||
* <p>Note that this implementation throws an
|
||||
* <tt>UnsupportedOperationException</tt> if the iterator returned by this
|
||||
* collection's iterator method does not implement the <tt>remove</tt>
|
||||
* method and this collection contains the specified object.
|
||||
*
|
||||
* @throws UnsupportedOperationException {@inheritDoc}
|
||||
* @throws ClassCastException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public boolean remove(Object o) {
|
||||
Iterator<E> it = iterator();
|
||||
if (o==null) {
|
||||
while (it.hasNext()) {
|
||||
if (it.next()==null) {
|
||||
it.remove();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (it.hasNext()) {
|
||||
if (o.equals(it.next())) {
|
||||
it.remove();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Bulk Operations
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>This implementation iterates over the specified collection,
|
||||
* checking each element returned by the iterator in turn to see
|
||||
* if it's contained in this collection. If all elements are so
|
||||
* contained <tt>true</tt> is returned, otherwise <tt>false</tt>.
|
||||
*
|
||||
* @throws ClassCastException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
* @see #contains(Object)
|
||||
*/
|
||||
public boolean containsAll(Collection<?> c) {
|
||||
for (Object e : c)
|
||||
if (!contains(e))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>This implementation iterates over the specified collection, and adds
|
||||
* each object returned by the iterator to this collection, in turn.
|
||||
*
|
||||
* <p>Note that this implementation will throw an
|
||||
* <tt>UnsupportedOperationException</tt> unless <tt>add</tt> is
|
||||
* overridden (assuming the specified collection is non-empty).
|
||||
*
|
||||
* @throws UnsupportedOperationException {@inheritDoc}
|
||||
* @throws ClassCastException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
* @throws IllegalArgumentException {@inheritDoc}
|
||||
* @throws IllegalStateException {@inheritDoc}
|
||||
*
|
||||
* @see #add(Object)
|
||||
*/
|
||||
public boolean addAll(Collection<? extends E> c) {
|
||||
boolean modified = false;
|
||||
for (E e : c)
|
||||
if (add(e))
|
||||
modified = true;
|
||||
return modified;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>This implementation iterates over this collection, checking each
|
||||
* element returned by the iterator in turn to see if it's contained
|
||||
* in the specified collection. If it's so contained, it's removed from
|
||||
* this collection with the iterator's <tt>remove</tt> method.
|
||||
*
|
||||
* <p>Note that this implementation will throw an
|
||||
* <tt>UnsupportedOperationException</tt> if the iterator returned by the
|
||||
* <tt>iterator</tt> method does not implement the <tt>remove</tt> method
|
||||
* and this collection contains one or more elements in common with the
|
||||
* specified collection.
|
||||
*
|
||||
* @throws UnsupportedOperationException {@inheritDoc}
|
||||
* @throws ClassCastException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*
|
||||
* @see #remove(Object)
|
||||
* @see #contains(Object)
|
||||
*/
|
||||
public boolean removeAll(Collection<?> c) {
|
||||
Objects.requireNonNull(c);
|
||||
boolean modified = false;
|
||||
Iterator<?> it = iterator();
|
||||
while (it.hasNext()) {
|
||||
if (c.contains(it.next())) {
|
||||
it.remove();
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>This implementation iterates over this collection, checking each
|
||||
* element returned by the iterator in turn to see if it's contained
|
||||
* in the specified collection. If it's not so contained, it's removed
|
||||
* from this collection with the iterator's <tt>remove</tt> method.
|
||||
*
|
||||
* <p>Note that this implementation will throw an
|
||||
* <tt>UnsupportedOperationException</tt> if the iterator returned by the
|
||||
* <tt>iterator</tt> method does not implement the <tt>remove</tt> method
|
||||
* and this collection contains one or more elements not present in the
|
||||
* specified collection.
|
||||
*
|
||||
* @throws UnsupportedOperationException {@inheritDoc}
|
||||
* @throws ClassCastException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*
|
||||
* @see #remove(Object)
|
||||
* @see #contains(Object)
|
||||
*/
|
||||
public boolean retainAll(Collection<?> c) {
|
||||
Objects.requireNonNull(c);
|
||||
boolean modified = false;
|
||||
Iterator<E> it = iterator();
|
||||
while (it.hasNext()) {
|
||||
if (!c.contains(it.next())) {
|
||||
it.remove();
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>This implementation iterates over this collection, removing each
|
||||
* element using the <tt>Iterator.remove</tt> operation. Most
|
||||
* implementations will probably choose to override this method for
|
||||
* efficiency.
|
||||
*
|
||||
* <p>Note that this implementation will throw an
|
||||
* <tt>UnsupportedOperationException</tt> if the iterator returned by this
|
||||
* collection's <tt>iterator</tt> method does not implement the
|
||||
* <tt>remove</tt> method and this collection is non-empty.
|
||||
*
|
||||
* @throws UnsupportedOperationException {@inheritDoc}
|
||||
*/
|
||||
public void clear() {
|
||||
Iterator<E> it = iterator();
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// String conversion
|
||||
|
||||
/**
|
||||
* Returns a string representation of this collection. The string
|
||||
* representation consists of a list of the collection's elements in the
|
||||
* order they are returned by its iterator, enclosed in square brackets
|
||||
* (<tt>"[]"</tt>). Adjacent elements are separated by the characters
|
||||
* <tt>", "</tt> (comma and space). Elements are converted to strings as
|
||||
* by {@link String#valueOf(Object)}.
|
||||
*
|
||||
* @return a string representation of this collection
|
||||
*/
|
||||
public String toString() {
|
||||
Iterator<E> it = iterator();
|
||||
if (! it.hasNext())
|
||||
return "[]";
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append('[');
|
||||
for (;;) {
|
||||
E e = it.next();
|
||||
sb.append(e == this ? "(this Collection)" : e);
|
||||
if (! it.hasNext())
|
||||
return sb.append(']').toString();
|
||||
sb.append(',').append(' ');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
781
jdkSrc/jdk8/java/util/AbstractList.java
Normal file
781
jdkSrc/jdk8/java/util/AbstractList.java
Normal file
@@ -0,0 +1,781 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* This class provides a skeletal implementation of the {@link List}
|
||||
* interface to minimize the effort required to implement this interface
|
||||
* backed by a "random access" data store (such as an array). For sequential
|
||||
* access data (such as a linked list), {@link AbstractSequentialList} should
|
||||
* be used in preference to this class.
|
||||
*
|
||||
* <p>To implement an unmodifiable list, the programmer needs only to extend
|
||||
* this class and provide implementations for the {@link #get(int)} and
|
||||
* {@link List#size() size()} methods.
|
||||
*
|
||||
* <p>To implement a modifiable list, the programmer must additionally
|
||||
* override the {@link #set(int, Object) set(int, E)} method (which otherwise
|
||||
* throws an {@code UnsupportedOperationException}). If the list is
|
||||
* variable-size the programmer must additionally override the
|
||||
* {@link #add(int, Object) add(int, E)} and {@link #remove(int)} methods.
|
||||
*
|
||||
* <p>The programmer should generally provide a void (no argument) and collection
|
||||
* constructor, as per the recommendation in the {@link Collection} interface
|
||||
* specification.
|
||||
*
|
||||
* <p>Unlike the other abstract collection implementations, the programmer does
|
||||
* <i>not</i> have to provide an iterator implementation; the iterator and
|
||||
* list iterator are implemented by this class, on top of the "random access"
|
||||
* methods:
|
||||
* {@link #get(int)},
|
||||
* {@link #set(int, Object) set(int, E)},
|
||||
* {@link #add(int, Object) add(int, E)} and
|
||||
* {@link #remove(int)}.
|
||||
*
|
||||
* <p>The documentation for each non-abstract method in this class describes its
|
||||
* implementation in detail. Each of these methods may be overridden if the
|
||||
* collection being implemented admits a more efficient implementation.
|
||||
*
|
||||
* <p>This class is a member of the
|
||||
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
|
||||
* Java Collections Framework</a>.
|
||||
*
|
||||
* @author Josh Bloch
|
||||
* @author Neal Gafter
|
||||
* @since 1.2
|
||||
*/
|
||||
|
||||
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
|
||||
/**
|
||||
* Sole constructor. (For invocation by subclass constructors, typically
|
||||
* implicit.)
|
||||
*/
|
||||
protected AbstractList() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the specified element to the end of this list (optional
|
||||
* operation).
|
||||
*
|
||||
* <p>Lists that support this operation may place limitations on what
|
||||
* elements may be added to this list. In particular, some
|
||||
* lists will refuse to add null elements, and others will impose
|
||||
* restrictions on the type of elements that may be added. List
|
||||
* classes should clearly specify in their documentation any restrictions
|
||||
* on what elements may be added.
|
||||
*
|
||||
* <p>This implementation calls {@code add(size(), e)}.
|
||||
*
|
||||
* <p>Note that this implementation throws an
|
||||
* {@code UnsupportedOperationException} unless
|
||||
* {@link #add(int, Object) add(int, E)} is overridden.
|
||||
*
|
||||
* @param e element to be appended to this list
|
||||
* @return {@code true} (as specified by {@link Collection#add})
|
||||
* @throws UnsupportedOperationException if the {@code add} operation
|
||||
* is not supported by this list
|
||||
* @throws ClassCastException if the class of the specified element
|
||||
* prevents it from being added to this list
|
||||
* @throws NullPointerException if the specified element is null and this
|
||||
* list does not permit null elements
|
||||
* @throws IllegalArgumentException if some property of this element
|
||||
* prevents it from being added to this list
|
||||
*/
|
||||
public boolean add(E e) {
|
||||
add(size(), e);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @throws IndexOutOfBoundsException {@inheritDoc}
|
||||
*/
|
||||
abstract public E get(int index);
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>This implementation always throws an
|
||||
* {@code UnsupportedOperationException}.
|
||||
*
|
||||
* @throws UnsupportedOperationException {@inheritDoc}
|
||||
* @throws ClassCastException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
* @throws IllegalArgumentException {@inheritDoc}
|
||||
* @throws IndexOutOfBoundsException {@inheritDoc}
|
||||
*/
|
||||
public E set(int index, E element) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>This implementation always throws an
|
||||
* {@code UnsupportedOperationException}.
|
||||
*
|
||||
* @throws UnsupportedOperationException {@inheritDoc}
|
||||
* @throws ClassCastException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
* @throws IllegalArgumentException {@inheritDoc}
|
||||
* @throws IndexOutOfBoundsException {@inheritDoc}
|
||||
*/
|
||||
public void add(int index, E element) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>This implementation always throws an
|
||||
* {@code UnsupportedOperationException}.
|
||||
*
|
||||
* @throws UnsupportedOperationException {@inheritDoc}
|
||||
* @throws IndexOutOfBoundsException {@inheritDoc}
|
||||
*/
|
||||
public E remove(int index) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
// Search Operations
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>This implementation first gets a list iterator (with
|
||||
* {@code listIterator()}). Then, it iterates over the list until the
|
||||
* specified element is found or the end of the list is reached.
|
||||
*
|
||||
* @throws ClassCastException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public int indexOf(Object o) {
|
||||
ListIterator<E> it = listIterator();
|
||||
if (o==null) {
|
||||
while (it.hasNext())
|
||||
if (it.next()==null)
|
||||
return it.previousIndex();
|
||||
} else {
|
||||
while (it.hasNext())
|
||||
if (o.equals(it.next()))
|
||||
return it.previousIndex();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>This implementation first gets a list iterator that points to the end
|
||||
* of the list (with {@code listIterator(size())}). Then, it iterates
|
||||
* backwards over the list until the specified element is found, or the
|
||||
* beginning of the list is reached.
|
||||
*
|
||||
* @throws ClassCastException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public int lastIndexOf(Object o) {
|
||||
ListIterator<E> it = listIterator(size());
|
||||
if (o==null) {
|
||||
while (it.hasPrevious())
|
||||
if (it.previous()==null)
|
||||
return it.nextIndex();
|
||||
} else {
|
||||
while (it.hasPrevious())
|
||||
if (o.equals(it.previous()))
|
||||
return it.nextIndex();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// Bulk Operations
|
||||
|
||||
/**
|
||||
* Removes all of the elements from this list (optional operation).
|
||||
* The list will be empty after this call returns.
|
||||
*
|
||||
* <p>This implementation calls {@code removeRange(0, size())}.
|
||||
*
|
||||
* <p>Note that this implementation throws an
|
||||
* {@code UnsupportedOperationException} unless {@code remove(int
|
||||
* index)} or {@code removeRange(int fromIndex, int toIndex)} is
|
||||
* overridden.
|
||||
*
|
||||
* @throws UnsupportedOperationException if the {@code clear} operation
|
||||
* is not supported by this list
|
||||
*/
|
||||
public void clear() {
|
||||
removeRange(0, size());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>This implementation gets an iterator over the specified collection
|
||||
* and iterates over it, inserting the elements obtained from the
|
||||
* iterator into this list at the appropriate position, one at a time,
|
||||
* using {@code add(int, E)}.
|
||||
* Many implementations will override this method for efficiency.
|
||||
*
|
||||
* <p>Note that this implementation throws an
|
||||
* {@code UnsupportedOperationException} unless
|
||||
* {@link #add(int, Object) add(int, E)} is overridden.
|
||||
*
|
||||
* @throws UnsupportedOperationException {@inheritDoc}
|
||||
* @throws ClassCastException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
* @throws IllegalArgumentException {@inheritDoc}
|
||||
* @throws IndexOutOfBoundsException {@inheritDoc}
|
||||
*/
|
||||
public boolean addAll(int index, Collection<? extends E> c) {
|
||||
rangeCheckForAdd(index);
|
||||
boolean modified = false;
|
||||
for (E e : c) {
|
||||
add(index++, e);
|
||||
modified = true;
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
|
||||
// Iterators
|
||||
|
||||
/**
|
||||
* Returns an iterator over the elements in this list in proper sequence.
|
||||
*
|
||||
* <p>This implementation returns a straightforward implementation of the
|
||||
* iterator interface, relying on the backing list's {@code size()},
|
||||
* {@code get(int)}, and {@code remove(int)} methods.
|
||||
*
|
||||
* <p>Note that the iterator returned by this method will throw an
|
||||
* {@link UnsupportedOperationException} in response to its
|
||||
* {@code remove} method unless the list's {@code remove(int)} method is
|
||||
* overridden.
|
||||
*
|
||||
* <p>This implementation can be made to throw runtime exceptions in the
|
||||
* face of concurrent modification, as described in the specification
|
||||
* for the (protected) {@link #modCount} field.
|
||||
*
|
||||
* @return an iterator over the elements in this list in proper sequence
|
||||
*/
|
||||
public Iterator<E> iterator() {
|
||||
return new Itr();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>This implementation returns {@code listIterator(0)}.
|
||||
*
|
||||
* @see #listIterator(int)
|
||||
*/
|
||||
public ListIterator<E> listIterator() {
|
||||
return listIterator(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>This implementation returns a straightforward implementation of the
|
||||
* {@code ListIterator} interface that extends the implementation of the
|
||||
* {@code Iterator} interface returned by the {@code iterator()} method.
|
||||
* The {@code ListIterator} implementation relies on the backing list's
|
||||
* {@code get(int)}, {@code set(int, E)}, {@code add(int, E)}
|
||||
* and {@code remove(int)} methods.
|
||||
*
|
||||
* <p>Note that the list iterator returned by this implementation will
|
||||
* throw an {@link UnsupportedOperationException} in response to its
|
||||
* {@code remove}, {@code set} and {@code add} methods unless the
|
||||
* list's {@code remove(int)}, {@code set(int, E)}, and
|
||||
* {@code add(int, E)} methods are overridden.
|
||||
*
|
||||
* <p>This implementation can be made to throw runtime exceptions in the
|
||||
* face of concurrent modification, as described in the specification for
|
||||
* the (protected) {@link #modCount} field.
|
||||
*
|
||||
* @throws IndexOutOfBoundsException {@inheritDoc}
|
||||
*/
|
||||
public ListIterator<E> listIterator(final int index) {
|
||||
rangeCheckForAdd(index);
|
||||
|
||||
return new ListItr(index);
|
||||
}
|
||||
|
||||
private class Itr implements Iterator<E> {
|
||||
/**
|
||||
* Index of element to be returned by subsequent call to next.
|
||||
*/
|
||||
int cursor = 0;
|
||||
|
||||
/**
|
||||
* Index of element returned by most recent call to next or
|
||||
* previous. Reset to -1 if this element is deleted by a call
|
||||
* to remove.
|
||||
*/
|
||||
int lastRet = -1;
|
||||
|
||||
/**
|
||||
* The modCount value that the iterator believes that the backing
|
||||
* List should have. If this expectation is violated, the iterator
|
||||
* has detected concurrent modification.
|
||||
*/
|
||||
int expectedModCount = modCount;
|
||||
|
||||
public boolean hasNext() {
|
||||
return cursor != size();
|
||||
}
|
||||
|
||||
public E next() {
|
||||
checkForComodification();
|
||||
try {
|
||||
int i = cursor;
|
||||
E next = get(i);
|
||||
lastRet = i;
|
||||
cursor = i + 1;
|
||||
return next;
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
checkForComodification();
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
if (lastRet < 0)
|
||||
throw new IllegalStateException();
|
||||
checkForComodification();
|
||||
|
||||
try {
|
||||
AbstractList.this.remove(lastRet);
|
||||
if (lastRet < cursor)
|
||||
cursor--;
|
||||
lastRet = -1;
|
||||
expectedModCount = modCount;
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
}
|
||||
|
||||
final void checkForComodification() {
|
||||
if (modCount != expectedModCount)
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
}
|
||||
|
||||
private class ListItr extends Itr implements ListIterator<E> {
|
||||
ListItr(int index) {
|
||||
cursor = index;
|
||||
}
|
||||
|
||||
public boolean hasPrevious() {
|
||||
return cursor != 0;
|
||||
}
|
||||
|
||||
public E previous() {
|
||||
checkForComodification();
|
||||
try {
|
||||
int i = cursor - 1;
|
||||
E previous = get(i);
|
||||
lastRet = cursor = i;
|
||||
return previous;
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
checkForComodification();
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
}
|
||||
|
||||
public int nextIndex() {
|
||||
return cursor;
|
||||
}
|
||||
|
||||
public int previousIndex() {
|
||||
return cursor-1;
|
||||
}
|
||||
|
||||
public void set(E e) {
|
||||
if (lastRet < 0)
|
||||
throw new IllegalStateException();
|
||||
checkForComodification();
|
||||
|
||||
try {
|
||||
AbstractList.this.set(lastRet, e);
|
||||
expectedModCount = modCount;
|
||||
} catch (IndexOutOfBoundsException ex) {
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
}
|
||||
|
||||
public void add(E e) {
|
||||
checkForComodification();
|
||||
|
||||
try {
|
||||
int i = cursor;
|
||||
AbstractList.this.add(i, e);
|
||||
lastRet = -1;
|
||||
cursor = i + 1;
|
||||
expectedModCount = modCount;
|
||||
} catch (IndexOutOfBoundsException ex) {
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>This implementation returns a list that subclasses
|
||||
* {@code AbstractList}. The subclass stores, in private fields, the
|
||||
* offset of the subList within the backing list, the size of the subList
|
||||
* (which can change over its lifetime), and the expected
|
||||
* {@code modCount} value of the backing list. There are two variants
|
||||
* of the subclass, one of which implements {@code RandomAccess}.
|
||||
* If this list implements {@code RandomAccess} the returned list will
|
||||
* be an instance of the subclass that implements {@code RandomAccess}.
|
||||
*
|
||||
* <p>The subclass's {@code set(int, E)}, {@code get(int)},
|
||||
* {@code add(int, E)}, {@code remove(int)}, {@code addAll(int,
|
||||
* Collection)} and {@code removeRange(int, int)} methods all
|
||||
* delegate to the corresponding methods on the backing abstract list,
|
||||
* after bounds-checking the index and adjusting for the offset. The
|
||||
* {@code addAll(Collection c)} method merely returns {@code addAll(size,
|
||||
* c)}.
|
||||
*
|
||||
* <p>The {@code listIterator(int)} method returns a "wrapper object"
|
||||
* over a list iterator on the backing list, which is created with the
|
||||
* corresponding method on the backing list. The {@code iterator} method
|
||||
* merely returns {@code listIterator()}, and the {@code size} method
|
||||
* merely returns the subclass's {@code size} field.
|
||||
*
|
||||
* <p>All methods first check to see if the actual {@code modCount} of
|
||||
* the backing list is equal to its expected value, and throw a
|
||||
* {@code ConcurrentModificationException} if it is not.
|
||||
*
|
||||
* @throws IndexOutOfBoundsException if an endpoint index value is out of range
|
||||
* {@code (fromIndex < 0 || toIndex > size)}
|
||||
* @throws IllegalArgumentException if the endpoint indices are out of order
|
||||
* {@code (fromIndex > toIndex)}
|
||||
*/
|
||||
public List<E> subList(int fromIndex, int toIndex) {
|
||||
return (this instanceof RandomAccess ?
|
||||
new RandomAccessSubList<>(this, fromIndex, toIndex) :
|
||||
new SubList<>(this, fromIndex, toIndex));
|
||||
}
|
||||
|
||||
// Comparison and hashing
|
||||
|
||||
/**
|
||||
* Compares the specified object with this list for equality. Returns
|
||||
* {@code true} if and only if the specified object is also a list, both
|
||||
* lists have the same size, and all corresponding pairs of elements in
|
||||
* the two lists are <i>equal</i>. (Two elements {@code e1} and
|
||||
* {@code e2} are <i>equal</i> if {@code (e1==null ? e2==null :
|
||||
* e1.equals(e2))}.) In other words, two lists are defined to be
|
||||
* equal if they contain the same elements in the same order.<p>
|
||||
*
|
||||
* This implementation first checks if the specified object is this
|
||||
* list. If so, it returns {@code true}; if not, it checks if the
|
||||
* specified object is a list. If not, it returns {@code false}; if so,
|
||||
* it iterates over both lists, comparing corresponding pairs of elements.
|
||||
* If any comparison returns {@code false}, this method returns
|
||||
* {@code false}. If either iterator runs out of elements before the
|
||||
* other it returns {@code false} (as the lists are of unequal length);
|
||||
* otherwise it returns {@code true} when the iterations complete.
|
||||
*
|
||||
* @param o the object to be compared for equality with this list
|
||||
* @return {@code true} if the specified object is equal to this list
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (o == this)
|
||||
return true;
|
||||
if (!(o instanceof List))
|
||||
return false;
|
||||
|
||||
ListIterator<E> e1 = listIterator();
|
||||
ListIterator<?> e2 = ((List<?>) o).listIterator();
|
||||
while (e1.hasNext() && e2.hasNext()) {
|
||||
E o1 = e1.next();
|
||||
Object o2 = e2.next();
|
||||
if (!(o1==null ? o2==null : o1.equals(o2)))
|
||||
return false;
|
||||
}
|
||||
return !(e1.hasNext() || e2.hasNext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code value for this list.
|
||||
*
|
||||
* <p>This implementation uses exactly the code that is used to define the
|
||||
* list hash function in the documentation for the {@link List#hashCode}
|
||||
* method.
|
||||
*
|
||||
* @return the hash code value for this list
|
||||
*/
|
||||
public int hashCode() {
|
||||
int hashCode = 1;
|
||||
for (E e : this)
|
||||
hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes from this list all of the elements whose index is between
|
||||
* {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
|
||||
* Shifts any succeeding elements to the left (reduces their index).
|
||||
* This call shortens the list by {@code (toIndex - fromIndex)} elements.
|
||||
* (If {@code toIndex==fromIndex}, this operation has no effect.)
|
||||
*
|
||||
* <p>This method is called by the {@code clear} operation on this list
|
||||
* and its subLists. Overriding this method to take advantage of
|
||||
* the internals of the list implementation can <i>substantially</i>
|
||||
* improve the performance of the {@code clear} operation on this list
|
||||
* and its subLists.
|
||||
*
|
||||
* <p>This implementation gets a list iterator positioned before
|
||||
* {@code fromIndex}, and repeatedly calls {@code ListIterator.next}
|
||||
* followed by {@code ListIterator.remove} until the entire range has
|
||||
* been removed. <b>Note: if {@code ListIterator.remove} requires linear
|
||||
* time, this implementation requires quadratic time.</b>
|
||||
*
|
||||
* @param fromIndex index of first element to be removed
|
||||
* @param toIndex index after last element to be removed
|
||||
*/
|
||||
protected void removeRange(int fromIndex, int toIndex) {
|
||||
ListIterator<E> it = listIterator(fromIndex);
|
||||
for (int i=0, n=toIndex-fromIndex; i<n; i++) {
|
||||
it.next();
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of times this list has been <i>structurally modified</i>.
|
||||
* Structural modifications are those that change the size of the
|
||||
* list, or otherwise perturb it in such a fashion that iterations in
|
||||
* progress may yield incorrect results.
|
||||
*
|
||||
* <p>This field is used by the iterator and list iterator implementation
|
||||
* returned by the {@code iterator} and {@code listIterator} methods.
|
||||
* If the value of this field changes unexpectedly, the iterator (or list
|
||||
* iterator) will throw a {@code ConcurrentModificationException} in
|
||||
* response to the {@code next}, {@code remove}, {@code previous},
|
||||
* {@code set} or {@code add} operations. This provides
|
||||
* <i>fail-fast</i> behavior, rather than non-deterministic behavior in
|
||||
* the face of concurrent modification during iteration.
|
||||
*
|
||||
* <p><b>Use of this field by subclasses is optional.</b> If a subclass
|
||||
* wishes to provide fail-fast iterators (and list iterators), then it
|
||||
* merely has to increment this field in its {@code add(int, E)} and
|
||||
* {@code remove(int)} methods (and any other methods that it overrides
|
||||
* that result in structural modifications to the list). A single call to
|
||||
* {@code add(int, E)} or {@code remove(int)} must add no more than
|
||||
* one to this field, or the iterators (and list iterators) will throw
|
||||
* bogus {@code ConcurrentModificationExceptions}. If an implementation
|
||||
* does not wish to provide fail-fast iterators, this field may be
|
||||
* ignored.
|
||||
*/
|
||||
protected transient int modCount = 0;
|
||||
|
||||
private void rangeCheckForAdd(int index) {
|
||||
if (index < 0 || index > size())
|
||||
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
|
||||
}
|
||||
|
||||
private String outOfBoundsMsg(int index) {
|
||||
return "Index: "+index+", Size: "+size();
|
||||
}
|
||||
}
|
||||
|
||||
class SubList<E> extends AbstractList<E> {
|
||||
private final AbstractList<E> l;
|
||||
private final int offset;
|
||||
private int size;
|
||||
|
||||
SubList(AbstractList<E> list, int fromIndex, int toIndex) {
|
||||
if (fromIndex < 0)
|
||||
throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
|
||||
if (toIndex > list.size())
|
||||
throw new IndexOutOfBoundsException("toIndex = " + toIndex);
|
||||
if (fromIndex > toIndex)
|
||||
throw new IllegalArgumentException("fromIndex(" + fromIndex +
|
||||
") > toIndex(" + toIndex + ")");
|
||||
l = list;
|
||||
offset = fromIndex;
|
||||
size = toIndex - fromIndex;
|
||||
this.modCount = l.modCount;
|
||||
}
|
||||
|
||||
public E set(int index, E element) {
|
||||
rangeCheck(index);
|
||||
checkForComodification();
|
||||
return l.set(index+offset, element);
|
||||
}
|
||||
|
||||
public E get(int index) {
|
||||
rangeCheck(index);
|
||||
checkForComodification();
|
||||
return l.get(index+offset);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
checkForComodification();
|
||||
return size;
|
||||
}
|
||||
|
||||
public void add(int index, E element) {
|
||||
rangeCheckForAdd(index);
|
||||
checkForComodification();
|
||||
l.add(index+offset, element);
|
||||
this.modCount = l.modCount;
|
||||
size++;
|
||||
}
|
||||
|
||||
public E remove(int index) {
|
||||
rangeCheck(index);
|
||||
checkForComodification();
|
||||
E result = l.remove(index+offset);
|
||||
this.modCount = l.modCount;
|
||||
size--;
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void removeRange(int fromIndex, int toIndex) {
|
||||
checkForComodification();
|
||||
l.removeRange(fromIndex+offset, toIndex+offset);
|
||||
this.modCount = l.modCount;
|
||||
size -= (toIndex-fromIndex);
|
||||
}
|
||||
|
||||
public boolean addAll(Collection<? extends E> c) {
|
||||
return addAll(size, c);
|
||||
}
|
||||
|
||||
public boolean addAll(int index, Collection<? extends E> c) {
|
||||
rangeCheckForAdd(index);
|
||||
int cSize = c.size();
|
||||
if (cSize==0)
|
||||
return false;
|
||||
|
||||
checkForComodification();
|
||||
l.addAll(offset+index, c);
|
||||
this.modCount = l.modCount;
|
||||
size += cSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
public Iterator<E> iterator() {
|
||||
return listIterator();
|
||||
}
|
||||
|
||||
public ListIterator<E> listIterator(final int index) {
|
||||
checkForComodification();
|
||||
rangeCheckForAdd(index);
|
||||
|
||||
return new ListIterator<E>() {
|
||||
private final ListIterator<E> i = l.listIterator(index+offset);
|
||||
|
||||
public boolean hasNext() {
|
||||
return nextIndex() < size;
|
||||
}
|
||||
|
||||
public E next() {
|
||||
if (hasNext())
|
||||
return i.next();
|
||||
else
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
public boolean hasPrevious() {
|
||||
return previousIndex() >= 0;
|
||||
}
|
||||
|
||||
public E previous() {
|
||||
if (hasPrevious())
|
||||
return i.previous();
|
||||
else
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
public int nextIndex() {
|
||||
return i.nextIndex() - offset;
|
||||
}
|
||||
|
||||
public int previousIndex() {
|
||||
return i.previousIndex() - offset;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
i.remove();
|
||||
SubList.this.modCount = l.modCount;
|
||||
size--;
|
||||
}
|
||||
|
||||
public void set(E e) {
|
||||
i.set(e);
|
||||
}
|
||||
|
||||
public void add(E e) {
|
||||
i.add(e);
|
||||
SubList.this.modCount = l.modCount;
|
||||
size++;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public List<E> subList(int fromIndex, int toIndex) {
|
||||
return new SubList<>(this, fromIndex, toIndex);
|
||||
}
|
||||
|
||||
private void rangeCheck(int index) {
|
||||
if (index < 0 || index >= size)
|
||||
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
|
||||
}
|
||||
|
||||
private void rangeCheckForAdd(int index) {
|
||||
if (index < 0 || index > size)
|
||||
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
|
||||
}
|
||||
|
||||
private String outOfBoundsMsg(int index) {
|
||||
return "Index: "+index+", Size: "+size;
|
||||
}
|
||||
|
||||
private void checkForComodification() {
|
||||
if (this.modCount != l.modCount)
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
}
|
||||
|
||||
class RandomAccessSubList<E> extends SubList<E> implements RandomAccess {
|
||||
RandomAccessSubList(AbstractList<E> list, int fromIndex, int toIndex) {
|
||||
super(list, fromIndex, toIndex);
|
||||
}
|
||||
|
||||
public List<E> subList(int fromIndex, int toIndex) {
|
||||
return new RandomAccessSubList<>(this, fromIndex, toIndex);
|
||||
}
|
||||
}
|
||||
860
jdkSrc/jdk8/java/util/AbstractMap.java
Normal file
860
jdkSrc/jdk8/java/util/AbstractMap.java
Normal file
@@ -0,0 +1,860 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* This class provides a skeletal implementation of the <tt>Map</tt>
|
||||
* interface, to minimize the effort required to implement this interface.
|
||||
*
|
||||
* <p>To implement an unmodifiable map, the programmer needs only to extend this
|
||||
* class and provide an implementation for the <tt>entrySet</tt> method, which
|
||||
* returns a set-view of the map's mappings. Typically, the returned set
|
||||
* will, in turn, be implemented atop <tt>AbstractSet</tt>. This set should
|
||||
* not support the <tt>add</tt> or <tt>remove</tt> methods, and its iterator
|
||||
* should not support the <tt>remove</tt> method.
|
||||
*
|
||||
* <p>To implement a modifiable map, the programmer must additionally override
|
||||
* this class's <tt>put</tt> method (which otherwise throws an
|
||||
* <tt>UnsupportedOperationException</tt>), and the iterator returned by
|
||||
* <tt>entrySet().iterator()</tt> must additionally implement its
|
||||
* <tt>remove</tt> method.
|
||||
*
|
||||
* <p>The programmer should generally provide a void (no argument) and map
|
||||
* constructor, as per the recommendation in the <tt>Map</tt> interface
|
||||
* specification.
|
||||
*
|
||||
* <p>The documentation for each non-abstract method in this class describes its
|
||||
* implementation in detail. Each of these methods may be overridden if the
|
||||
* map being implemented admits a more efficient implementation.
|
||||
*
|
||||
* <p>This class is a member of the
|
||||
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
|
||||
* Java Collections Framework</a>.
|
||||
*
|
||||
* @param <K> the type of keys maintained by this map
|
||||
* @param <V> the type of mapped values
|
||||
*
|
||||
* @author Josh Bloch
|
||||
* @author Neal Gafter
|
||||
* @see Map
|
||||
* @see Collection
|
||||
* @since 1.2
|
||||
*/
|
||||
|
||||
public abstract class AbstractMap<K,V> implements Map<K,V> {
|
||||
/**
|
||||
* Sole constructor. (For invocation by subclass constructors, typically
|
||||
* implicit.)
|
||||
*/
|
||||
protected AbstractMap() {
|
||||
}
|
||||
|
||||
// Query Operations
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @implSpec
|
||||
* This implementation returns <tt>entrySet().size()</tt>.
|
||||
*/
|
||||
public int size() {
|
||||
return entrySet().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @implSpec
|
||||
* This implementation returns <tt>size() == 0</tt>.
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @implSpec
|
||||
* This implementation iterates over <tt>entrySet()</tt> searching
|
||||
* for an entry with the specified value. If such an entry is found,
|
||||
* <tt>true</tt> is returned. If the iteration terminates without
|
||||
* finding such an entry, <tt>false</tt> is returned. Note that this
|
||||
* implementation requires linear time in the size of the map.
|
||||
*
|
||||
* @throws ClassCastException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public boolean containsValue(Object value) {
|
||||
Iterator<Entry<K,V>> i = entrySet().iterator();
|
||||
if (value==null) {
|
||||
while (i.hasNext()) {
|
||||
Entry<K,V> e = i.next();
|
||||
if (e.getValue()==null)
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
while (i.hasNext()) {
|
||||
Entry<K,V> e = i.next();
|
||||
if (value.equals(e.getValue()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @implSpec
|
||||
* This implementation iterates over <tt>entrySet()</tt> searching
|
||||
* for an entry with the specified key. If such an entry is found,
|
||||
* <tt>true</tt> is returned. If the iteration terminates without
|
||||
* finding such an entry, <tt>false</tt> is returned. Note that this
|
||||
* implementation requires linear time in the size of the map; many
|
||||
* implementations will override this method.
|
||||
*
|
||||
* @throws ClassCastException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public boolean containsKey(Object key) {
|
||||
Iterator<Map.Entry<K,V>> i = entrySet().iterator();
|
||||
if (key==null) {
|
||||
while (i.hasNext()) {
|
||||
Entry<K,V> e = i.next();
|
||||
if (e.getKey()==null)
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
while (i.hasNext()) {
|
||||
Entry<K,V> e = i.next();
|
||||
if (key.equals(e.getKey()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @implSpec
|
||||
* This implementation iterates over <tt>entrySet()</tt> searching
|
||||
* for an entry with the specified key. If such an entry is found,
|
||||
* the entry's value is returned. If the iteration terminates without
|
||||
* finding such an entry, <tt>null</tt> is returned. Note that this
|
||||
* implementation requires linear time in the size of the map; many
|
||||
* implementations will override this method.
|
||||
*
|
||||
* @throws ClassCastException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public V get(Object key) {
|
||||
Iterator<Entry<K,V>> i = entrySet().iterator();
|
||||
if (key==null) {
|
||||
while (i.hasNext()) {
|
||||
Entry<K,V> e = i.next();
|
||||
if (e.getKey()==null)
|
||||
return e.getValue();
|
||||
}
|
||||
} else {
|
||||
while (i.hasNext()) {
|
||||
Entry<K,V> e = i.next();
|
||||
if (key.equals(e.getKey()))
|
||||
return e.getValue();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// Modification Operations
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @implSpec
|
||||
* This implementation always throws an
|
||||
* <tt>UnsupportedOperationException</tt>.
|
||||
*
|
||||
* @throws UnsupportedOperationException {@inheritDoc}
|
||||
* @throws ClassCastException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
* @throws IllegalArgumentException {@inheritDoc}
|
||||
*/
|
||||
public V put(K key, V value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @implSpec
|
||||
* This implementation iterates over <tt>entrySet()</tt> searching for an
|
||||
* entry with the specified key. If such an entry is found, its value is
|
||||
* obtained with its <tt>getValue</tt> operation, the entry is removed
|
||||
* from the collection (and the backing map) with the iterator's
|
||||
* <tt>remove</tt> operation, and the saved value is returned. If the
|
||||
* iteration terminates without finding such an entry, <tt>null</tt> is
|
||||
* returned. Note that this implementation requires linear time in the
|
||||
* size of the map; many implementations will override this method.
|
||||
*
|
||||
* <p>Note that this implementation throws an
|
||||
* <tt>UnsupportedOperationException</tt> if the <tt>entrySet</tt>
|
||||
* iterator does not support the <tt>remove</tt> method and this map
|
||||
* contains a mapping for the specified key.
|
||||
*
|
||||
* @throws UnsupportedOperationException {@inheritDoc}
|
||||
* @throws ClassCastException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public V remove(Object key) {
|
||||
Iterator<Entry<K,V>> i = entrySet().iterator();
|
||||
Entry<K,V> correctEntry = null;
|
||||
if (key==null) {
|
||||
while (correctEntry==null && i.hasNext()) {
|
||||
Entry<K,V> e = i.next();
|
||||
if (e.getKey()==null)
|
||||
correctEntry = e;
|
||||
}
|
||||
} else {
|
||||
while (correctEntry==null && i.hasNext()) {
|
||||
Entry<K,V> e = i.next();
|
||||
if (key.equals(e.getKey()))
|
||||
correctEntry = e;
|
||||
}
|
||||
}
|
||||
|
||||
V oldValue = null;
|
||||
if (correctEntry !=null) {
|
||||
oldValue = correctEntry.getValue();
|
||||
i.remove();
|
||||
}
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
|
||||
// Bulk Operations
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @implSpec
|
||||
* This implementation iterates over the specified map's
|
||||
* <tt>entrySet()</tt> collection, and calls this map's <tt>put</tt>
|
||||
* operation once for each entry returned by the iteration.
|
||||
*
|
||||
* <p>Note that this implementation throws an
|
||||
* <tt>UnsupportedOperationException</tt> if this map does not support
|
||||
* the <tt>put</tt> operation and the specified map is nonempty.
|
||||
*
|
||||
* @throws UnsupportedOperationException {@inheritDoc}
|
||||
* @throws ClassCastException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
* @throws IllegalArgumentException {@inheritDoc}
|
||||
*/
|
||||
public void putAll(Map<? extends K, ? extends V> m) {
|
||||
for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
|
||||
put(e.getKey(), e.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @implSpec
|
||||
* This implementation calls <tt>entrySet().clear()</tt>.
|
||||
*
|
||||
* <p>Note that this implementation throws an
|
||||
* <tt>UnsupportedOperationException</tt> if the <tt>entrySet</tt>
|
||||
* does not support the <tt>clear</tt> operation.
|
||||
*
|
||||
* @throws UnsupportedOperationException {@inheritDoc}
|
||||
*/
|
||||
public void clear() {
|
||||
entrySet().clear();
|
||||
}
|
||||
|
||||
|
||||
// Views
|
||||
|
||||
/**
|
||||
* Each of these fields are initialized to contain an instance of the
|
||||
* appropriate view the first time this view is requested. The views are
|
||||
* stateless, so there's no reason to create more than one of each.
|
||||
*
|
||||
* <p>Since there is no synchronization performed while accessing these fields,
|
||||
* it is expected that java.util.Map view classes using these fields have
|
||||
* no non-final fields (or any fields at all except for outer-this). Adhering
|
||||
* to this rule would make the races on these fields benign.
|
||||
*
|
||||
* <p>It is also imperative that implementations read the field only once,
|
||||
* as in:
|
||||
*
|
||||
* <pre> {@code
|
||||
* public Set<K> keySet() {
|
||||
* Set<K> ks = keySet; // single racy read
|
||||
* if (ks == null) {
|
||||
* ks = new KeySet();
|
||||
* keySet = ks;
|
||||
* }
|
||||
* return ks;
|
||||
* }
|
||||
*}</pre>
|
||||
*/
|
||||
transient Set<K> keySet;
|
||||
transient Collection<V> values;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @implSpec
|
||||
* This implementation returns a set that subclasses {@link AbstractSet}.
|
||||
* The subclass's iterator method returns a "wrapper object" over this
|
||||
* map's <tt>entrySet()</tt> iterator. The <tt>size</tt> method
|
||||
* delegates to this map's <tt>size</tt> method and the
|
||||
* <tt>contains</tt> method delegates to this map's
|
||||
* <tt>containsKey</tt> method.
|
||||
*
|
||||
* <p>The set is created the first time this method is called,
|
||||
* and returned in response to all subsequent calls. No synchronization
|
||||
* is performed, so there is a slight chance that multiple calls to this
|
||||
* method will not all return the same set.
|
||||
*/
|
||||
public Set<K> keySet() {
|
||||
Set<K> ks = keySet;
|
||||
if (ks == null) {
|
||||
ks = new AbstractSet<K>() {
|
||||
public Iterator<K> iterator() {
|
||||
return new Iterator<K>() {
|
||||
private Iterator<Entry<K,V>> i = entrySet().iterator();
|
||||
|
||||
public boolean hasNext() {
|
||||
return i.hasNext();
|
||||
}
|
||||
|
||||
public K next() {
|
||||
return i.next().getKey();
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
i.remove();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return AbstractMap.this.size();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return AbstractMap.this.isEmpty();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
AbstractMap.this.clear();
|
||||
}
|
||||
|
||||
public boolean contains(Object k) {
|
||||
return AbstractMap.this.containsKey(k);
|
||||
}
|
||||
};
|
||||
keySet = ks;
|
||||
}
|
||||
return ks;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @implSpec
|
||||
* This implementation returns a collection that subclasses {@link
|
||||
* AbstractCollection}. The subclass's iterator method returns a
|
||||
* "wrapper object" over this map's <tt>entrySet()</tt> iterator.
|
||||
* The <tt>size</tt> method delegates to this map's <tt>size</tt>
|
||||
* method and the <tt>contains</tt> method delegates to this map's
|
||||
* <tt>containsValue</tt> method.
|
||||
*
|
||||
* <p>The collection is created the first time this method is called, and
|
||||
* returned in response to all subsequent calls. No synchronization is
|
||||
* performed, so there is a slight chance that multiple calls to this
|
||||
* method will not all return the same collection.
|
||||
*/
|
||||
public Collection<V> values() {
|
||||
Collection<V> vals = values;
|
||||
if (vals == null) {
|
||||
vals = new AbstractCollection<V>() {
|
||||
public Iterator<V> iterator() {
|
||||
return new Iterator<V>() {
|
||||
private Iterator<Entry<K,V>> i = entrySet().iterator();
|
||||
|
||||
public boolean hasNext() {
|
||||
return i.hasNext();
|
||||
}
|
||||
|
||||
public V next() {
|
||||
return i.next().getValue();
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
i.remove();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return AbstractMap.this.size();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return AbstractMap.this.isEmpty();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
AbstractMap.this.clear();
|
||||
}
|
||||
|
||||
public boolean contains(Object v) {
|
||||
return AbstractMap.this.containsValue(v);
|
||||
}
|
||||
};
|
||||
values = vals;
|
||||
}
|
||||
return vals;
|
||||
}
|
||||
|
||||
public abstract Set<Entry<K,V>> entrySet();
|
||||
|
||||
|
||||
// Comparison and hashing
|
||||
|
||||
/**
|
||||
* Compares the specified object with this map for equality. Returns
|
||||
* <tt>true</tt> if the given object is also a map and the two maps
|
||||
* represent the same mappings. More formally, two maps <tt>m1</tt> and
|
||||
* <tt>m2</tt> represent the same mappings if
|
||||
* <tt>m1.entrySet().equals(m2.entrySet())</tt>. This ensures that the
|
||||
* <tt>equals</tt> method works properly across different implementations
|
||||
* of the <tt>Map</tt> interface.
|
||||
*
|
||||
* @implSpec
|
||||
* This implementation first checks if the specified object is this map;
|
||||
* if so it returns <tt>true</tt>. Then, it checks if the specified
|
||||
* object is a map whose size is identical to the size of this map; if
|
||||
* not, it returns <tt>false</tt>. If so, it iterates over this map's
|
||||
* <tt>entrySet</tt> collection, and checks that the specified map
|
||||
* contains each mapping that this map contains. If the specified map
|
||||
* fails to contain such a mapping, <tt>false</tt> is returned. If the
|
||||
* iteration completes, <tt>true</tt> is returned.
|
||||
*
|
||||
* @param o object to be compared for equality with this map
|
||||
* @return <tt>true</tt> if the specified object is equal to this map
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (o == this)
|
||||
return true;
|
||||
|
||||
if (!(o instanceof Map))
|
||||
return false;
|
||||
Map<?,?> m = (Map<?,?>) o;
|
||||
if (m.size() != size())
|
||||
return false;
|
||||
|
||||
try {
|
||||
Iterator<Entry<K,V>> i = entrySet().iterator();
|
||||
while (i.hasNext()) {
|
||||
Entry<K,V> e = i.next();
|
||||
K key = e.getKey();
|
||||
V value = e.getValue();
|
||||
if (value == null) {
|
||||
if (!(m.get(key)==null && m.containsKey(key)))
|
||||
return false;
|
||||
} else {
|
||||
if (!value.equals(m.get(key)))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} catch (ClassCastException unused) {
|
||||
return false;
|
||||
} catch (NullPointerException unused) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code value for this map. The hash code of a map is
|
||||
* defined to be the sum of the hash codes of each entry in the map's
|
||||
* <tt>entrySet()</tt> view. This ensures that <tt>m1.equals(m2)</tt>
|
||||
* implies that <tt>m1.hashCode()==m2.hashCode()</tt> for any two maps
|
||||
* <tt>m1</tt> and <tt>m2</tt>, as required by the general contract of
|
||||
* {@link Object#hashCode}.
|
||||
*
|
||||
* @implSpec
|
||||
* This implementation iterates over <tt>entrySet()</tt>, calling
|
||||
* {@link Map.Entry#hashCode hashCode()} on each element (entry) in the
|
||||
* set, and adding up the results.
|
||||
*
|
||||
* @return the hash code value for this map
|
||||
* @see Map.Entry#hashCode()
|
||||
* @see Object#equals(Object)
|
||||
* @see Set#equals(Object)
|
||||
*/
|
||||
public int hashCode() {
|
||||
int h = 0;
|
||||
Iterator<Entry<K,V>> i = entrySet().iterator();
|
||||
while (i.hasNext())
|
||||
h += i.next().hashCode();
|
||||
return h;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this map. The string representation
|
||||
* consists of a list of key-value mappings in the order returned by the
|
||||
* map's <tt>entrySet</tt> view's iterator, enclosed in braces
|
||||
* (<tt>"{}"</tt>). Adjacent mappings are separated by the characters
|
||||
* <tt>", "</tt> (comma and space). Each key-value mapping is rendered as
|
||||
* the key followed by an equals sign (<tt>"="</tt>) followed by the
|
||||
* associated value. Keys and values are converted to strings as by
|
||||
* {@link String#valueOf(Object)}.
|
||||
*
|
||||
* @return a string representation of this map
|
||||
*/
|
||||
public String toString() {
|
||||
Iterator<Entry<K,V>> i = entrySet().iterator();
|
||||
if (! i.hasNext())
|
||||
return "{}";
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append('{');
|
||||
for (;;) {
|
||||
Entry<K,V> e = i.next();
|
||||
K key = e.getKey();
|
||||
V value = e.getValue();
|
||||
sb.append(key == this ? "(this Map)" : key);
|
||||
sb.append('=');
|
||||
sb.append(value == this ? "(this Map)" : value);
|
||||
if (! i.hasNext())
|
||||
return sb.append('}').toString();
|
||||
sb.append(',').append(' ');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a shallow copy of this <tt>AbstractMap</tt> instance: the keys
|
||||
* and values themselves are not cloned.
|
||||
*
|
||||
* @return a shallow copy of this map
|
||||
*/
|
||||
protected Object clone() throws CloneNotSupportedException {
|
||||
AbstractMap<?,?> result = (AbstractMap<?,?>)super.clone();
|
||||
result.keySet = null;
|
||||
result.values = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method for SimpleEntry and SimpleImmutableEntry.
|
||||
* Test for equality, checking for nulls.
|
||||
*
|
||||
* NB: Do not replace with Object.equals until JDK-8015417 is resolved.
|
||||
*/
|
||||
private static boolean eq(Object o1, Object o2) {
|
||||
return o1 == null ? o2 == null : o1.equals(o2);
|
||||
}
|
||||
|
||||
// Implementation Note: SimpleEntry and SimpleImmutableEntry
|
||||
// are distinct unrelated classes, even though they share
|
||||
// some code. Since you can't add or subtract final-ness
|
||||
// of a field in a subclass, they can't share representations,
|
||||
// and the amount of duplicated code is too small to warrant
|
||||
// exposing a common abstract class.
|
||||
|
||||
|
||||
/**
|
||||
* An Entry maintaining a key and a value. The value may be
|
||||
* changed using the <tt>setValue</tt> method. This class
|
||||
* facilitates the process of building custom map
|
||||
* implementations. For example, it may be convenient to return
|
||||
* arrays of <tt>SimpleEntry</tt> instances in method
|
||||
* <tt>Map.entrySet().toArray</tt>.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public static class SimpleEntry<K,V>
|
||||
implements Entry<K,V>, java.io.Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -8499721149061103585L;
|
||||
|
||||
private final K key;
|
||||
private V value;
|
||||
|
||||
/**
|
||||
* Creates an entry representing a mapping from the specified
|
||||
* key to the specified value.
|
||||
*
|
||||
* @param key the key represented by this entry
|
||||
* @param value the value represented by this entry
|
||||
*/
|
||||
public SimpleEntry(K key, V value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an entry representing the same mapping as the
|
||||
* specified entry.
|
||||
*
|
||||
* @param entry the entry to copy
|
||||
*/
|
||||
public SimpleEntry(Entry<? extends K, ? extends V> entry) {
|
||||
this.key = entry.getKey();
|
||||
this.value = entry.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key corresponding to this entry.
|
||||
*
|
||||
* @return the key corresponding to this entry
|
||||
*/
|
||||
public K getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value corresponding to this entry.
|
||||
*
|
||||
* @return the value corresponding to this entry
|
||||
*/
|
||||
public V getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the value corresponding to this entry with the specified
|
||||
* value.
|
||||
*
|
||||
* @param value new value to be stored in this entry
|
||||
* @return the old value corresponding to the entry
|
||||
*/
|
||||
public V setValue(V value) {
|
||||
V oldValue = this.value;
|
||||
this.value = value;
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the specified object with this entry for equality.
|
||||
* Returns {@code true} if the given object is also a map entry and
|
||||
* the two entries represent the same mapping. More formally, two
|
||||
* entries {@code e1} and {@code e2} represent the same mapping
|
||||
* if<pre>
|
||||
* (e1.getKey()==null ?
|
||||
* e2.getKey()==null :
|
||||
* e1.getKey().equals(e2.getKey()))
|
||||
* &&
|
||||
* (e1.getValue()==null ?
|
||||
* e2.getValue()==null :
|
||||
* e1.getValue().equals(e2.getValue()))</pre>
|
||||
* This ensures that the {@code equals} method works properly across
|
||||
* different implementations of the {@code Map.Entry} interface.
|
||||
*
|
||||
* @param o object to be compared for equality with this map entry
|
||||
* @return {@code true} if the specified object is equal to this map
|
||||
* entry
|
||||
* @see #hashCode
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof Map.Entry))
|
||||
return false;
|
||||
Map.Entry<?,?> e = (Map.Entry<?,?>)o;
|
||||
return eq(key, e.getKey()) && eq(value, e.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code value for this map entry. The hash code
|
||||
* of a map entry {@code e} is defined to be: <pre>
|
||||
* (e.getKey()==null ? 0 : e.getKey().hashCode()) ^
|
||||
* (e.getValue()==null ? 0 : e.getValue().hashCode())</pre>
|
||||
* This ensures that {@code e1.equals(e2)} implies that
|
||||
* {@code e1.hashCode()==e2.hashCode()} for any two Entries
|
||||
* {@code e1} and {@code e2}, as required by the general
|
||||
* contract of {@link Object#hashCode}.
|
||||
*
|
||||
* @return the hash code value for this map entry
|
||||
* @see #equals
|
||||
*/
|
||||
public int hashCode() {
|
||||
return (key == null ? 0 : key.hashCode()) ^
|
||||
(value == null ? 0 : value.hashCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a String representation of this map entry. This
|
||||
* implementation returns the string representation of this
|
||||
* entry's key followed by the equals character ("<tt>=</tt>")
|
||||
* followed by the string representation of this entry's value.
|
||||
*
|
||||
* @return a String representation of this map entry
|
||||
*/
|
||||
public String toString() {
|
||||
return key + "=" + value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* An Entry maintaining an immutable key and value. This class
|
||||
* does not support method <tt>setValue</tt>. This class may be
|
||||
* convenient in methods that return thread-safe snapshots of
|
||||
* key-value mappings.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public static class SimpleImmutableEntry<K,V>
|
||||
implements Entry<K,V>, java.io.Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 7138329143949025153L;
|
||||
|
||||
private final K key;
|
||||
private final V value;
|
||||
|
||||
/**
|
||||
* Creates an entry representing a mapping from the specified
|
||||
* key to the specified value.
|
||||
*
|
||||
* @param key the key represented by this entry
|
||||
* @param value the value represented by this entry
|
||||
*/
|
||||
public SimpleImmutableEntry(K key, V value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an entry representing the same mapping as the
|
||||
* specified entry.
|
||||
*
|
||||
* @param entry the entry to copy
|
||||
*/
|
||||
public SimpleImmutableEntry(Entry<? extends K, ? extends V> entry) {
|
||||
this.key = entry.getKey();
|
||||
this.value = entry.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key corresponding to this entry.
|
||||
*
|
||||
* @return the key corresponding to this entry
|
||||
*/
|
||||
public K getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value corresponding to this entry.
|
||||
*
|
||||
* @return the value corresponding to this entry
|
||||
*/
|
||||
public V getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the value corresponding to this entry with the specified
|
||||
* value (optional operation). This implementation simply throws
|
||||
* <tt>UnsupportedOperationException</tt>, as this class implements
|
||||
* an <i>immutable</i> map entry.
|
||||
*
|
||||
* @param value new value to be stored in this entry
|
||||
* @return (Does not return)
|
||||
* @throws UnsupportedOperationException always
|
||||
*/
|
||||
public V setValue(V value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the specified object with this entry for equality.
|
||||
* Returns {@code true} if the given object is also a map entry and
|
||||
* the two entries represent the same mapping. More formally, two
|
||||
* entries {@code e1} and {@code e2} represent the same mapping
|
||||
* if<pre>
|
||||
* (e1.getKey()==null ?
|
||||
* e2.getKey()==null :
|
||||
* e1.getKey().equals(e2.getKey()))
|
||||
* &&
|
||||
* (e1.getValue()==null ?
|
||||
* e2.getValue()==null :
|
||||
* e1.getValue().equals(e2.getValue()))</pre>
|
||||
* This ensures that the {@code equals} method works properly across
|
||||
* different implementations of the {@code Map.Entry} interface.
|
||||
*
|
||||
* @param o object to be compared for equality with this map entry
|
||||
* @return {@code true} if the specified object is equal to this map
|
||||
* entry
|
||||
* @see #hashCode
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof Map.Entry))
|
||||
return false;
|
||||
Map.Entry<?,?> e = (Map.Entry<?,?>)o;
|
||||
return eq(key, e.getKey()) && eq(value, e.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code value for this map entry. The hash code
|
||||
* of a map entry {@code e} is defined to be: <pre>
|
||||
* (e.getKey()==null ? 0 : e.getKey().hashCode()) ^
|
||||
* (e.getValue()==null ? 0 : e.getValue().hashCode())</pre>
|
||||
* This ensures that {@code e1.equals(e2)} implies that
|
||||
* {@code e1.hashCode()==e2.hashCode()} for any two Entries
|
||||
* {@code e1} and {@code e2}, as required by the general
|
||||
* contract of {@link Object#hashCode}.
|
||||
*
|
||||
* @return the hash code value for this map entry
|
||||
* @see #equals
|
||||
*/
|
||||
public int hashCode() {
|
||||
return (key == null ? 0 : key.hashCode()) ^
|
||||
(value == null ? 0 : value.hashCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a String representation of this map entry. This
|
||||
* implementation returns the string representation of this
|
||||
* entry's key followed by the equals character ("<tt>=</tt>")
|
||||
* followed by the string representation of this entry's value.
|
||||
*
|
||||
* @return a String representation of this map entry
|
||||
*/
|
||||
public String toString() {
|
||||
return key + "=" + value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
192
jdkSrc/jdk8/java/util/AbstractQueue.java
Normal file
192
jdkSrc/jdk8/java/util/AbstractQueue.java
Normal file
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is available under and governed by the GNU General Public
|
||||
* License version 2 only, as published by the Free Software Foundation.
|
||||
* However, the following notice accompanied the original version of this
|
||||
* file:
|
||||
*
|
||||
* Written by Doug Lea with assistance from members of JCP JSR-166
|
||||
* Expert Group and released to the public domain, as explained at
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* This class provides skeletal implementations of some {@link Queue}
|
||||
* operations. The implementations in this class are appropriate when
|
||||
* the base implementation does <em>not</em> allow <tt>null</tt>
|
||||
* elements. Methods {@link #add add}, {@link #remove remove}, and
|
||||
* {@link #element element} are based on {@link #offer offer}, {@link
|
||||
* #poll poll}, and {@link #peek peek}, respectively, but throw
|
||||
* exceptions instead of indicating failure via <tt>false</tt> or
|
||||
* <tt>null</tt> returns.
|
||||
*
|
||||
* <p>A <tt>Queue</tt> implementation that extends this class must
|
||||
* minimally define a method {@link Queue#offer} which does not permit
|
||||
* insertion of <tt>null</tt> elements, along with methods {@link
|
||||
* Queue#peek}, {@link Queue#poll}, {@link Collection#size}, and
|
||||
* {@link Collection#iterator}. Typically, additional methods will be
|
||||
* overridden as well. If these requirements cannot be met, consider
|
||||
* instead subclassing {@link AbstractCollection}.
|
||||
*
|
||||
* <p>This class is a member of the
|
||||
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
|
||||
* Java Collections Framework</a>.
|
||||
*
|
||||
* @since 1.5
|
||||
* @author Doug Lea
|
||||
* @param <E> the type of elements held in this collection
|
||||
*/
|
||||
public abstract class AbstractQueue<E>
|
||||
extends AbstractCollection<E>
|
||||
implements Queue<E> {
|
||||
|
||||
/**
|
||||
* Constructor for use by subclasses.
|
||||
*/
|
||||
protected AbstractQueue() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the specified element into this queue if it is possible to do so
|
||||
* immediately without violating capacity restrictions, returning
|
||||
* <tt>true</tt> upon success and throwing an <tt>IllegalStateException</tt>
|
||||
* if no space is currently available.
|
||||
*
|
||||
* <p>This implementation returns <tt>true</tt> if <tt>offer</tt> succeeds,
|
||||
* else throws an <tt>IllegalStateException</tt>.
|
||||
*
|
||||
* @param e the element to add
|
||||
* @return <tt>true</tt> (as specified by {@link Collection#add})
|
||||
* @throws IllegalStateException if the element cannot be added at this
|
||||
* time due to capacity restrictions
|
||||
* @throws ClassCastException if the class of the specified element
|
||||
* prevents it from being added to this queue
|
||||
* @throws NullPointerException if the specified element is null and
|
||||
* this queue does not permit null elements
|
||||
* @throws IllegalArgumentException if some property of this element
|
||||
* prevents it from being added to this queue
|
||||
*/
|
||||
public boolean add(E e) {
|
||||
if (offer(e))
|
||||
return true;
|
||||
else
|
||||
throw new IllegalStateException("Queue full");
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves and removes the head of this queue. This method differs
|
||||
* from {@link #poll poll} only in that it throws an exception if this
|
||||
* queue is empty.
|
||||
*
|
||||
* <p>This implementation returns the result of <tt>poll</tt>
|
||||
* unless the queue is empty.
|
||||
*
|
||||
* @return the head of this queue
|
||||
* @throws NoSuchElementException if this queue is empty
|
||||
*/
|
||||
public E remove() {
|
||||
E x = poll();
|
||||
if (x != null)
|
||||
return x;
|
||||
else
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves, but does not remove, the head of this queue. This method
|
||||
* differs from {@link #peek peek} only in that it throws an exception if
|
||||
* this queue is empty.
|
||||
*
|
||||
* <p>This implementation returns the result of <tt>peek</tt>
|
||||
* unless the queue is empty.
|
||||
*
|
||||
* @return the head of this queue
|
||||
* @throws NoSuchElementException if this queue is empty
|
||||
*/
|
||||
public E element() {
|
||||
E x = peek();
|
||||
if (x != null)
|
||||
return x;
|
||||
else
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all of the elements from this queue.
|
||||
* The queue will be empty after this call returns.
|
||||
*
|
||||
* <p>This implementation repeatedly invokes {@link #poll poll} until it
|
||||
* returns <tt>null</tt>.
|
||||
*/
|
||||
public void clear() {
|
||||
while (poll() != null)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all of the elements in the specified collection to this
|
||||
* queue. Attempts to addAll of a queue to itself result in
|
||||
* <tt>IllegalArgumentException</tt>. Further, the behavior of
|
||||
* this operation is undefined if the specified collection is
|
||||
* modified while the operation is in progress.
|
||||
*
|
||||
* <p>This implementation iterates over the specified collection,
|
||||
* and adds each element returned by the iterator to this
|
||||
* queue, in turn. A runtime exception encountered while
|
||||
* trying to add an element (including, in particular, a
|
||||
* <tt>null</tt> element) may result in only some of the elements
|
||||
* having been successfully added when the associated exception is
|
||||
* thrown.
|
||||
*
|
||||
* @param c collection containing elements to be added to this queue
|
||||
* @return <tt>true</tt> if this queue changed as a result of the call
|
||||
* @throws ClassCastException if the class of an element of the specified
|
||||
* collection prevents it from being added to this queue
|
||||
* @throws NullPointerException if the specified collection contains a
|
||||
* null element and this queue does not permit null elements,
|
||||
* or if the specified collection is null
|
||||
* @throws IllegalArgumentException if some property of an element of the
|
||||
* specified collection prevents it from being added to this
|
||||
* queue, or if the specified collection is this queue
|
||||
* @throws IllegalStateException if not all the elements can be added at
|
||||
* this time due to insertion restrictions
|
||||
* @see #add(Object)
|
||||
*/
|
||||
public boolean addAll(Collection<? extends E> c) {
|
||||
if (c == null)
|
||||
throw new NullPointerException();
|
||||
if (c == this)
|
||||
throw new IllegalArgumentException();
|
||||
boolean modified = false;
|
||||
for (E e : c)
|
||||
if (add(e))
|
||||
modified = true;
|
||||
return modified;
|
||||
}
|
||||
|
||||
}
|
||||
253
jdkSrc/jdk8/java/util/AbstractSequentialList.java
Normal file
253
jdkSrc/jdk8/java/util/AbstractSequentialList.java
Normal file
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* This class provides a skeletal implementation of the <tt>List</tt>
|
||||
* interface to minimize the effort required to implement this interface
|
||||
* backed by a "sequential access" data store (such as a linked list). For
|
||||
* random access data (such as an array), <tt>AbstractList</tt> should be used
|
||||
* in preference to this class.<p>
|
||||
*
|
||||
* This class is the opposite of the <tt>AbstractList</tt> class in the sense
|
||||
* that it implements the "random access" methods (<tt>get(int index)</tt>,
|
||||
* <tt>set(int index, E element)</tt>, <tt>add(int index, E element)</tt> and
|
||||
* <tt>remove(int index)</tt>) on top of the list's list iterator, instead of
|
||||
* the other way around.<p>
|
||||
*
|
||||
* To implement a list the programmer needs only to extend this class and
|
||||
* provide implementations for the <tt>listIterator</tt> and <tt>size</tt>
|
||||
* methods. For an unmodifiable list, the programmer need only implement the
|
||||
* list iterator's <tt>hasNext</tt>, <tt>next</tt>, <tt>hasPrevious</tt>,
|
||||
* <tt>previous</tt> and <tt>index</tt> methods.<p>
|
||||
*
|
||||
* For a modifiable list the programmer should additionally implement the list
|
||||
* iterator's <tt>set</tt> method. For a variable-size list the programmer
|
||||
* should additionally implement the list iterator's <tt>remove</tt> and
|
||||
* <tt>add</tt> methods.<p>
|
||||
*
|
||||
* The programmer should generally provide a void (no argument) and collection
|
||||
* constructor, as per the recommendation in the <tt>Collection</tt> interface
|
||||
* specification.<p>
|
||||
*
|
||||
* This class is a member of the
|
||||
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
|
||||
* Java Collections Framework</a>.
|
||||
*
|
||||
* @author Josh Bloch
|
||||
* @author Neal Gafter
|
||||
* @see Collection
|
||||
* @see List
|
||||
* @see AbstractList
|
||||
* @see AbstractCollection
|
||||
* @since 1.2
|
||||
*/
|
||||
|
||||
public abstract class AbstractSequentialList<E> extends AbstractList<E> {
|
||||
/**
|
||||
* Sole constructor. (For invocation by subclass constructors, typically
|
||||
* implicit.)
|
||||
*/
|
||||
protected AbstractSequentialList() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the element at the specified position in this list.
|
||||
*
|
||||
* <p>This implementation first gets a list iterator pointing to the
|
||||
* indexed element (with <tt>listIterator(index)</tt>). Then, it gets
|
||||
* the element using <tt>ListIterator.next</tt> and returns it.
|
||||
*
|
||||
* @throws IndexOutOfBoundsException {@inheritDoc}
|
||||
*/
|
||||
public E get(int index) {
|
||||
try {
|
||||
return listIterator(index).next();
|
||||
} catch (NoSuchElementException exc) {
|
||||
throw new IndexOutOfBoundsException("Index: "+index);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the element at the specified position in this list with the
|
||||
* specified element (optional operation).
|
||||
*
|
||||
* <p>This implementation first gets a list iterator pointing to the
|
||||
* indexed element (with <tt>listIterator(index)</tt>). Then, it gets
|
||||
* the current element using <tt>ListIterator.next</tt> and replaces it
|
||||
* with <tt>ListIterator.set</tt>.
|
||||
*
|
||||
* <p>Note that this implementation will throw an
|
||||
* <tt>UnsupportedOperationException</tt> if the list iterator does not
|
||||
* implement the <tt>set</tt> operation.
|
||||
*
|
||||
* @throws UnsupportedOperationException {@inheritDoc}
|
||||
* @throws ClassCastException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
* @throws IllegalArgumentException {@inheritDoc}
|
||||
* @throws IndexOutOfBoundsException {@inheritDoc}
|
||||
*/
|
||||
public E set(int index, E element) {
|
||||
try {
|
||||
ListIterator<E> e = listIterator(index);
|
||||
E oldVal = e.next();
|
||||
e.set(element);
|
||||
return oldVal;
|
||||
} catch (NoSuchElementException exc) {
|
||||
throw new IndexOutOfBoundsException("Index: "+index);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the specified element at the specified position in this list
|
||||
* (optional operation). Shifts the element currently at that position
|
||||
* (if any) and any subsequent elements to the right (adds one to their
|
||||
* indices).
|
||||
*
|
||||
* <p>This implementation first gets a list iterator pointing to the
|
||||
* indexed element (with <tt>listIterator(index)</tt>). Then, it
|
||||
* inserts the specified element with <tt>ListIterator.add</tt>.
|
||||
*
|
||||
* <p>Note that this implementation will throw an
|
||||
* <tt>UnsupportedOperationException</tt> if the list iterator does not
|
||||
* implement the <tt>add</tt> operation.
|
||||
*
|
||||
* @throws UnsupportedOperationException {@inheritDoc}
|
||||
* @throws ClassCastException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
* @throws IllegalArgumentException {@inheritDoc}
|
||||
* @throws IndexOutOfBoundsException {@inheritDoc}
|
||||
*/
|
||||
public void add(int index, E element) {
|
||||
try {
|
||||
listIterator(index).add(element);
|
||||
} catch (NoSuchElementException exc) {
|
||||
throw new IndexOutOfBoundsException("Index: "+index);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the element at the specified position in this list (optional
|
||||
* operation). Shifts any subsequent elements to the left (subtracts one
|
||||
* from their indices). Returns the element that was removed from the
|
||||
* list.
|
||||
*
|
||||
* <p>This implementation first gets a list iterator pointing to the
|
||||
* indexed element (with <tt>listIterator(index)</tt>). Then, it removes
|
||||
* the element with <tt>ListIterator.remove</tt>.
|
||||
*
|
||||
* <p>Note that this implementation will throw an
|
||||
* <tt>UnsupportedOperationException</tt> if the list iterator does not
|
||||
* implement the <tt>remove</tt> operation.
|
||||
*
|
||||
* @throws UnsupportedOperationException {@inheritDoc}
|
||||
* @throws IndexOutOfBoundsException {@inheritDoc}
|
||||
*/
|
||||
public E remove(int index) {
|
||||
try {
|
||||
ListIterator<E> e = listIterator(index);
|
||||
E outCast = e.next();
|
||||
e.remove();
|
||||
return outCast;
|
||||
} catch (NoSuchElementException exc) {
|
||||
throw new IndexOutOfBoundsException("Index: "+index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Bulk Operations
|
||||
|
||||
/**
|
||||
* Inserts all of the elements in the specified collection into this
|
||||
* list at the specified position (optional operation). Shifts the
|
||||
* element currently at that position (if any) and any subsequent
|
||||
* elements to the right (increases their indices). The new elements
|
||||
* will appear in this list in the order that they are returned by the
|
||||
* specified collection's iterator. The behavior of this operation is
|
||||
* undefined if the specified collection is modified while the
|
||||
* operation is in progress. (Note that this will occur if the specified
|
||||
* collection is this list, and it's nonempty.)
|
||||
*
|
||||
* <p>This implementation gets an iterator over the specified collection and
|
||||
* a list iterator over this list pointing to the indexed element (with
|
||||
* <tt>listIterator(index)</tt>). Then, it iterates over the specified
|
||||
* collection, inserting the elements obtained from the iterator into this
|
||||
* list, one at a time, using <tt>ListIterator.add</tt> followed by
|
||||
* <tt>ListIterator.next</tt> (to skip over the added element).
|
||||
*
|
||||
* <p>Note that this implementation will throw an
|
||||
* <tt>UnsupportedOperationException</tt> if the list iterator returned by
|
||||
* the <tt>listIterator</tt> method does not implement the <tt>add</tt>
|
||||
* operation.
|
||||
*
|
||||
* @throws UnsupportedOperationException {@inheritDoc}
|
||||
* @throws ClassCastException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
* @throws IllegalArgumentException {@inheritDoc}
|
||||
* @throws IndexOutOfBoundsException {@inheritDoc}
|
||||
*/
|
||||
public boolean addAll(int index, Collection<? extends E> c) {
|
||||
try {
|
||||
boolean modified = false;
|
||||
ListIterator<E> e1 = listIterator(index);
|
||||
Iterator<? extends E> e2 = c.iterator();
|
||||
while (e2.hasNext()) {
|
||||
e1.add(e2.next());
|
||||
modified = true;
|
||||
}
|
||||
return modified;
|
||||
} catch (NoSuchElementException exc) {
|
||||
throw new IndexOutOfBoundsException("Index: "+index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Iterators
|
||||
|
||||
/**
|
||||
* Returns an iterator over the elements in this list (in proper
|
||||
* sequence).<p>
|
||||
*
|
||||
* This implementation merely returns a list iterator over the list.
|
||||
*
|
||||
* @return an iterator over the elements in this list (in proper sequence)
|
||||
*/
|
||||
public Iterator<E> iterator() {
|
||||
return listIterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list iterator over the elements in this list (in proper
|
||||
* sequence).
|
||||
*
|
||||
* @param index index of first element to be returned from the list
|
||||
* iterator (by a call to the <code>next</code> method)
|
||||
* @return a list iterator over the elements in this list (in proper
|
||||
* sequence)
|
||||
* @throws IndexOutOfBoundsException {@inheritDoc}
|
||||
*/
|
||||
public abstract ListIterator<E> listIterator(int index);
|
||||
}
|
||||
186
jdkSrc/jdk8/java/util/AbstractSet.java
Normal file
186
jdkSrc/jdk8/java/util/AbstractSet.java
Normal file
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* This class provides a skeletal implementation of the <tt>Set</tt>
|
||||
* interface to minimize the effort required to implement this
|
||||
* interface. <p>
|
||||
*
|
||||
* The process of implementing a set by extending this class is identical
|
||||
* to that of implementing a Collection by extending AbstractCollection,
|
||||
* except that all of the methods and constructors in subclasses of this
|
||||
* class must obey the additional constraints imposed by the <tt>Set</tt>
|
||||
* interface (for instance, the add method must not permit addition of
|
||||
* multiple instances of an object to a set).<p>
|
||||
*
|
||||
* Note that this class does not override any of the implementations from
|
||||
* the <tt>AbstractCollection</tt> class. It merely adds implementations
|
||||
* for <tt>equals</tt> and <tt>hashCode</tt>.<p>
|
||||
*
|
||||
* This class is a member of the
|
||||
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
|
||||
* Java Collections Framework</a>.
|
||||
*
|
||||
* @param <E> the type of elements maintained by this set
|
||||
*
|
||||
* @author Josh Bloch
|
||||
* @author Neal Gafter
|
||||
* @see Collection
|
||||
* @see AbstractCollection
|
||||
* @see Set
|
||||
* @since 1.2
|
||||
*/
|
||||
|
||||
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {
|
||||
/**
|
||||
* Sole constructor. (For invocation by subclass constructors, typically
|
||||
* implicit.)
|
||||
*/
|
||||
protected AbstractSet() {
|
||||
}
|
||||
|
||||
// Comparison and hashing
|
||||
|
||||
/**
|
||||
* Compares the specified object with this set for equality. Returns
|
||||
* <tt>true</tt> if the given object is also a set, the two sets have
|
||||
* the same size, and every member of the given set is contained in
|
||||
* this set. This ensures that the <tt>equals</tt> method works
|
||||
* properly across different implementations of the <tt>Set</tt>
|
||||
* interface.<p>
|
||||
*
|
||||
* This implementation first checks if the specified object is this
|
||||
* set; if so it returns <tt>true</tt>. Then, it checks if the
|
||||
* specified object is a set whose size is identical to the size of
|
||||
* this set; if not, it returns false. If so, it returns
|
||||
* <tt>containsAll((Collection) o)</tt>.
|
||||
*
|
||||
* @param o object to be compared for equality with this set
|
||||
* @return <tt>true</tt> if the specified object is equal to this set
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (o == this)
|
||||
return true;
|
||||
|
||||
if (!(o instanceof Set))
|
||||
return false;
|
||||
Collection<?> c = (Collection<?>) o;
|
||||
if (c.size() != size())
|
||||
return false;
|
||||
try {
|
||||
return containsAll(c);
|
||||
} catch (ClassCastException unused) {
|
||||
return false;
|
||||
} catch (NullPointerException unused) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code value for this set. The hash code of a set is
|
||||
* defined to be the sum of the hash codes of the elements in the set,
|
||||
* where the hash code of a <tt>null</tt> element is defined to be zero.
|
||||
* This ensures that <tt>s1.equals(s2)</tt> implies that
|
||||
* <tt>s1.hashCode()==s2.hashCode()</tt> for any two sets <tt>s1</tt>
|
||||
* and <tt>s2</tt>, as required by the general contract of
|
||||
* {@link Object#hashCode}.
|
||||
*
|
||||
* <p>This implementation iterates over the set, calling the
|
||||
* <tt>hashCode</tt> method on each element in the set, and adding up
|
||||
* the results.
|
||||
*
|
||||
* @return the hash code value for this set
|
||||
* @see Object#equals(Object)
|
||||
* @see Set#equals(Object)
|
||||
*/
|
||||
public int hashCode() {
|
||||
int h = 0;
|
||||
Iterator<E> i = iterator();
|
||||
while (i.hasNext()) {
|
||||
E obj = i.next();
|
||||
if (obj != null)
|
||||
h += obj.hashCode();
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes from this set all of its elements that are contained in the
|
||||
* specified collection (optional operation). If the specified
|
||||
* collection is also a set, this operation effectively modifies this
|
||||
* set so that its value is the <i>asymmetric set difference</i> of
|
||||
* the two sets.
|
||||
*
|
||||
* <p>This implementation determines which is the smaller of this set
|
||||
* and the specified collection, by invoking the <tt>size</tt>
|
||||
* method on each. If this set has fewer elements, then the
|
||||
* implementation iterates over this set, checking each element
|
||||
* returned by the iterator in turn to see if it is contained in
|
||||
* the specified collection. If it is so contained, it is removed
|
||||
* from this set with the iterator's <tt>remove</tt> method. If
|
||||
* the specified collection has fewer elements, then the
|
||||
* implementation iterates over the specified collection, removing
|
||||
* from this set each element returned by the iterator, using this
|
||||
* set's <tt>remove</tt> method.
|
||||
*
|
||||
* <p>Note that this implementation will throw an
|
||||
* <tt>UnsupportedOperationException</tt> if the iterator returned by the
|
||||
* <tt>iterator</tt> method does not implement the <tt>remove</tt> method.
|
||||
*
|
||||
* @param c collection containing elements to be removed from this set
|
||||
* @return <tt>true</tt> if this set changed as a result of the call
|
||||
* @throws UnsupportedOperationException if the <tt>removeAll</tt> operation
|
||||
* is not supported by this set
|
||||
* @throws ClassCastException if the class of an element of this set
|
||||
* is incompatible with the specified collection
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if this set contains a null element and the
|
||||
* specified collection does not permit null elements
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>),
|
||||
* or if the specified collection is null
|
||||
* @see #remove(Object)
|
||||
* @see #contains(Object)
|
||||
*/
|
||||
public boolean removeAll(Collection<?> c) {
|
||||
Objects.requireNonNull(c);
|
||||
boolean modified = false;
|
||||
|
||||
if (size() > c.size()) {
|
||||
for (Iterator<?> i = c.iterator(); i.hasNext(); )
|
||||
modified |= remove(i.next());
|
||||
} else {
|
||||
for (Iterator<?> i = iterator(); i.hasNext(); ) {
|
||||
if (c.contains(i.next())) {
|
||||
i.remove();
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
}
|
||||
992
jdkSrc/jdk8/java/util/ArrayDeque.java
Normal file
992
jdkSrc/jdk8/java/util/ArrayDeque.java
Normal file
@@ -0,0 +1,992 @@
|
||||
/*
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is available under and governed by the GNU General Public
|
||||
* License version 2 only, as published by the Free Software Foundation.
|
||||
* However, the following notice accompanied the original version of this
|
||||
* file:
|
||||
*
|
||||
* Written by Josh Bloch of Google Inc. and released to the public domain,
|
||||
* as explained at http://creativecommons.org/publicdomain/zero/1.0/.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.function.Consumer;
|
||||
import sun.misc.SharedSecrets;
|
||||
|
||||
/**
|
||||
* Resizable-array implementation of the {@link Deque} interface. Array
|
||||
* deques have no capacity restrictions; they grow as necessary to support
|
||||
* usage. They are not thread-safe; in the absence of external
|
||||
* synchronization, they do not support concurrent access by multiple threads.
|
||||
* Null elements are prohibited. This class is likely to be faster than
|
||||
* {@link Stack} when used as a stack, and faster than {@link LinkedList}
|
||||
* when used as a queue.
|
||||
*
|
||||
* <p>Most {@code ArrayDeque} operations run in amortized constant time.
|
||||
* Exceptions include {@link #remove(Object) remove}, {@link
|
||||
* #removeFirstOccurrence removeFirstOccurrence}, {@link #removeLastOccurrence
|
||||
* removeLastOccurrence}, {@link #contains contains}, {@link #iterator
|
||||
* iterator.remove()}, and the bulk operations, all of which run in linear
|
||||
* time.
|
||||
*
|
||||
* <p>The iterators returned by this class's {@code iterator} method are
|
||||
* <i>fail-fast</i>: If the deque is modified at any time after the iterator
|
||||
* is created, in any way except through the iterator's own {@code remove}
|
||||
* method, the iterator will generally throw a {@link
|
||||
* ConcurrentModificationException}. Thus, in the face of concurrent
|
||||
* modification, the iterator fails quickly and cleanly, rather than risking
|
||||
* arbitrary, non-deterministic behavior at an undetermined time in the
|
||||
* future.
|
||||
*
|
||||
* <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
|
||||
* as it is, generally speaking, impossible to make any hard guarantees in the
|
||||
* presence of unsynchronized concurrent modification. Fail-fast iterators
|
||||
* throw {@code ConcurrentModificationException} on a best-effort basis.
|
||||
* Therefore, it would be wrong to write a program that depended on this
|
||||
* exception for its correctness: <i>the fail-fast behavior of iterators
|
||||
* should be used only to detect bugs.</i>
|
||||
*
|
||||
* <p>This class and its iterator implement all of the
|
||||
* <em>optional</em> methods of the {@link Collection} and {@link
|
||||
* Iterator} interfaces.
|
||||
*
|
||||
* <p>This class is a member of the
|
||||
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
|
||||
* Java Collections Framework</a>.
|
||||
*
|
||||
* @author Josh Bloch and Doug Lea
|
||||
* @since 1.6
|
||||
* @param <E> the type of elements held in this collection
|
||||
*/
|
||||
public class ArrayDeque<E> extends AbstractCollection<E>
|
||||
implements Deque<E>, Cloneable, Serializable
|
||||
{
|
||||
/**
|
||||
* The array in which the elements of the deque are stored.
|
||||
* The capacity of the deque is the length of this array, which is
|
||||
* always a power of two. The array is never allowed to become
|
||||
* full, except transiently within an addX method where it is
|
||||
* resized (see doubleCapacity) immediately upon becoming full,
|
||||
* thus avoiding head and tail wrapping around to equal each
|
||||
* other. We also guarantee that all array cells not holding
|
||||
* deque elements are always null.
|
||||
*/
|
||||
transient Object[] elements; // non-private to simplify nested class access
|
||||
|
||||
/**
|
||||
* The index of the element at the head of the deque (which is the
|
||||
* element that would be removed by remove() or pop()); or an
|
||||
* arbitrary number equal to tail if the deque is empty.
|
||||
*/
|
||||
transient int head;
|
||||
|
||||
/**
|
||||
* The index at which the next element would be added to the tail
|
||||
* of the deque (via addLast(E), add(E), or push(E)).
|
||||
*/
|
||||
transient int tail;
|
||||
|
||||
/**
|
||||
* The minimum capacity that we'll use for a newly created deque.
|
||||
* Must be a power of 2.
|
||||
*/
|
||||
private static final int MIN_INITIAL_CAPACITY = 8;
|
||||
|
||||
// ****** Array allocation and resizing utilities ******
|
||||
|
||||
private static int calculateSize(int numElements) {
|
||||
int initialCapacity = MIN_INITIAL_CAPACITY;
|
||||
// Find the best power of two to hold elements.
|
||||
// Tests "<=" because arrays aren't kept full.
|
||||
if (numElements >= initialCapacity) {
|
||||
initialCapacity = numElements;
|
||||
initialCapacity |= (initialCapacity >>> 1);
|
||||
initialCapacity |= (initialCapacity >>> 2);
|
||||
initialCapacity |= (initialCapacity >>> 4);
|
||||
initialCapacity |= (initialCapacity >>> 8);
|
||||
initialCapacity |= (initialCapacity >>> 16);
|
||||
initialCapacity++;
|
||||
|
||||
if (initialCapacity < 0) // Too many elements, must back off
|
||||
initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements
|
||||
}
|
||||
return initialCapacity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates empty array to hold the given number of elements.
|
||||
*
|
||||
* @param numElements the number of elements to hold
|
||||
*/
|
||||
private void allocateElements(int numElements) {
|
||||
elements = new Object[calculateSize(numElements)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Doubles the capacity of this deque. Call only when full, i.e.,
|
||||
* when head and tail have wrapped around to become equal.
|
||||
*/
|
||||
private void doubleCapacity() {
|
||||
assert head == tail;
|
||||
int p = head;
|
||||
int n = elements.length;
|
||||
int r = n - p; // number of elements to the right of p
|
||||
int newCapacity = n << 1;
|
||||
if (newCapacity < 0)
|
||||
throw new IllegalStateException("Sorry, deque too big");
|
||||
Object[] a = new Object[newCapacity];
|
||||
System.arraycopy(elements, p, a, 0, r);
|
||||
System.arraycopy(elements, 0, a, r, p);
|
||||
elements = a;
|
||||
head = 0;
|
||||
tail = n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the elements from our element array into the specified array,
|
||||
* in order (from first to last element in the deque). It is assumed
|
||||
* that the array is large enough to hold all elements in the deque.
|
||||
*
|
||||
* @return its argument
|
||||
*/
|
||||
private <T> T[] copyElements(T[] a) {
|
||||
if (head < tail) {
|
||||
System.arraycopy(elements, head, a, 0, size());
|
||||
} else if (head > tail) {
|
||||
int headPortionLen = elements.length - head;
|
||||
System.arraycopy(elements, head, a, 0, headPortionLen);
|
||||
System.arraycopy(elements, 0, a, headPortionLen, tail);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an empty array deque with an initial capacity
|
||||
* sufficient to hold 16 elements.
|
||||
*/
|
||||
public ArrayDeque() {
|
||||
elements = new Object[16];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an empty array deque with an initial capacity
|
||||
* sufficient to hold the specified number of elements.
|
||||
*
|
||||
* @param numElements lower bound on initial capacity of the deque
|
||||
*/
|
||||
public ArrayDeque(int numElements) {
|
||||
allocateElements(numElements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a deque containing the elements of the specified
|
||||
* collection, in the order they are returned by the collection's
|
||||
* iterator. (The first element returned by the collection's
|
||||
* iterator becomes the first element, or <i>front</i> of the
|
||||
* deque.)
|
||||
*
|
||||
* @param c the collection whose elements are to be placed into the deque
|
||||
* @throws NullPointerException if the specified collection is null
|
||||
*/
|
||||
public ArrayDeque(Collection<? extends E> c) {
|
||||
allocateElements(c.size());
|
||||
addAll(c);
|
||||
}
|
||||
|
||||
// The main insertion and extraction methods are addFirst,
|
||||
// addLast, pollFirst, pollLast. The other methods are defined in
|
||||
// terms of these.
|
||||
|
||||
/**
|
||||
* Inserts the specified element at the front of this deque.
|
||||
*
|
||||
* @param e the element to add
|
||||
* @throws NullPointerException if the specified element is null
|
||||
*/
|
||||
public void addFirst(E e) {
|
||||
if (e == null)
|
||||
throw new NullPointerException();
|
||||
elements[head = (head - 1) & (elements.length - 1)] = e;
|
||||
if (head == tail)
|
||||
doubleCapacity();
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the specified element at the end of this deque.
|
||||
*
|
||||
* <p>This method is equivalent to {@link #add}.
|
||||
*
|
||||
* @param e the element to add
|
||||
* @throws NullPointerException if the specified element is null
|
||||
*/
|
||||
public void addLast(E e) {
|
||||
if (e == null)
|
||||
throw new NullPointerException();
|
||||
elements[tail] = e;
|
||||
if ( (tail = (tail + 1) & (elements.length - 1)) == head)
|
||||
doubleCapacity();
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the specified element at the front of this deque.
|
||||
*
|
||||
* @param e the element to add
|
||||
* @return {@code true} (as specified by {@link Deque#offerFirst})
|
||||
* @throws NullPointerException if the specified element is null
|
||||
*/
|
||||
public boolean offerFirst(E e) {
|
||||
addFirst(e);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the specified element at the end of this deque.
|
||||
*
|
||||
* @param e the element to add
|
||||
* @return {@code true} (as specified by {@link Deque#offerLast})
|
||||
* @throws NullPointerException if the specified element is null
|
||||
*/
|
||||
public boolean offerLast(E e) {
|
||||
addLast(e);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NoSuchElementException {@inheritDoc}
|
||||
*/
|
||||
public E removeFirst() {
|
||||
E x = pollFirst();
|
||||
if (x == null)
|
||||
throw new NoSuchElementException();
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NoSuchElementException {@inheritDoc}
|
||||
*/
|
||||
public E removeLast() {
|
||||
E x = pollLast();
|
||||
if (x == null)
|
||||
throw new NoSuchElementException();
|
||||
return x;
|
||||
}
|
||||
|
||||
public E pollFirst() {
|
||||
int h = head;
|
||||
@SuppressWarnings("unchecked")
|
||||
E result = (E) elements[h];
|
||||
// Element is null if deque empty
|
||||
if (result == null)
|
||||
return null;
|
||||
elements[h] = null; // Must null out slot
|
||||
head = (h + 1) & (elements.length - 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
public E pollLast() {
|
||||
int t = (tail - 1) & (elements.length - 1);
|
||||
@SuppressWarnings("unchecked")
|
||||
E result = (E) elements[t];
|
||||
if (result == null)
|
||||
return null;
|
||||
elements[t] = null;
|
||||
tail = t;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NoSuchElementException {@inheritDoc}
|
||||
*/
|
||||
public E getFirst() {
|
||||
@SuppressWarnings("unchecked")
|
||||
E result = (E) elements[head];
|
||||
if (result == null)
|
||||
throw new NoSuchElementException();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NoSuchElementException {@inheritDoc}
|
||||
*/
|
||||
public E getLast() {
|
||||
@SuppressWarnings("unchecked")
|
||||
E result = (E) elements[(tail - 1) & (elements.length - 1)];
|
||||
if (result == null)
|
||||
throw new NoSuchElementException();
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public E peekFirst() {
|
||||
// elements[head] is null if deque empty
|
||||
return (E) elements[head];
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public E peekLast() {
|
||||
return (E) elements[(tail - 1) & (elements.length - 1)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the first occurrence of the specified element in this
|
||||
* deque (when traversing the deque from head to tail).
|
||||
* If the deque does not contain the element, it is unchanged.
|
||||
* More formally, removes the first element {@code e} such that
|
||||
* {@code o.equals(e)} (if such an element exists).
|
||||
* Returns {@code true} if this deque contained the specified element
|
||||
* (or equivalently, if this deque changed as a result of the call).
|
||||
*
|
||||
* @param o element to be removed from this deque, if present
|
||||
* @return {@code true} if the deque contained the specified element
|
||||
*/
|
||||
public boolean removeFirstOccurrence(Object o) {
|
||||
if (o == null)
|
||||
return false;
|
||||
int mask = elements.length - 1;
|
||||
int i = head;
|
||||
Object x;
|
||||
while ( (x = elements[i]) != null) {
|
||||
if (o.equals(x)) {
|
||||
delete(i);
|
||||
return true;
|
||||
}
|
||||
i = (i + 1) & mask;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the last occurrence of the specified element in this
|
||||
* deque (when traversing the deque from head to tail).
|
||||
* If the deque does not contain the element, it is unchanged.
|
||||
* More formally, removes the last element {@code e} such that
|
||||
* {@code o.equals(e)} (if such an element exists).
|
||||
* Returns {@code true} if this deque contained the specified element
|
||||
* (or equivalently, if this deque changed as a result of the call).
|
||||
*
|
||||
* @param o element to be removed from this deque, if present
|
||||
* @return {@code true} if the deque contained the specified element
|
||||
*/
|
||||
public boolean removeLastOccurrence(Object o) {
|
||||
if (o == null)
|
||||
return false;
|
||||
int mask = elements.length - 1;
|
||||
int i = (tail - 1) & mask;
|
||||
Object x;
|
||||
while ( (x = elements[i]) != null) {
|
||||
if (o.equals(x)) {
|
||||
delete(i);
|
||||
return true;
|
||||
}
|
||||
i = (i - 1) & mask;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// *** Queue methods ***
|
||||
|
||||
/**
|
||||
* Inserts the specified element at the end of this deque.
|
||||
*
|
||||
* <p>This method is equivalent to {@link #addLast}.
|
||||
*
|
||||
* @param e the element to add
|
||||
* @return {@code true} (as specified by {@link Collection#add})
|
||||
* @throws NullPointerException if the specified element is null
|
||||
*/
|
||||
public boolean add(E e) {
|
||||
addLast(e);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the specified element at the end of this deque.
|
||||
*
|
||||
* <p>This method is equivalent to {@link #offerLast}.
|
||||
*
|
||||
* @param e the element to add
|
||||
* @return {@code true} (as specified by {@link Queue#offer})
|
||||
* @throws NullPointerException if the specified element is null
|
||||
*/
|
||||
public boolean offer(E e) {
|
||||
return offerLast(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves and removes the head of the queue represented by this deque.
|
||||
*
|
||||
* This method differs from {@link #poll poll} only in that it throws an
|
||||
* exception if this deque is empty.
|
||||
*
|
||||
* <p>This method is equivalent to {@link #removeFirst}.
|
||||
*
|
||||
* @return the head of the queue represented by this deque
|
||||
* @throws NoSuchElementException {@inheritDoc}
|
||||
*/
|
||||
public E remove() {
|
||||
return removeFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves and removes the head of the queue represented by this deque
|
||||
* (in other words, the first element of this deque), or returns
|
||||
* {@code null} if this deque is empty.
|
||||
*
|
||||
* <p>This method is equivalent to {@link #pollFirst}.
|
||||
*
|
||||
* @return the head of the queue represented by this deque, or
|
||||
* {@code null} if this deque is empty
|
||||
*/
|
||||
public E poll() {
|
||||
return pollFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves, but does not remove, the head of the queue represented by
|
||||
* this deque. This method differs from {@link #peek peek} only in
|
||||
* that it throws an exception if this deque is empty.
|
||||
*
|
||||
* <p>This method is equivalent to {@link #getFirst}.
|
||||
*
|
||||
* @return the head of the queue represented by this deque
|
||||
* @throws NoSuchElementException {@inheritDoc}
|
||||
*/
|
||||
public E element() {
|
||||
return getFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves, but does not remove, the head of the queue represented by
|
||||
* this deque, or returns {@code null} if this deque is empty.
|
||||
*
|
||||
* <p>This method is equivalent to {@link #peekFirst}.
|
||||
*
|
||||
* @return the head of the queue represented by this deque, or
|
||||
* {@code null} if this deque is empty
|
||||
*/
|
||||
public E peek() {
|
||||
return peekFirst();
|
||||
}
|
||||
|
||||
// *** Stack methods ***
|
||||
|
||||
/**
|
||||
* Pushes an element onto the stack represented by this deque. In other
|
||||
* words, inserts the element at the front of this deque.
|
||||
*
|
||||
* <p>This method is equivalent to {@link #addFirst}.
|
||||
*
|
||||
* @param e the element to push
|
||||
* @throws NullPointerException if the specified element is null
|
||||
*/
|
||||
public void push(E e) {
|
||||
addFirst(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pops an element from the stack represented by this deque. In other
|
||||
* words, removes and returns the first element of this deque.
|
||||
*
|
||||
* <p>This method is equivalent to {@link #removeFirst()}.
|
||||
*
|
||||
* @return the element at the front of this deque (which is the top
|
||||
* of the stack represented by this deque)
|
||||
* @throws NoSuchElementException {@inheritDoc}
|
||||
*/
|
||||
public E pop() {
|
||||
return removeFirst();
|
||||
}
|
||||
|
||||
private void checkInvariants() {
|
||||
assert elements[tail] == null;
|
||||
assert head == tail ? elements[head] == null :
|
||||
(elements[head] != null &&
|
||||
elements[(tail - 1) & (elements.length - 1)] != null);
|
||||
assert elements[(head - 1) & (elements.length - 1)] == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the element at the specified position in the elements array,
|
||||
* adjusting head and tail as necessary. This can result in motion of
|
||||
* elements backwards or forwards in the array.
|
||||
*
|
||||
* <p>This method is called delete rather than remove to emphasize
|
||||
* that its semantics differ from those of {@link List#remove(int)}.
|
||||
*
|
||||
* @return true if elements moved backwards
|
||||
*/
|
||||
private boolean delete(int i) {
|
||||
checkInvariants();
|
||||
final Object[] elements = this.elements;
|
||||
final int mask = elements.length - 1;
|
||||
final int h = head;
|
||||
final int t = tail;
|
||||
final int front = (i - h) & mask;
|
||||
final int back = (t - i) & mask;
|
||||
|
||||
// Invariant: head <= i < tail mod circularity
|
||||
if (front >= ((t - h) & mask))
|
||||
throw new ConcurrentModificationException();
|
||||
|
||||
// Optimize for least element motion
|
||||
if (front < back) {
|
||||
if (h <= i) {
|
||||
System.arraycopy(elements, h, elements, h + 1, front);
|
||||
} else { // Wrap around
|
||||
System.arraycopy(elements, 0, elements, 1, i);
|
||||
elements[0] = elements[mask];
|
||||
System.arraycopy(elements, h, elements, h + 1, mask - h);
|
||||
}
|
||||
elements[h] = null;
|
||||
head = (h + 1) & mask;
|
||||
return false;
|
||||
} else {
|
||||
if (i < t) { // Copy the null tail as well
|
||||
System.arraycopy(elements, i + 1, elements, i, back);
|
||||
tail = t - 1;
|
||||
} else { // Wrap around
|
||||
System.arraycopy(elements, i + 1, elements, i, mask - i);
|
||||
elements[mask] = elements[0];
|
||||
System.arraycopy(elements, 1, elements, 0, t);
|
||||
tail = (t - 1) & mask;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// *** Collection Methods ***
|
||||
|
||||
/**
|
||||
* Returns the number of elements in this deque.
|
||||
*
|
||||
* @return the number of elements in this deque
|
||||
*/
|
||||
public int size() {
|
||||
return (tail - head) & (elements.length - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this deque contains no elements.
|
||||
*
|
||||
* @return {@code true} if this deque contains no elements
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return head == tail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator over the elements in this deque. The elements
|
||||
* will be ordered from first (head) to last (tail). This is the same
|
||||
* order that elements would be dequeued (via successive calls to
|
||||
* {@link #remove} or popped (via successive calls to {@link #pop}).
|
||||
*
|
||||
* @return an iterator over the elements in this deque
|
||||
*/
|
||||
public Iterator<E> iterator() {
|
||||
return new DeqIterator();
|
||||
}
|
||||
|
||||
public Iterator<E> descendingIterator() {
|
||||
return new DescendingIterator();
|
||||
}
|
||||
|
||||
private class DeqIterator implements Iterator<E> {
|
||||
/**
|
||||
* Index of element to be returned by subsequent call to next.
|
||||
*/
|
||||
private int cursor = head;
|
||||
|
||||
/**
|
||||
* Tail recorded at construction (also in remove), to stop
|
||||
* iterator and also to check for comodification.
|
||||
*/
|
||||
private int fence = tail;
|
||||
|
||||
/**
|
||||
* Index of element returned by most recent call to next.
|
||||
* Reset to -1 if element is deleted by a call to remove.
|
||||
*/
|
||||
private int lastRet = -1;
|
||||
|
||||
public boolean hasNext() {
|
||||
return cursor != fence;
|
||||
}
|
||||
|
||||
public E next() {
|
||||
if (cursor == fence)
|
||||
throw new NoSuchElementException();
|
||||
@SuppressWarnings("unchecked")
|
||||
E result = (E) elements[cursor];
|
||||
// This check doesn't catch all possible comodifications,
|
||||
// but does catch the ones that corrupt traversal
|
||||
if (tail != fence || result == null)
|
||||
throw new ConcurrentModificationException();
|
||||
lastRet = cursor;
|
||||
cursor = (cursor + 1) & (elements.length - 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
if (lastRet < 0)
|
||||
throw new IllegalStateException();
|
||||
if (delete(lastRet)) { // if left-shifted, undo increment in next()
|
||||
cursor = (cursor - 1) & (elements.length - 1);
|
||||
fence = tail;
|
||||
}
|
||||
lastRet = -1;
|
||||
}
|
||||
|
||||
public void forEachRemaining(Consumer<? super E> action) {
|
||||
Objects.requireNonNull(action);
|
||||
Object[] a = elements;
|
||||
int m = a.length - 1, f = fence, i = cursor;
|
||||
cursor = f;
|
||||
while (i != f) {
|
||||
@SuppressWarnings("unchecked") E e = (E)a[i];
|
||||
i = (i + 1) & m;
|
||||
if (e == null)
|
||||
throw new ConcurrentModificationException();
|
||||
action.accept(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class DescendingIterator implements Iterator<E> {
|
||||
/*
|
||||
* This class is nearly a mirror-image of DeqIterator, using
|
||||
* tail instead of head for initial cursor, and head instead of
|
||||
* tail for fence.
|
||||
*/
|
||||
private int cursor = tail;
|
||||
private int fence = head;
|
||||
private int lastRet = -1;
|
||||
|
||||
public boolean hasNext() {
|
||||
return cursor != fence;
|
||||
}
|
||||
|
||||
public E next() {
|
||||
if (cursor == fence)
|
||||
throw new NoSuchElementException();
|
||||
cursor = (cursor - 1) & (elements.length - 1);
|
||||
@SuppressWarnings("unchecked")
|
||||
E result = (E) elements[cursor];
|
||||
if (head != fence || result == null)
|
||||
throw new ConcurrentModificationException();
|
||||
lastRet = cursor;
|
||||
return result;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
if (lastRet < 0)
|
||||
throw new IllegalStateException();
|
||||
if (!delete(lastRet)) {
|
||||
cursor = (cursor + 1) & (elements.length - 1);
|
||||
fence = head;
|
||||
}
|
||||
lastRet = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this deque contains the specified element.
|
||||
* More formally, returns {@code true} if and only if this deque contains
|
||||
* at least one element {@code e} such that {@code o.equals(e)}.
|
||||
*
|
||||
* @param o object to be checked for containment in this deque
|
||||
* @return {@code true} if this deque contains the specified element
|
||||
*/
|
||||
public boolean contains(Object o) {
|
||||
if (o == null)
|
||||
return false;
|
||||
int mask = elements.length - 1;
|
||||
int i = head;
|
||||
Object x;
|
||||
while ( (x = elements[i]) != null) {
|
||||
if (o.equals(x))
|
||||
return true;
|
||||
i = (i + 1) & mask;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a single instance of the specified element from this deque.
|
||||
* If the deque does not contain the element, it is unchanged.
|
||||
* More formally, removes the first element {@code e} such that
|
||||
* {@code o.equals(e)} (if such an element exists).
|
||||
* Returns {@code true} if this deque contained the specified element
|
||||
* (or equivalently, if this deque changed as a result of the call).
|
||||
*
|
||||
* <p>This method is equivalent to {@link #removeFirstOccurrence(Object)}.
|
||||
*
|
||||
* @param o element to be removed from this deque, if present
|
||||
* @return {@code true} if this deque contained the specified element
|
||||
*/
|
||||
public boolean remove(Object o) {
|
||||
return removeFirstOccurrence(o);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all of the elements from this deque.
|
||||
* The deque will be empty after this call returns.
|
||||
*/
|
||||
public void clear() {
|
||||
int h = head;
|
||||
int t = tail;
|
||||
if (h != t) { // clear all cells
|
||||
head = tail = 0;
|
||||
int i = h;
|
||||
int mask = elements.length - 1;
|
||||
do {
|
||||
elements[i] = null;
|
||||
i = (i + 1) & mask;
|
||||
} while (i != t);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing all of the elements in this deque
|
||||
* in proper sequence (from first to last element).
|
||||
*
|
||||
* <p>The returned array will be "safe" in that no references to it are
|
||||
* maintained by this deque. (In other words, this method must allocate
|
||||
* a new array). The caller is thus free to modify the returned array.
|
||||
*
|
||||
* <p>This method acts as bridge between array-based and collection-based
|
||||
* APIs.
|
||||
*
|
||||
* @return an array containing all of the elements in this deque
|
||||
*/
|
||||
public Object[] toArray() {
|
||||
return copyElements(new Object[size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing all of the elements in this deque in
|
||||
* proper sequence (from first to last element); the runtime type of the
|
||||
* returned array is that of the specified array. If the deque fits in
|
||||
* the specified array, it is returned therein. Otherwise, a new array
|
||||
* is allocated with the runtime type of the specified array and the
|
||||
* size of this deque.
|
||||
*
|
||||
* <p>If this deque fits in the specified array with room to spare
|
||||
* (i.e., the array has more elements than this deque), the element in
|
||||
* the array immediately following the end of the deque is set to
|
||||
* {@code null}.
|
||||
*
|
||||
* <p>Like the {@link #toArray()} method, this method acts as bridge between
|
||||
* array-based and collection-based APIs. Further, this method allows
|
||||
* precise control over the runtime type of the output array, and may,
|
||||
* under certain circumstances, be used to save allocation costs.
|
||||
*
|
||||
* <p>Suppose {@code x} is a deque known to contain only strings.
|
||||
* The following code can be used to dump the deque into a newly
|
||||
* allocated array of {@code String}:
|
||||
*
|
||||
* <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
|
||||
*
|
||||
* Note that {@code toArray(new Object[0])} is identical in function to
|
||||
* {@code toArray()}.
|
||||
*
|
||||
* @param a the array into which the elements of the deque are to
|
||||
* be stored, if it is big enough; otherwise, a new array of the
|
||||
* same runtime type is allocated for this purpose
|
||||
* @return an array containing all of the elements in this deque
|
||||
* @throws ArrayStoreException if the runtime type of the specified array
|
||||
* is not a supertype of the runtime type of every element in
|
||||
* this deque
|
||||
* @throws NullPointerException if the specified array is null
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T[] toArray(T[] a) {
|
||||
int size = size();
|
||||
if (a.length < size)
|
||||
a = (T[])java.lang.reflect.Array.newInstance(
|
||||
a.getClass().getComponentType(), size);
|
||||
copyElements(a);
|
||||
if (a.length > size)
|
||||
a[size] = null;
|
||||
return a;
|
||||
}
|
||||
|
||||
// *** Object methods ***
|
||||
|
||||
/**
|
||||
* Returns a copy of this deque.
|
||||
*
|
||||
* @return a copy of this deque
|
||||
*/
|
||||
public ArrayDeque<E> clone() {
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
ArrayDeque<E> result = (ArrayDeque<E>) super.clone();
|
||||
result.elements = Arrays.copyOf(elements, elements.length);
|
||||
return result;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 2340985798034038923L;
|
||||
|
||||
/**
|
||||
* Saves this deque to a stream (that is, serializes it).
|
||||
*
|
||||
* @serialData The current size ({@code int}) of the deque,
|
||||
* followed by all of its elements (each an object reference) in
|
||||
* first-to-last order.
|
||||
*/
|
||||
private void writeObject(java.io.ObjectOutputStream s)
|
||||
throws java.io.IOException {
|
||||
s.defaultWriteObject();
|
||||
|
||||
// Write out size
|
||||
s.writeInt(size());
|
||||
|
||||
// Write out elements in order.
|
||||
int mask = elements.length - 1;
|
||||
for (int i = head; i != tail; i = (i + 1) & mask)
|
||||
s.writeObject(elements[i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconstitutes this deque from a stream (that is, deserializes it).
|
||||
*/
|
||||
private void readObject(java.io.ObjectInputStream s)
|
||||
throws java.io.IOException, ClassNotFoundException {
|
||||
s.defaultReadObject();
|
||||
|
||||
// Read in size and allocate array
|
||||
int size = s.readInt();
|
||||
int capacity = calculateSize(size);
|
||||
SharedSecrets.getJavaOISAccess().checkArray(s, Object[].class, capacity);
|
||||
allocateElements(size);
|
||||
head = 0;
|
||||
tail = size;
|
||||
|
||||
// Read in all elements in the proper order.
|
||||
for (int i = 0; i < size; i++)
|
||||
elements[i] = s.readObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
|
||||
* and <em>fail-fast</em> {@link Spliterator} over the elements in this
|
||||
* deque.
|
||||
*
|
||||
* <p>The {@code Spliterator} reports {@link Spliterator#SIZED},
|
||||
* {@link Spliterator#SUBSIZED}, {@link Spliterator#ORDERED}, and
|
||||
* {@link Spliterator#NONNULL}. Overriding implementations should document
|
||||
* the reporting of additional characteristic values.
|
||||
*
|
||||
* @return a {@code Spliterator} over the elements in this deque
|
||||
* @since 1.8
|
||||
*/
|
||||
public Spliterator<E> spliterator() {
|
||||
return new DeqSpliterator<E>(this, -1, -1);
|
||||
}
|
||||
|
||||
static final class DeqSpliterator<E> implements Spliterator<E> {
|
||||
private final ArrayDeque<E> deq;
|
||||
private int fence; // -1 until first use
|
||||
private int index; // current index, modified on traverse/split
|
||||
|
||||
/** Creates new spliterator covering the given array and range */
|
||||
DeqSpliterator(ArrayDeque<E> deq, int origin, int fence) {
|
||||
this.deq = deq;
|
||||
this.index = origin;
|
||||
this.fence = fence;
|
||||
}
|
||||
|
||||
private int getFence() { // force initialization
|
||||
int t;
|
||||
if ((t = fence) < 0) {
|
||||
t = fence = deq.tail;
|
||||
index = deq.head;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
public DeqSpliterator<E> trySplit() {
|
||||
int t = getFence(), h = index, n = deq.elements.length;
|
||||
if (h != t && ((h + 1) & (n - 1)) != t) {
|
||||
if (h > t)
|
||||
t += n;
|
||||
int m = ((h + t) >>> 1) & (n - 1);
|
||||
return new DeqSpliterator<>(deq, h, index = m);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void forEachRemaining(Consumer<? super E> consumer) {
|
||||
if (consumer == null)
|
||||
throw new NullPointerException();
|
||||
Object[] a = deq.elements;
|
||||
int m = a.length - 1, f = getFence(), i = index;
|
||||
index = f;
|
||||
while (i != f) {
|
||||
@SuppressWarnings("unchecked") E e = (E)a[i];
|
||||
i = (i + 1) & m;
|
||||
if (e == null)
|
||||
throw new ConcurrentModificationException();
|
||||
consumer.accept(e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean tryAdvance(Consumer<? super E> consumer) {
|
||||
if (consumer == null)
|
||||
throw new NullPointerException();
|
||||
Object[] a = deq.elements;
|
||||
int m = a.length - 1, f = getFence(), i = index;
|
||||
if (i != fence) {
|
||||
@SuppressWarnings("unchecked") E e = (E)a[i];
|
||||
index = (i + 1) & m;
|
||||
if (e == null)
|
||||
throw new ConcurrentModificationException();
|
||||
consumer.accept(e);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public long estimateSize() {
|
||||
int n = getFence() - index;
|
||||
if (n < 0)
|
||||
n += deq.elements.length;
|
||||
return (long) n;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int characteristics() {
|
||||
return Spliterator.ORDERED | Spliterator.SIZED |
|
||||
Spliterator.NONNULL | Spliterator.SUBSIZED;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
1474
jdkSrc/jdk8/java/util/ArrayList.java
Normal file
1474
jdkSrc/jdk8/java/util/ArrayList.java
Normal file
File diff suppressed because it is too large
Load Diff
696
jdkSrc/jdk8/java/util/ArrayPrefixHelpers.java
Normal file
696
jdkSrc/jdk8/java/util/ArrayPrefixHelpers.java
Normal file
@@ -0,0 +1,696 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.util;
|
||||
|
||||
/*
|
||||
* Written by Doug Lea with assistance from members of JCP JSR-166
|
||||
* Expert Group and released to the public domain, as explained at
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.CountedCompleter;
|
||||
import java.util.function.BinaryOperator;
|
||||
import java.util.function.IntBinaryOperator;
|
||||
import java.util.function.LongBinaryOperator;
|
||||
import java.util.function.DoubleBinaryOperator;
|
||||
|
||||
/**
|
||||
* ForkJoin tasks to perform Arrays.parallelPrefix operations.
|
||||
*
|
||||
* @author Doug Lea
|
||||
* @since 1.8
|
||||
*/
|
||||
class ArrayPrefixHelpers {
|
||||
private ArrayPrefixHelpers() {}; // non-instantiable
|
||||
|
||||
/*
|
||||
* Parallel prefix (aka cumulate, scan) task classes
|
||||
* are based loosely on Guy Blelloch's original
|
||||
* algorithm (http://www.cs.cmu.edu/~scandal/alg/scan.html):
|
||||
* Keep dividing by two to threshold segment size, and then:
|
||||
* Pass 1: Create tree of partial sums for each segment
|
||||
* Pass 2: For each segment, cumulate with offset of left sibling
|
||||
*
|
||||
* This version improves performance within FJ framework mainly by
|
||||
* allowing the second pass of ready left-hand sides to proceed
|
||||
* even if some right-hand side first passes are still executing.
|
||||
* It also combines first and second pass for leftmost segment,
|
||||
* and skips the first pass for rightmost segment (whose result is
|
||||
* not needed for second pass). It similarly manages to avoid
|
||||
* requiring that users supply an identity basis for accumulations
|
||||
* by tracking those segments/subtasks for which the first
|
||||
* existing element is used as base.
|
||||
*
|
||||
* Managing this relies on ORing some bits in the pendingCount for
|
||||
* phases/states: CUMULATE, SUMMED, and FINISHED. CUMULATE is the
|
||||
* main phase bit. When false, segments compute only their sum.
|
||||
* When true, they cumulate array elements. CUMULATE is set at
|
||||
* root at beginning of second pass and then propagated down. But
|
||||
* it may also be set earlier for subtrees with lo==0 (the left
|
||||
* spine of tree). SUMMED is a one bit join count. For leafs, it
|
||||
* is set when summed. For internal nodes, it becomes true when
|
||||
* one child is summed. When the second child finishes summing,
|
||||
* we then moves up tree to trigger the cumulate phase. FINISHED
|
||||
* is also a one bit join count. For leafs, it is set when
|
||||
* cumulated. For internal nodes, it becomes true when one child
|
||||
* is cumulated. When the second child finishes cumulating, it
|
||||
* then moves up tree, completing at the root.
|
||||
*
|
||||
* To better exploit locality and reduce overhead, the compute
|
||||
* method loops starting with the current task, moving if possible
|
||||
* to one of its subtasks rather than forking.
|
||||
*
|
||||
* As usual for this sort of utility, there are 4 versions, that
|
||||
* are simple copy/paste/adapt variants of each other. (The
|
||||
* double and int versions differ from long version soley by
|
||||
* replacing "long" (with case-matching)).
|
||||
*/
|
||||
|
||||
// see above
|
||||
static final int CUMULATE = 1;
|
||||
static final int SUMMED = 2;
|
||||
static final int FINISHED = 4;
|
||||
|
||||
/** The smallest subtask array partition size to use as threshold */
|
||||
static final int MIN_PARTITION = 16;
|
||||
|
||||
static final class CumulateTask<T> extends CountedCompleter<Void> {
|
||||
final T[] array;
|
||||
final BinaryOperator<T> function;
|
||||
CumulateTask<T> left, right;
|
||||
T in, out;
|
||||
final int lo, hi, origin, fence, threshold;
|
||||
|
||||
/** Root task constructor */
|
||||
public CumulateTask(CumulateTask<T> parent,
|
||||
BinaryOperator<T> function,
|
||||
T[] array, int lo, int hi) {
|
||||
super(parent);
|
||||
this.function = function; this.array = array;
|
||||
this.lo = this.origin = lo; this.hi = this.fence = hi;
|
||||
int p;
|
||||
this.threshold =
|
||||
(p = (hi - lo) / (ForkJoinPool.getCommonPoolParallelism() << 3))
|
||||
<= MIN_PARTITION ? MIN_PARTITION : p;
|
||||
}
|
||||
|
||||
/** Subtask constructor */
|
||||
CumulateTask(CumulateTask<T> parent, BinaryOperator<T> function,
|
||||
T[] array, int origin, int fence, int threshold,
|
||||
int lo, int hi) {
|
||||
super(parent);
|
||||
this.function = function; this.array = array;
|
||||
this.origin = origin; this.fence = fence;
|
||||
this.threshold = threshold;
|
||||
this.lo = lo; this.hi = hi;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public final void compute() {
|
||||
final BinaryOperator<T> fn;
|
||||
final T[] a;
|
||||
if ((fn = this.function) == null || (a = this.array) == null)
|
||||
throw new NullPointerException(); // hoist checks
|
||||
int th = threshold, org = origin, fnc = fence, l, h;
|
||||
CumulateTask<T> t = this;
|
||||
outer: while ((l = t.lo) >= 0 && (h = t.hi) <= a.length) {
|
||||
if (h - l > th) {
|
||||
CumulateTask<T> lt = t.left, rt = t.right, f;
|
||||
if (lt == null) { // first pass
|
||||
int mid = (l + h) >>> 1;
|
||||
f = rt = t.right =
|
||||
new CumulateTask<T>(t, fn, a, org, fnc, th, mid, h);
|
||||
t = lt = t.left =
|
||||
new CumulateTask<T>(t, fn, a, org, fnc, th, l, mid);
|
||||
}
|
||||
else { // possibly refork
|
||||
T pin = t.in;
|
||||
lt.in = pin;
|
||||
f = t = null;
|
||||
if (rt != null) {
|
||||
T lout = lt.out;
|
||||
rt.in = (l == org ? lout :
|
||||
fn.apply(pin, lout));
|
||||
for (int c;;) {
|
||||
if (((c = rt.getPendingCount()) & CUMULATE) != 0)
|
||||
break;
|
||||
if (rt.compareAndSetPendingCount(c, c|CUMULATE)){
|
||||
t = rt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int c;;) {
|
||||
if (((c = lt.getPendingCount()) & CUMULATE) != 0)
|
||||
break;
|
||||
if (lt.compareAndSetPendingCount(c, c|CUMULATE)) {
|
||||
if (t != null)
|
||||
f = t;
|
||||
t = lt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (t == null)
|
||||
break;
|
||||
}
|
||||
if (f != null)
|
||||
f.fork();
|
||||
}
|
||||
else {
|
||||
int state; // Transition to sum, cumulate, or both
|
||||
for (int b;;) {
|
||||
if (((b = t.getPendingCount()) & FINISHED) != 0)
|
||||
break outer; // already done
|
||||
state = ((b & CUMULATE) != 0? FINISHED :
|
||||
(l > org) ? SUMMED : (SUMMED|FINISHED));
|
||||
if (t.compareAndSetPendingCount(b, b|state))
|
||||
break;
|
||||
}
|
||||
|
||||
T sum;
|
||||
if (state != SUMMED) {
|
||||
int first;
|
||||
if (l == org) { // leftmost; no in
|
||||
sum = a[org];
|
||||
first = org + 1;
|
||||
}
|
||||
else {
|
||||
sum = t.in;
|
||||
first = l;
|
||||
}
|
||||
for (int i = first; i < h; ++i) // cumulate
|
||||
a[i] = sum = fn.apply(sum, a[i]);
|
||||
}
|
||||
else if (h < fnc) { // skip rightmost
|
||||
sum = a[l];
|
||||
for (int i = l + 1; i < h; ++i) // sum only
|
||||
sum = fn.apply(sum, a[i]);
|
||||
}
|
||||
else
|
||||
sum = t.in;
|
||||
t.out = sum;
|
||||
for (CumulateTask<T> par;;) { // propagate
|
||||
if ((par = (CumulateTask<T>)t.getCompleter()) == null) {
|
||||
if ((state & FINISHED) != 0) // enable join
|
||||
t.quietlyComplete();
|
||||
break outer;
|
||||
}
|
||||
int b = par.getPendingCount();
|
||||
if ((b & state & FINISHED) != 0)
|
||||
t = par; // both done
|
||||
else if ((b & state & SUMMED) != 0) { // both summed
|
||||
int nextState; CumulateTask<T> lt, rt;
|
||||
if ((lt = par.left) != null &&
|
||||
(rt = par.right) != null) {
|
||||
T lout = lt.out;
|
||||
par.out = (rt.hi == fnc ? lout :
|
||||
fn.apply(lout, rt.out));
|
||||
}
|
||||
int refork = (((b & CUMULATE) == 0 &&
|
||||
par.lo == org) ? CUMULATE : 0);
|
||||
if ((nextState = b|state|refork) == b ||
|
||||
par.compareAndSetPendingCount(b, nextState)) {
|
||||
state = SUMMED; // drop finished
|
||||
t = par;
|
||||
if (refork != 0)
|
||||
par.fork();
|
||||
}
|
||||
}
|
||||
else if (par.compareAndSetPendingCount(b, b|state))
|
||||
break outer; // sib not ready
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static final class LongCumulateTask extends CountedCompleter<Void> {
|
||||
final long[] array;
|
||||
final LongBinaryOperator function;
|
||||
LongCumulateTask left, right;
|
||||
long in, out;
|
||||
final int lo, hi, origin, fence, threshold;
|
||||
|
||||
/** Root task constructor */
|
||||
public LongCumulateTask(LongCumulateTask parent,
|
||||
LongBinaryOperator function,
|
||||
long[] array, int lo, int hi) {
|
||||
super(parent);
|
||||
this.function = function; this.array = array;
|
||||
this.lo = this.origin = lo; this.hi = this.fence = hi;
|
||||
int p;
|
||||
this.threshold =
|
||||
(p = (hi - lo) / (ForkJoinPool.getCommonPoolParallelism() << 3))
|
||||
<= MIN_PARTITION ? MIN_PARTITION : p;
|
||||
}
|
||||
|
||||
/** Subtask constructor */
|
||||
LongCumulateTask(LongCumulateTask parent, LongBinaryOperator function,
|
||||
long[] array, int origin, int fence, int threshold,
|
||||
int lo, int hi) {
|
||||
super(parent);
|
||||
this.function = function; this.array = array;
|
||||
this.origin = origin; this.fence = fence;
|
||||
this.threshold = threshold;
|
||||
this.lo = lo; this.hi = hi;
|
||||
}
|
||||
|
||||
public final void compute() {
|
||||
final LongBinaryOperator fn;
|
||||
final long[] a;
|
||||
if ((fn = this.function) == null || (a = this.array) == null)
|
||||
throw new NullPointerException(); // hoist checks
|
||||
int th = threshold, org = origin, fnc = fence, l, h;
|
||||
LongCumulateTask t = this;
|
||||
outer: while ((l = t.lo) >= 0 && (h = t.hi) <= a.length) {
|
||||
if (h - l > th) {
|
||||
LongCumulateTask lt = t.left, rt = t.right, f;
|
||||
if (lt == null) { // first pass
|
||||
int mid = (l + h) >>> 1;
|
||||
f = rt = t.right =
|
||||
new LongCumulateTask(t, fn, a, org, fnc, th, mid, h);
|
||||
t = lt = t.left =
|
||||
new LongCumulateTask(t, fn, a, org, fnc, th, l, mid);
|
||||
}
|
||||
else { // possibly refork
|
||||
long pin = t.in;
|
||||
lt.in = pin;
|
||||
f = t = null;
|
||||
if (rt != null) {
|
||||
long lout = lt.out;
|
||||
rt.in = (l == org ? lout :
|
||||
fn.applyAsLong(pin, lout));
|
||||
for (int c;;) {
|
||||
if (((c = rt.getPendingCount()) & CUMULATE) != 0)
|
||||
break;
|
||||
if (rt.compareAndSetPendingCount(c, c|CUMULATE)){
|
||||
t = rt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int c;;) {
|
||||
if (((c = lt.getPendingCount()) & CUMULATE) != 0)
|
||||
break;
|
||||
if (lt.compareAndSetPendingCount(c, c|CUMULATE)) {
|
||||
if (t != null)
|
||||
f = t;
|
||||
t = lt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (t == null)
|
||||
break;
|
||||
}
|
||||
if (f != null)
|
||||
f.fork();
|
||||
}
|
||||
else {
|
||||
int state; // Transition to sum, cumulate, or both
|
||||
for (int b;;) {
|
||||
if (((b = t.getPendingCount()) & FINISHED) != 0)
|
||||
break outer; // already done
|
||||
state = ((b & CUMULATE) != 0? FINISHED :
|
||||
(l > org) ? SUMMED : (SUMMED|FINISHED));
|
||||
if (t.compareAndSetPendingCount(b, b|state))
|
||||
break;
|
||||
}
|
||||
|
||||
long sum;
|
||||
if (state != SUMMED) {
|
||||
int first;
|
||||
if (l == org) { // leftmost; no in
|
||||
sum = a[org];
|
||||
first = org + 1;
|
||||
}
|
||||
else {
|
||||
sum = t.in;
|
||||
first = l;
|
||||
}
|
||||
for (int i = first; i < h; ++i) // cumulate
|
||||
a[i] = sum = fn.applyAsLong(sum, a[i]);
|
||||
}
|
||||
else if (h < fnc) { // skip rightmost
|
||||
sum = a[l];
|
||||
for (int i = l + 1; i < h; ++i) // sum only
|
||||
sum = fn.applyAsLong(sum, a[i]);
|
||||
}
|
||||
else
|
||||
sum = t.in;
|
||||
t.out = sum;
|
||||
for (LongCumulateTask par;;) { // propagate
|
||||
if ((par = (LongCumulateTask)t.getCompleter()) == null) {
|
||||
if ((state & FINISHED) != 0) // enable join
|
||||
t.quietlyComplete();
|
||||
break outer;
|
||||
}
|
||||
int b = par.getPendingCount();
|
||||
if ((b & state & FINISHED) != 0)
|
||||
t = par; // both done
|
||||
else if ((b & state & SUMMED) != 0) { // both summed
|
||||
int nextState; LongCumulateTask lt, rt;
|
||||
if ((lt = par.left) != null &&
|
||||
(rt = par.right) != null) {
|
||||
long lout = lt.out;
|
||||
par.out = (rt.hi == fnc ? lout :
|
||||
fn.applyAsLong(lout, rt.out));
|
||||
}
|
||||
int refork = (((b & CUMULATE) == 0 &&
|
||||
par.lo == org) ? CUMULATE : 0);
|
||||
if ((nextState = b|state|refork) == b ||
|
||||
par.compareAndSetPendingCount(b, nextState)) {
|
||||
state = SUMMED; // drop finished
|
||||
t = par;
|
||||
if (refork != 0)
|
||||
par.fork();
|
||||
}
|
||||
}
|
||||
else if (par.compareAndSetPendingCount(b, b|state))
|
||||
break outer; // sib not ready
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static final class DoubleCumulateTask extends CountedCompleter<Void> {
|
||||
final double[] array;
|
||||
final DoubleBinaryOperator function;
|
||||
DoubleCumulateTask left, right;
|
||||
double in, out;
|
||||
final int lo, hi, origin, fence, threshold;
|
||||
|
||||
/** Root task constructor */
|
||||
public DoubleCumulateTask(DoubleCumulateTask parent,
|
||||
DoubleBinaryOperator function,
|
||||
double[] array, int lo, int hi) {
|
||||
super(parent);
|
||||
this.function = function; this.array = array;
|
||||
this.lo = this.origin = lo; this.hi = this.fence = hi;
|
||||
int p;
|
||||
this.threshold =
|
||||
(p = (hi - lo) / (ForkJoinPool.getCommonPoolParallelism() << 3))
|
||||
<= MIN_PARTITION ? MIN_PARTITION : p;
|
||||
}
|
||||
|
||||
/** Subtask constructor */
|
||||
DoubleCumulateTask(DoubleCumulateTask parent, DoubleBinaryOperator function,
|
||||
double[] array, int origin, int fence, int threshold,
|
||||
int lo, int hi) {
|
||||
super(parent);
|
||||
this.function = function; this.array = array;
|
||||
this.origin = origin; this.fence = fence;
|
||||
this.threshold = threshold;
|
||||
this.lo = lo; this.hi = hi;
|
||||
}
|
||||
|
||||
public final void compute() {
|
||||
final DoubleBinaryOperator fn;
|
||||
final double[] a;
|
||||
if ((fn = this.function) == null || (a = this.array) == null)
|
||||
throw new NullPointerException(); // hoist checks
|
||||
int th = threshold, org = origin, fnc = fence, l, h;
|
||||
DoubleCumulateTask t = this;
|
||||
outer: while ((l = t.lo) >= 0 && (h = t.hi) <= a.length) {
|
||||
if (h - l > th) {
|
||||
DoubleCumulateTask lt = t.left, rt = t.right, f;
|
||||
if (lt == null) { // first pass
|
||||
int mid = (l + h) >>> 1;
|
||||
f = rt = t.right =
|
||||
new DoubleCumulateTask(t, fn, a, org, fnc, th, mid, h);
|
||||
t = lt = t.left =
|
||||
new DoubleCumulateTask(t, fn, a, org, fnc, th, l, mid);
|
||||
}
|
||||
else { // possibly refork
|
||||
double pin = t.in;
|
||||
lt.in = pin;
|
||||
f = t = null;
|
||||
if (rt != null) {
|
||||
double lout = lt.out;
|
||||
rt.in = (l == org ? lout :
|
||||
fn.applyAsDouble(pin, lout));
|
||||
for (int c;;) {
|
||||
if (((c = rt.getPendingCount()) & CUMULATE) != 0)
|
||||
break;
|
||||
if (rt.compareAndSetPendingCount(c, c|CUMULATE)){
|
||||
t = rt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int c;;) {
|
||||
if (((c = lt.getPendingCount()) & CUMULATE) != 0)
|
||||
break;
|
||||
if (lt.compareAndSetPendingCount(c, c|CUMULATE)) {
|
||||
if (t != null)
|
||||
f = t;
|
||||
t = lt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (t == null)
|
||||
break;
|
||||
}
|
||||
if (f != null)
|
||||
f.fork();
|
||||
}
|
||||
else {
|
||||
int state; // Transition to sum, cumulate, or both
|
||||
for (int b;;) {
|
||||
if (((b = t.getPendingCount()) & FINISHED) != 0)
|
||||
break outer; // already done
|
||||
state = ((b & CUMULATE) != 0? FINISHED :
|
||||
(l > org) ? SUMMED : (SUMMED|FINISHED));
|
||||
if (t.compareAndSetPendingCount(b, b|state))
|
||||
break;
|
||||
}
|
||||
|
||||
double sum;
|
||||
if (state != SUMMED) {
|
||||
int first;
|
||||
if (l == org) { // leftmost; no in
|
||||
sum = a[org];
|
||||
first = org + 1;
|
||||
}
|
||||
else {
|
||||
sum = t.in;
|
||||
first = l;
|
||||
}
|
||||
for (int i = first; i < h; ++i) // cumulate
|
||||
a[i] = sum = fn.applyAsDouble(sum, a[i]);
|
||||
}
|
||||
else if (h < fnc) { // skip rightmost
|
||||
sum = a[l];
|
||||
for (int i = l + 1; i < h; ++i) // sum only
|
||||
sum = fn.applyAsDouble(sum, a[i]);
|
||||
}
|
||||
else
|
||||
sum = t.in;
|
||||
t.out = sum;
|
||||
for (DoubleCumulateTask par;;) { // propagate
|
||||
if ((par = (DoubleCumulateTask)t.getCompleter()) == null) {
|
||||
if ((state & FINISHED) != 0) // enable join
|
||||
t.quietlyComplete();
|
||||
break outer;
|
||||
}
|
||||
int b = par.getPendingCount();
|
||||
if ((b & state & FINISHED) != 0)
|
||||
t = par; // both done
|
||||
else if ((b & state & SUMMED) != 0) { // both summed
|
||||
int nextState; DoubleCumulateTask lt, rt;
|
||||
if ((lt = par.left) != null &&
|
||||
(rt = par.right) != null) {
|
||||
double lout = lt.out;
|
||||
par.out = (rt.hi == fnc ? lout :
|
||||
fn.applyAsDouble(lout, rt.out));
|
||||
}
|
||||
int refork = (((b & CUMULATE) == 0 &&
|
||||
par.lo == org) ? CUMULATE : 0);
|
||||
if ((nextState = b|state|refork) == b ||
|
||||
par.compareAndSetPendingCount(b, nextState)) {
|
||||
state = SUMMED; // drop finished
|
||||
t = par;
|
||||
if (refork != 0)
|
||||
par.fork();
|
||||
}
|
||||
}
|
||||
else if (par.compareAndSetPendingCount(b, b|state))
|
||||
break outer; // sib not ready
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static final class IntCumulateTask extends CountedCompleter<Void> {
|
||||
final int[] array;
|
||||
final IntBinaryOperator function;
|
||||
IntCumulateTask left, right;
|
||||
int in, out;
|
||||
final int lo, hi, origin, fence, threshold;
|
||||
|
||||
/** Root task constructor */
|
||||
public IntCumulateTask(IntCumulateTask parent,
|
||||
IntBinaryOperator function,
|
||||
int[] array, int lo, int hi) {
|
||||
super(parent);
|
||||
this.function = function; this.array = array;
|
||||
this.lo = this.origin = lo; this.hi = this.fence = hi;
|
||||
int p;
|
||||
this.threshold =
|
||||
(p = (hi - lo) / (ForkJoinPool.getCommonPoolParallelism() << 3))
|
||||
<= MIN_PARTITION ? MIN_PARTITION : p;
|
||||
}
|
||||
|
||||
/** Subtask constructor */
|
||||
IntCumulateTask(IntCumulateTask parent, IntBinaryOperator function,
|
||||
int[] array, int origin, int fence, int threshold,
|
||||
int lo, int hi) {
|
||||
super(parent);
|
||||
this.function = function; this.array = array;
|
||||
this.origin = origin; this.fence = fence;
|
||||
this.threshold = threshold;
|
||||
this.lo = lo; this.hi = hi;
|
||||
}
|
||||
|
||||
public final void compute() {
|
||||
final IntBinaryOperator fn;
|
||||
final int[] a;
|
||||
if ((fn = this.function) == null || (a = this.array) == null)
|
||||
throw new NullPointerException(); // hoist checks
|
||||
int th = threshold, org = origin, fnc = fence, l, h;
|
||||
IntCumulateTask t = this;
|
||||
outer: while ((l = t.lo) >= 0 && (h = t.hi) <= a.length) {
|
||||
if (h - l > th) {
|
||||
IntCumulateTask lt = t.left, rt = t.right, f;
|
||||
if (lt == null) { // first pass
|
||||
int mid = (l + h) >>> 1;
|
||||
f = rt = t.right =
|
||||
new IntCumulateTask(t, fn, a, org, fnc, th, mid, h);
|
||||
t = lt = t.left =
|
||||
new IntCumulateTask(t, fn, a, org, fnc, th, l, mid);
|
||||
}
|
||||
else { // possibly refork
|
||||
int pin = t.in;
|
||||
lt.in = pin;
|
||||
f = t = null;
|
||||
if (rt != null) {
|
||||
int lout = lt.out;
|
||||
rt.in = (l == org ? lout :
|
||||
fn.applyAsInt(pin, lout));
|
||||
for (int c;;) {
|
||||
if (((c = rt.getPendingCount()) & CUMULATE) != 0)
|
||||
break;
|
||||
if (rt.compareAndSetPendingCount(c, c|CUMULATE)){
|
||||
t = rt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int c;;) {
|
||||
if (((c = lt.getPendingCount()) & CUMULATE) != 0)
|
||||
break;
|
||||
if (lt.compareAndSetPendingCount(c, c|CUMULATE)) {
|
||||
if (t != null)
|
||||
f = t;
|
||||
t = lt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (t == null)
|
||||
break;
|
||||
}
|
||||
if (f != null)
|
||||
f.fork();
|
||||
}
|
||||
else {
|
||||
int state; // Transition to sum, cumulate, or both
|
||||
for (int b;;) {
|
||||
if (((b = t.getPendingCount()) & FINISHED) != 0)
|
||||
break outer; // already done
|
||||
state = ((b & CUMULATE) != 0? FINISHED :
|
||||
(l > org) ? SUMMED : (SUMMED|FINISHED));
|
||||
if (t.compareAndSetPendingCount(b, b|state))
|
||||
break;
|
||||
}
|
||||
|
||||
int sum;
|
||||
if (state != SUMMED) {
|
||||
int first;
|
||||
if (l == org) { // leftmost; no in
|
||||
sum = a[org];
|
||||
first = org + 1;
|
||||
}
|
||||
else {
|
||||
sum = t.in;
|
||||
first = l;
|
||||
}
|
||||
for (int i = first; i < h; ++i) // cumulate
|
||||
a[i] = sum = fn.applyAsInt(sum, a[i]);
|
||||
}
|
||||
else if (h < fnc) { // skip rightmost
|
||||
sum = a[l];
|
||||
for (int i = l + 1; i < h; ++i) // sum only
|
||||
sum = fn.applyAsInt(sum, a[i]);
|
||||
}
|
||||
else
|
||||
sum = t.in;
|
||||
t.out = sum;
|
||||
for (IntCumulateTask par;;) { // propagate
|
||||
if ((par = (IntCumulateTask)t.getCompleter()) == null) {
|
||||
if ((state & FINISHED) != 0) // enable join
|
||||
t.quietlyComplete();
|
||||
break outer;
|
||||
}
|
||||
int b = par.getPendingCount();
|
||||
if ((b & state & FINISHED) != 0)
|
||||
t = par; // both done
|
||||
else if ((b & state & SUMMED) != 0) { // both summed
|
||||
int nextState; IntCumulateTask lt, rt;
|
||||
if ((lt = par.left) != null &&
|
||||
(rt = par.right) != null) {
|
||||
int lout = lt.out;
|
||||
par.out = (rt.hi == fnc ? lout :
|
||||
fn.applyAsInt(lout, rt.out));
|
||||
}
|
||||
int refork = (((b & CUMULATE) == 0 &&
|
||||
par.lo == org) ? CUMULATE : 0);
|
||||
if ((nextState = b|state|refork) == b ||
|
||||
par.compareAndSetPendingCount(b, nextState)) {
|
||||
state = SUMMED; // drop finished
|
||||
t = par;
|
||||
if (refork != 0)
|
||||
par.fork();
|
||||
}
|
||||
}
|
||||
else if (par.compareAndSetPendingCount(b, b|state))
|
||||
break outer; // sib not ready
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
5115
jdkSrc/jdk8/java/util/Arrays.java
Normal file
5115
jdkSrc/jdk8/java/util/Arrays.java
Normal file
File diff suppressed because it is too large
Load Diff
1010
jdkSrc/jdk8/java/util/ArraysParallelSortHelpers.java
Normal file
1010
jdkSrc/jdk8/java/util/ArraysParallelSortHelpers.java
Normal file
File diff suppressed because it is too large
Load Diff
998
jdkSrc/jdk8/java/util/Base64.java
Normal file
998
jdkSrc/jdk8/java/util/Base64.java
Normal file
@@ -0,0 +1,998 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
import java.io.FilterOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* This class consists exclusively of static methods for obtaining
|
||||
* encoders and decoders for the Base64 encoding scheme. The
|
||||
* implementation of this class supports the following types of Base64
|
||||
* as specified in
|
||||
* <a href="http://www.ietf.org/rfc/rfc4648.txt">RFC 4648</a> and
|
||||
* <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>.
|
||||
*
|
||||
* <ul>
|
||||
* <li><a name="basic"><b>Basic</b></a>
|
||||
* <p> Uses "The Base64 Alphabet" as specified in Table 1 of
|
||||
* RFC 4648 and RFC 2045 for encoding and decoding operation.
|
||||
* The encoder does not add any line feed (line separator)
|
||||
* character. The decoder rejects data that contains characters
|
||||
* outside the base64 alphabet.</p></li>
|
||||
*
|
||||
* <li><a name="url"><b>URL and Filename safe</b></a>
|
||||
* <p> Uses the "URL and Filename safe Base64 Alphabet" as specified
|
||||
* in Table 2 of RFC 4648 for encoding and decoding. The
|
||||
* encoder does not add any line feed (line separator) character.
|
||||
* The decoder rejects data that contains characters outside the
|
||||
* base64 alphabet.</p></li>
|
||||
*
|
||||
* <li><a name="mime"><b>MIME</b></a>
|
||||
* <p> Uses the "The Base64 Alphabet" as specified in Table 1 of
|
||||
* RFC 2045 for encoding and decoding operation. The encoded output
|
||||
* must be represented in lines of no more than 76 characters each
|
||||
* and uses a carriage return {@code '\r'} followed immediately by
|
||||
* a linefeed {@code '\n'} as the line separator. No line separator
|
||||
* is added to the end of the encoded output. All line separators
|
||||
* or other characters not found in the base64 alphabet table are
|
||||
* ignored in decoding operation.</p></li>
|
||||
* </ul>
|
||||
*
|
||||
* <p> Unless otherwise noted, passing a {@code null} argument to a
|
||||
* method of this class will cause a {@link java.lang.NullPointerException
|
||||
* NullPointerException} to be thrown.
|
||||
*
|
||||
* @author Xueming Shen
|
||||
* @since 1.8
|
||||
*/
|
||||
|
||||
public class Base64 {
|
||||
|
||||
private Base64() {}
|
||||
|
||||
/**
|
||||
* Returns a {@link Encoder} that encodes using the
|
||||
* <a href="#basic">Basic</a> type base64 encoding scheme.
|
||||
*
|
||||
* @return A Base64 encoder.
|
||||
*/
|
||||
public static Encoder getEncoder() {
|
||||
return Encoder.RFC4648;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Encoder} that encodes using the
|
||||
* <a href="#url">URL and Filename safe</a> type base64
|
||||
* encoding scheme.
|
||||
*
|
||||
* @return A Base64 encoder.
|
||||
*/
|
||||
public static Encoder getUrlEncoder() {
|
||||
return Encoder.RFC4648_URLSAFE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Encoder} that encodes using the
|
||||
* <a href="#mime">MIME</a> type base64 encoding scheme.
|
||||
*
|
||||
* @return A Base64 encoder.
|
||||
*/
|
||||
public static Encoder getMimeEncoder() {
|
||||
return Encoder.RFC2045;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Encoder} that encodes using the
|
||||
* <a href="#mime">MIME</a> type base64 encoding scheme
|
||||
* with specified line length and line separators.
|
||||
*
|
||||
* @param lineLength
|
||||
* the length of each output line (rounded down to nearest multiple
|
||||
* of 4). If {@code lineLength <= 0} the output will not be separated
|
||||
* in lines
|
||||
* @param lineSeparator
|
||||
* the line separator for each output line
|
||||
*
|
||||
* @return A Base64 encoder.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code lineSeparator} includes any
|
||||
* character of "The Base64 Alphabet" as specified in Table 1 of
|
||||
* RFC 2045.
|
||||
*/
|
||||
public static Encoder getMimeEncoder(int lineLength, byte[] lineSeparator) {
|
||||
Objects.requireNonNull(lineSeparator);
|
||||
int[] base64 = Decoder.fromBase64;
|
||||
for (byte b : lineSeparator) {
|
||||
if (base64[b & 0xff] != -1)
|
||||
throw new IllegalArgumentException(
|
||||
"Illegal base64 line separator character 0x" + Integer.toString(b, 16));
|
||||
}
|
||||
if (lineLength <= 0) {
|
||||
return Encoder.RFC4648;
|
||||
}
|
||||
return new Encoder(false, lineSeparator, lineLength >> 2 << 2, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Decoder} that decodes using the
|
||||
* <a href="#basic">Basic</a> type base64 encoding scheme.
|
||||
*
|
||||
* @return A Base64 decoder.
|
||||
*/
|
||||
public static Decoder getDecoder() {
|
||||
return Decoder.RFC4648;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Decoder} that decodes using the
|
||||
* <a href="#url">URL and Filename safe</a> type base64
|
||||
* encoding scheme.
|
||||
*
|
||||
* @return A Base64 decoder.
|
||||
*/
|
||||
public static Decoder getUrlDecoder() {
|
||||
return Decoder.RFC4648_URLSAFE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Decoder} that decodes using the
|
||||
* <a href="#mime">MIME</a> type base64 decoding scheme.
|
||||
*
|
||||
* @return A Base64 decoder.
|
||||
*/
|
||||
public static Decoder getMimeDecoder() {
|
||||
return Decoder.RFC2045;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements an encoder for encoding byte data using
|
||||
* the Base64 encoding scheme as specified in RFC 4648 and RFC 2045.
|
||||
*
|
||||
* <p> Instances of {@link Encoder} class are safe for use by
|
||||
* multiple concurrent threads.
|
||||
*
|
||||
* <p> Unless otherwise noted, passing a {@code null} argument to
|
||||
* a method of this class will cause a
|
||||
* {@link java.lang.NullPointerException NullPointerException} to
|
||||
* be thrown.
|
||||
*
|
||||
* @see Decoder
|
||||
* @since 1.8
|
||||
*/
|
||||
public static class Encoder {
|
||||
|
||||
private final byte[] newline;
|
||||
private final int linemax;
|
||||
private final boolean isURL;
|
||||
private final boolean doPadding;
|
||||
|
||||
private Encoder(boolean isURL, byte[] newline, int linemax, boolean doPadding) {
|
||||
this.isURL = isURL;
|
||||
this.newline = newline;
|
||||
this.linemax = linemax;
|
||||
this.doPadding = doPadding;
|
||||
}
|
||||
|
||||
/**
|
||||
* This array is a lookup table that translates 6-bit positive integer
|
||||
* index values into their "Base64 Alphabet" equivalents as specified
|
||||
* in "Table 1: The Base64 Alphabet" of RFC 2045 (and RFC 4648).
|
||||
*/
|
||||
private static final char[] toBase64 = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
||||
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
|
||||
};
|
||||
|
||||
/**
|
||||
* It's the lookup table for "URL and Filename safe Base64" as specified
|
||||
* in Table 2 of the RFC 4648, with the '+' and '/' changed to '-' and
|
||||
* '_'. This table is used when BASE64_URL is specified.
|
||||
*/
|
||||
private static final char[] toBase64URL = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
||||
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'
|
||||
};
|
||||
|
||||
private static final int MIMELINEMAX = 76;
|
||||
private static final byte[] CRLF = new byte[] {'\r', '\n'};
|
||||
|
||||
static final Encoder RFC4648 = new Encoder(false, null, -1, true);
|
||||
static final Encoder RFC4648_URLSAFE = new Encoder(true, null, -1, true);
|
||||
static final Encoder RFC2045 = new Encoder(false, CRLF, MIMELINEMAX, true);
|
||||
|
||||
private final int outLength(int srclen) {
|
||||
int len = 0;
|
||||
if (doPadding) {
|
||||
len = 4 * ((srclen + 2) / 3);
|
||||
} else {
|
||||
int n = srclen % 3;
|
||||
len = 4 * (srclen / 3) + (n == 0 ? 0 : n + 1);
|
||||
}
|
||||
if (linemax > 0) // line separators
|
||||
len += (len - 1) / linemax * newline.length;
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes all bytes from the specified byte array into a newly-allocated
|
||||
* byte array using the {@link Base64} encoding scheme. The returned byte
|
||||
* array is of the length of the resulting bytes.
|
||||
*
|
||||
* @param src
|
||||
* the byte array to encode
|
||||
* @return A newly-allocated byte array containing the resulting
|
||||
* encoded bytes.
|
||||
*/
|
||||
public byte[] encode(byte[] src) {
|
||||
int len = outLength(src.length); // dst array size
|
||||
byte[] dst = new byte[len];
|
||||
int ret = encode0(src, 0, src.length, dst);
|
||||
if (ret != dst.length)
|
||||
return Arrays.copyOf(dst, ret);
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes all bytes from the specified byte array using the
|
||||
* {@link Base64} encoding scheme, writing the resulting bytes to the
|
||||
* given output byte array, starting at offset 0.
|
||||
*
|
||||
* <p> It is the responsibility of the invoker of this method to make
|
||||
* sure the output byte array {@code dst} has enough space for encoding
|
||||
* all bytes from the input byte array. No bytes will be written to the
|
||||
* output byte array if the output byte array is not big enough.
|
||||
*
|
||||
* @param src
|
||||
* the byte array to encode
|
||||
* @param dst
|
||||
* the output byte array
|
||||
* @return The number of bytes written to the output byte array
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code dst} does not have enough
|
||||
* space for encoding all input bytes.
|
||||
*/
|
||||
public int encode(byte[] src, byte[] dst) {
|
||||
int len = outLength(src.length); // dst array size
|
||||
if (dst.length < len)
|
||||
throw new IllegalArgumentException(
|
||||
"Output byte array is too small for encoding all input bytes");
|
||||
return encode0(src, 0, src.length, dst);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the specified byte array into a String using the {@link Base64}
|
||||
* encoding scheme.
|
||||
*
|
||||
* <p> This method first encodes all input bytes into a base64 encoded
|
||||
* byte array and then constructs a new String by using the encoded byte
|
||||
* array and the {@link java.nio.charset.StandardCharsets#ISO_8859_1
|
||||
* ISO-8859-1} charset.
|
||||
*
|
||||
* <p> In other words, an invocation of this method has exactly the same
|
||||
* effect as invoking
|
||||
* {@code new String(encode(src), StandardCharsets.ISO_8859_1)}.
|
||||
*
|
||||
* @param src
|
||||
* the byte array to encode
|
||||
* @return A String containing the resulting Base64 encoded characters
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public String encodeToString(byte[] src) {
|
||||
byte[] encoded = encode(src);
|
||||
return new String(encoded, 0, 0, encoded.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes all remaining bytes from the specified byte buffer into
|
||||
* a newly-allocated ByteBuffer using the {@link Base64} encoding
|
||||
* scheme.
|
||||
*
|
||||
* Upon return, the source buffer's position will be updated to
|
||||
* its limit; its limit will not have been changed. The returned
|
||||
* output buffer's position will be zero and its limit will be the
|
||||
* number of resulting encoded bytes.
|
||||
*
|
||||
* @param buffer
|
||||
* the source ByteBuffer to encode
|
||||
* @return A newly-allocated byte buffer containing the encoded bytes.
|
||||
*/
|
||||
public ByteBuffer encode(ByteBuffer buffer) {
|
||||
int len = outLength(buffer.remaining());
|
||||
byte[] dst = new byte[len];
|
||||
int ret = 0;
|
||||
if (buffer.hasArray()) {
|
||||
ret = encode0(buffer.array(),
|
||||
buffer.arrayOffset() + buffer.position(),
|
||||
buffer.arrayOffset() + buffer.limit(),
|
||||
dst);
|
||||
buffer.position(buffer.limit());
|
||||
} else {
|
||||
byte[] src = new byte[buffer.remaining()];
|
||||
buffer.get(src);
|
||||
ret = encode0(src, 0, src.length, dst);
|
||||
}
|
||||
if (ret != dst.length)
|
||||
dst = Arrays.copyOf(dst, ret);
|
||||
return ByteBuffer.wrap(dst);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps an output stream for encoding byte data using the {@link Base64}
|
||||
* encoding scheme.
|
||||
*
|
||||
* <p> It is recommended to promptly close the returned output stream after
|
||||
* use, during which it will flush all possible leftover bytes to the underlying
|
||||
* output stream. Closing the returned output stream will close the underlying
|
||||
* output stream.
|
||||
*
|
||||
* @param os
|
||||
* the output stream.
|
||||
* @return the output stream for encoding the byte data into the
|
||||
* specified Base64 encoded format
|
||||
*/
|
||||
public OutputStream wrap(OutputStream os) {
|
||||
Objects.requireNonNull(os);
|
||||
return new EncOutputStream(os, isURL ? toBase64URL : toBase64,
|
||||
newline, linemax, doPadding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an encoder instance that encodes equivalently to this one,
|
||||
* but without adding any padding character at the end of the encoded
|
||||
* byte data.
|
||||
*
|
||||
* <p> The encoding scheme of this encoder instance is unaffected by
|
||||
* this invocation. The returned encoder instance should be used for
|
||||
* non-padding encoding operation.
|
||||
*
|
||||
* @return an equivalent encoder that encodes without adding any
|
||||
* padding character at the end
|
||||
*/
|
||||
public Encoder withoutPadding() {
|
||||
if (!doPadding)
|
||||
return this;
|
||||
return new Encoder(isURL, newline, linemax, false);
|
||||
}
|
||||
|
||||
private int encode0(byte[] src, int off, int end, byte[] dst) {
|
||||
char[] base64 = isURL ? toBase64URL : toBase64;
|
||||
int sp = off;
|
||||
int slen = (end - off) / 3 * 3;
|
||||
int sl = off + slen;
|
||||
if (linemax > 0 && slen > linemax / 4 * 3)
|
||||
slen = linemax / 4 * 3;
|
||||
int dp = 0;
|
||||
while (sp < sl) {
|
||||
int sl0 = Math.min(sp + slen, sl);
|
||||
for (int sp0 = sp, dp0 = dp ; sp0 < sl0; ) {
|
||||
int bits = (src[sp0++] & 0xff) << 16 |
|
||||
(src[sp0++] & 0xff) << 8 |
|
||||
(src[sp0++] & 0xff);
|
||||
dst[dp0++] = (byte)base64[(bits >>> 18) & 0x3f];
|
||||
dst[dp0++] = (byte)base64[(bits >>> 12) & 0x3f];
|
||||
dst[dp0++] = (byte)base64[(bits >>> 6) & 0x3f];
|
||||
dst[dp0++] = (byte)base64[bits & 0x3f];
|
||||
}
|
||||
int dlen = (sl0 - sp) / 3 * 4;
|
||||
dp += dlen;
|
||||
sp = sl0;
|
||||
if (dlen == linemax && sp < end) {
|
||||
for (byte b : newline){
|
||||
dst[dp++] = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sp < end) { // 1 or 2 leftover bytes
|
||||
int b0 = src[sp++] & 0xff;
|
||||
dst[dp++] = (byte)base64[b0 >> 2];
|
||||
if (sp == end) {
|
||||
dst[dp++] = (byte)base64[(b0 << 4) & 0x3f];
|
||||
if (doPadding) {
|
||||
dst[dp++] = '=';
|
||||
dst[dp++] = '=';
|
||||
}
|
||||
} else {
|
||||
int b1 = src[sp++] & 0xff;
|
||||
dst[dp++] = (byte)base64[(b0 << 4) & 0x3f | (b1 >> 4)];
|
||||
dst[dp++] = (byte)base64[(b1 << 2) & 0x3f];
|
||||
if (doPadding) {
|
||||
dst[dp++] = '=';
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements a decoder for decoding byte data using the
|
||||
* Base64 encoding scheme as specified in RFC 4648 and RFC 2045.
|
||||
*
|
||||
* <p> The Base64 padding character {@code '='} is accepted and
|
||||
* interpreted as the end of the encoded byte data, but is not
|
||||
* required. So if the final unit of the encoded byte data only has
|
||||
* two or three Base64 characters (without the corresponding padding
|
||||
* character(s) padded), they are decoded as if followed by padding
|
||||
* character(s). If there is a padding character present in the
|
||||
* final unit, the correct number of padding character(s) must be
|
||||
* present, otherwise {@code IllegalArgumentException} (
|
||||
* {@code IOException} when reading from a Base64 stream) is thrown
|
||||
* during decoding.
|
||||
*
|
||||
* <p> Instances of {@link Decoder} class are safe for use by
|
||||
* multiple concurrent threads.
|
||||
*
|
||||
* <p> Unless otherwise noted, passing a {@code null} argument to
|
||||
* a method of this class will cause a
|
||||
* {@link java.lang.NullPointerException NullPointerException} to
|
||||
* be thrown.
|
||||
*
|
||||
* @see Encoder
|
||||
* @since 1.8
|
||||
*/
|
||||
public static class Decoder {
|
||||
|
||||
private final boolean isURL;
|
||||
private final boolean isMIME;
|
||||
|
||||
private Decoder(boolean isURL, boolean isMIME) {
|
||||
this.isURL = isURL;
|
||||
this.isMIME = isMIME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup table for decoding unicode characters drawn from the
|
||||
* "Base64 Alphabet" (as specified in Table 1 of RFC 2045) into
|
||||
* their 6-bit positive integer equivalents. Characters that
|
||||
* are not in the Base64 alphabet but fall within the bounds of
|
||||
* the array are encoded to -1.
|
||||
*
|
||||
*/
|
||||
private static final int[] fromBase64 = new int[256];
|
||||
static {
|
||||
Arrays.fill(fromBase64, -1);
|
||||
for (int i = 0; i < Encoder.toBase64.length; i++)
|
||||
fromBase64[Encoder.toBase64[i]] = i;
|
||||
fromBase64['='] = -2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup table for decoding "URL and Filename safe Base64 Alphabet"
|
||||
* as specified in Table2 of the RFC 4648.
|
||||
*/
|
||||
private static final int[] fromBase64URL = new int[256];
|
||||
|
||||
static {
|
||||
Arrays.fill(fromBase64URL, -1);
|
||||
for (int i = 0; i < Encoder.toBase64URL.length; i++)
|
||||
fromBase64URL[Encoder.toBase64URL[i]] = i;
|
||||
fromBase64URL['='] = -2;
|
||||
}
|
||||
|
||||
static final Decoder RFC4648 = new Decoder(false, false);
|
||||
static final Decoder RFC4648_URLSAFE = new Decoder(true, false);
|
||||
static final Decoder RFC2045 = new Decoder(false, true);
|
||||
|
||||
/**
|
||||
* Decodes all bytes from the input byte array using the {@link Base64}
|
||||
* encoding scheme, writing the results into a newly-allocated output
|
||||
* byte array. The returned byte array is of the length of the resulting
|
||||
* bytes.
|
||||
*
|
||||
* @param src
|
||||
* the byte array to decode
|
||||
*
|
||||
* @return A newly-allocated byte array containing the decoded bytes.
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* if {@code src} is not in valid Base64 scheme
|
||||
*/
|
||||
public byte[] decode(byte[] src) {
|
||||
byte[] dst = new byte[outLength(src, 0, src.length)];
|
||||
int ret = decode0(src, 0, src.length, dst);
|
||||
if (ret != dst.length) {
|
||||
dst = Arrays.copyOf(dst, ret);
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes a Base64 encoded String into a newly-allocated byte array
|
||||
* using the {@link Base64} encoding scheme.
|
||||
*
|
||||
* <p> An invocation of this method has exactly the same effect as invoking
|
||||
* {@code decode(src.getBytes(StandardCharsets.ISO_8859_1))}
|
||||
*
|
||||
* @param src
|
||||
* the string to decode
|
||||
*
|
||||
* @return A newly-allocated byte array containing the decoded bytes.
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* if {@code src} is not in valid Base64 scheme
|
||||
*/
|
||||
public byte[] decode(String src) {
|
||||
return decode(src.getBytes(StandardCharsets.ISO_8859_1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes all bytes from the input byte array using the {@link Base64}
|
||||
* encoding scheme, writing the results into the given output byte array,
|
||||
* starting at offset 0.
|
||||
*
|
||||
* <p> It is the responsibility of the invoker of this method to make
|
||||
* sure the output byte array {@code dst} has enough space for decoding
|
||||
* all bytes from the input byte array. No bytes will be be written to
|
||||
* the output byte array if the output byte array is not big enough.
|
||||
*
|
||||
* <p> If the input byte array is not in valid Base64 encoding scheme
|
||||
* then some bytes may have been written to the output byte array before
|
||||
* IllegalargumentException is thrown.
|
||||
*
|
||||
* @param src
|
||||
* the byte array to decode
|
||||
* @param dst
|
||||
* the output byte array
|
||||
*
|
||||
* @return The number of bytes written to the output byte array
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* if {@code src} is not in valid Base64 scheme, or {@code dst}
|
||||
* does not have enough space for decoding all input bytes.
|
||||
*/
|
||||
public int decode(byte[] src, byte[] dst) {
|
||||
int len = outLength(src, 0, src.length);
|
||||
if (dst.length < len)
|
||||
throw new IllegalArgumentException(
|
||||
"Output byte array is too small for decoding all input bytes");
|
||||
return decode0(src, 0, src.length, dst);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes all bytes from the input byte buffer using the {@link Base64}
|
||||
* encoding scheme, writing the results into a newly-allocated ByteBuffer.
|
||||
*
|
||||
* <p> Upon return, the source buffer's position will be updated to
|
||||
* its limit; its limit will not have been changed. The returned
|
||||
* output buffer's position will be zero and its limit will be the
|
||||
* number of resulting decoded bytes
|
||||
*
|
||||
* <p> {@code IllegalArgumentException} is thrown if the input buffer
|
||||
* is not in valid Base64 encoding scheme. The position of the input
|
||||
* buffer will not be advanced in this case.
|
||||
*
|
||||
* @param buffer
|
||||
* the ByteBuffer to decode
|
||||
*
|
||||
* @return A newly-allocated byte buffer containing the decoded bytes
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* if {@code src} is not in valid Base64 scheme.
|
||||
*/
|
||||
public ByteBuffer decode(ByteBuffer buffer) {
|
||||
int pos0 = buffer.position();
|
||||
try {
|
||||
byte[] src;
|
||||
int sp, sl;
|
||||
if (buffer.hasArray()) {
|
||||
src = buffer.array();
|
||||
sp = buffer.arrayOffset() + buffer.position();
|
||||
sl = buffer.arrayOffset() + buffer.limit();
|
||||
buffer.position(buffer.limit());
|
||||
} else {
|
||||
src = new byte[buffer.remaining()];
|
||||
buffer.get(src);
|
||||
sp = 0;
|
||||
sl = src.length;
|
||||
}
|
||||
byte[] dst = new byte[outLength(src, sp, sl)];
|
||||
return ByteBuffer.wrap(dst, 0, decode0(src, sp, sl, dst));
|
||||
} catch (IllegalArgumentException iae) {
|
||||
buffer.position(pos0);
|
||||
throw iae;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an input stream for decoding {@link Base64} encoded byte stream.
|
||||
*
|
||||
* <p> The {@code read} methods of the returned {@code InputStream} will
|
||||
* throw {@code IOException} when reading bytes that cannot be decoded.
|
||||
*
|
||||
* <p> Closing the returned input stream will close the underlying
|
||||
* input stream.
|
||||
*
|
||||
* @param is
|
||||
* the input stream
|
||||
*
|
||||
* @return the input stream for decoding the specified Base64 encoded
|
||||
* byte stream
|
||||
*/
|
||||
public InputStream wrap(InputStream is) {
|
||||
Objects.requireNonNull(is);
|
||||
return new DecInputStream(is, isURL ? fromBase64URL : fromBase64, isMIME);
|
||||
}
|
||||
|
||||
private int outLength(byte[] src, int sp, int sl) {
|
||||
int[] base64 = isURL ? fromBase64URL : fromBase64;
|
||||
int paddings = 0;
|
||||
int len = sl - sp;
|
||||
if (len == 0)
|
||||
return 0;
|
||||
if (len < 2) {
|
||||
if (isMIME && base64[0] == -1)
|
||||
return 0;
|
||||
throw new IllegalArgumentException(
|
||||
"Input byte[] should at least have 2 bytes for base64 bytes");
|
||||
}
|
||||
if (isMIME) {
|
||||
// scan all bytes to fill out all non-alphabet. a performance
|
||||
// trade-off of pre-scan or Arrays.copyOf
|
||||
int n = 0;
|
||||
while (sp < sl) {
|
||||
int b = src[sp++] & 0xff;
|
||||
if (b == '=') {
|
||||
len -= (sl - sp + 1);
|
||||
break;
|
||||
}
|
||||
if ((b = base64[b]) == -1)
|
||||
n++;
|
||||
}
|
||||
len -= n;
|
||||
} else {
|
||||
if (src[sl - 1] == '=') {
|
||||
paddings++;
|
||||
if (src[sl - 2] == '=')
|
||||
paddings++;
|
||||
}
|
||||
}
|
||||
if (paddings == 0 && (len & 0x3) != 0)
|
||||
paddings = 4 - (len & 0x3);
|
||||
return 3 * ((len + 3) / 4) - paddings;
|
||||
}
|
||||
|
||||
private int decode0(byte[] src, int sp, int sl, byte[] dst) {
|
||||
int[] base64 = isURL ? fromBase64URL : fromBase64;
|
||||
int dp = 0;
|
||||
int bits = 0;
|
||||
int shiftto = 18; // pos of first byte of 4-byte atom
|
||||
while (sp < sl) {
|
||||
int b = src[sp++] & 0xff;
|
||||
if ((b = base64[b]) < 0) {
|
||||
if (b == -2) { // padding byte '='
|
||||
// = shiftto==18 unnecessary padding
|
||||
// x= shiftto==12 a dangling single x
|
||||
// x to be handled together with non-padding case
|
||||
// xx= shiftto==6&&sp==sl missing last =
|
||||
// xx=y shiftto==6 last is not =
|
||||
if (shiftto == 6 && (sp == sl || src[sp++] != '=') ||
|
||||
shiftto == 18) {
|
||||
throw new IllegalArgumentException(
|
||||
"Input byte array has wrong 4-byte ending unit");
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (isMIME) // skip if for rfc2045
|
||||
continue;
|
||||
else
|
||||
throw new IllegalArgumentException(
|
||||
"Illegal base64 character " +
|
||||
Integer.toString(src[sp - 1], 16));
|
||||
}
|
||||
bits |= (b << shiftto);
|
||||
shiftto -= 6;
|
||||
if (shiftto < 0) {
|
||||
dst[dp++] = (byte)(bits >> 16);
|
||||
dst[dp++] = (byte)(bits >> 8);
|
||||
dst[dp++] = (byte)(bits);
|
||||
shiftto = 18;
|
||||
bits = 0;
|
||||
}
|
||||
}
|
||||
// reached end of byte array or hit padding '=' characters.
|
||||
if (shiftto == 6) {
|
||||
dst[dp++] = (byte)(bits >> 16);
|
||||
} else if (shiftto == 0) {
|
||||
dst[dp++] = (byte)(bits >> 16);
|
||||
dst[dp++] = (byte)(bits >> 8);
|
||||
} else if (shiftto == 12) {
|
||||
// dangling single "x", incorrectly encoded.
|
||||
throw new IllegalArgumentException(
|
||||
"Last unit does not have enough valid bits");
|
||||
}
|
||||
// anything left is invalid, if is not MIME.
|
||||
// if MIME, ignore all non-base64 character
|
||||
while (sp < sl) {
|
||||
if (isMIME && base64[src[sp++]] < 0)
|
||||
continue;
|
||||
throw new IllegalArgumentException(
|
||||
"Input byte array has incorrect ending byte at " + sp);
|
||||
}
|
||||
return dp;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* An output stream for encoding bytes into the Base64.
|
||||
*/
|
||||
private static class EncOutputStream extends FilterOutputStream {
|
||||
|
||||
private int leftover = 0;
|
||||
private int b0, b1, b2;
|
||||
private boolean closed = false;
|
||||
|
||||
private final char[] base64; // byte->base64 mapping
|
||||
private final byte[] newline; // line separator, if needed
|
||||
private final int linemax;
|
||||
private final boolean doPadding;// whether or not to pad
|
||||
private int linepos = 0;
|
||||
|
||||
EncOutputStream(OutputStream os, char[] base64,
|
||||
byte[] newline, int linemax, boolean doPadding) {
|
||||
super(os);
|
||||
this.base64 = base64;
|
||||
this.newline = newline;
|
||||
this.linemax = linemax;
|
||||
this.doPadding = doPadding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
byte[] buf = new byte[1];
|
||||
buf[0] = (byte)(b & 0xff);
|
||||
write(buf, 0, 1);
|
||||
}
|
||||
|
||||
private void checkNewline() throws IOException {
|
||||
if (linepos == linemax) {
|
||||
out.write(newline);
|
||||
linepos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
if (closed)
|
||||
throw new IOException("Stream is closed");
|
||||
if (off < 0 || len < 0 || len > b.length - off)
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
if (len == 0)
|
||||
return;
|
||||
if (leftover != 0) {
|
||||
if (leftover == 1) {
|
||||
b1 = b[off++] & 0xff;
|
||||
len--;
|
||||
if (len == 0) {
|
||||
leftover++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
b2 = b[off++] & 0xff;
|
||||
len--;
|
||||
checkNewline();
|
||||
out.write(base64[b0 >> 2]);
|
||||
out.write(base64[(b0 << 4) & 0x3f | (b1 >> 4)]);
|
||||
out.write(base64[(b1 << 2) & 0x3f | (b2 >> 6)]);
|
||||
out.write(base64[b2 & 0x3f]);
|
||||
linepos += 4;
|
||||
}
|
||||
int nBits24 = len / 3;
|
||||
leftover = len - (nBits24 * 3);
|
||||
while (nBits24-- > 0) {
|
||||
checkNewline();
|
||||
int bits = (b[off++] & 0xff) << 16 |
|
||||
(b[off++] & 0xff) << 8 |
|
||||
(b[off++] & 0xff);
|
||||
out.write(base64[(bits >>> 18) & 0x3f]);
|
||||
out.write(base64[(bits >>> 12) & 0x3f]);
|
||||
out.write(base64[(bits >>> 6) & 0x3f]);
|
||||
out.write(base64[bits & 0x3f]);
|
||||
linepos += 4;
|
||||
}
|
||||
if (leftover == 1) {
|
||||
b0 = b[off++] & 0xff;
|
||||
} else if (leftover == 2) {
|
||||
b0 = b[off++] & 0xff;
|
||||
b1 = b[off++] & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (!closed) {
|
||||
closed = true;
|
||||
if (leftover == 1) {
|
||||
checkNewline();
|
||||
out.write(base64[b0 >> 2]);
|
||||
out.write(base64[(b0 << 4) & 0x3f]);
|
||||
if (doPadding) {
|
||||
out.write('=');
|
||||
out.write('=');
|
||||
}
|
||||
} else if (leftover == 2) {
|
||||
checkNewline();
|
||||
out.write(base64[b0 >> 2]);
|
||||
out.write(base64[(b0 << 4) & 0x3f | (b1 >> 4)]);
|
||||
out.write(base64[(b1 << 2) & 0x3f]);
|
||||
if (doPadding) {
|
||||
out.write('=');
|
||||
}
|
||||
}
|
||||
leftover = 0;
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* An input stream for decoding Base64 bytes
|
||||
*/
|
||||
private static class DecInputStream extends InputStream {
|
||||
|
||||
private final InputStream is;
|
||||
private final boolean isMIME;
|
||||
private final int[] base64; // base64 -> byte mapping
|
||||
private int bits = 0; // 24-bit buffer for decoding
|
||||
private int nextin = 18; // next available "off" in "bits" for input;
|
||||
// -> 18, 12, 6, 0
|
||||
private int nextout = -8; // next available "off" in "bits" for output;
|
||||
// -> 8, 0, -8 (no byte for output)
|
||||
private boolean eof = false;
|
||||
private boolean closed = false;
|
||||
|
||||
DecInputStream(InputStream is, int[] base64, boolean isMIME) {
|
||||
this.is = is;
|
||||
this.base64 = base64;
|
||||
this.isMIME = isMIME;
|
||||
}
|
||||
|
||||
private byte[] sbBuf = new byte[1];
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
return read(sbBuf, 0, 1) == -1 ? -1 : sbBuf[0] & 0xff;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
if (closed)
|
||||
throw new IOException("Stream is closed");
|
||||
if (eof && nextout < 0) // eof and no leftover
|
||||
return -1;
|
||||
if (off < 0 || len < 0 || len > b.length - off)
|
||||
throw new IndexOutOfBoundsException();
|
||||
int oldOff = off;
|
||||
if (nextout >= 0) { // leftover output byte(s) in bits buf
|
||||
do {
|
||||
if (len == 0)
|
||||
return off - oldOff;
|
||||
b[off++] = (byte)(bits >> nextout);
|
||||
len--;
|
||||
nextout -= 8;
|
||||
} while (nextout >= 0);
|
||||
bits = 0;
|
||||
}
|
||||
while (len > 0) {
|
||||
int v = is.read();
|
||||
if (v == -1) {
|
||||
eof = true;
|
||||
if (nextin != 18) {
|
||||
if (nextin == 12)
|
||||
throw new IOException("Base64 stream has one un-decoded dangling byte.");
|
||||
// treat ending xx/xxx without padding character legal.
|
||||
// same logic as v == '=' below
|
||||
b[off++] = (byte)(bits >> (16));
|
||||
len--;
|
||||
if (nextin == 0) { // only one padding byte
|
||||
if (len == 0) { // no enough output space
|
||||
bits >>= 8; // shift to lowest byte
|
||||
nextout = 0;
|
||||
} else {
|
||||
b[off++] = (byte) (bits >> 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (off == oldOff)
|
||||
return -1;
|
||||
else
|
||||
return off - oldOff;
|
||||
}
|
||||
if (v == '=') { // padding byte(s)
|
||||
// = shiftto==18 unnecessary padding
|
||||
// x= shiftto==12 dangling x, invalid unit
|
||||
// xx= shiftto==6 && missing last '='
|
||||
// xx=y or last is not '='
|
||||
if (nextin == 18 || nextin == 12 ||
|
||||
nextin == 6 && is.read() != '=') {
|
||||
throw new IOException("Illegal base64 ending sequence:" + nextin);
|
||||
}
|
||||
b[off++] = (byte)(bits >> (16));
|
||||
len--;
|
||||
if (nextin == 0) { // only one padding byte
|
||||
if (len == 0) { // no enough output space
|
||||
bits >>= 8; // shift to lowest byte
|
||||
nextout = 0;
|
||||
} else {
|
||||
b[off++] = (byte) (bits >> 8);
|
||||
}
|
||||
}
|
||||
eof = true;
|
||||
break;
|
||||
}
|
||||
if ((v = base64[v]) == -1) {
|
||||
if (isMIME) // skip if for rfc2045
|
||||
continue;
|
||||
else
|
||||
throw new IOException("Illegal base64 character " +
|
||||
Integer.toString(v, 16));
|
||||
}
|
||||
bits |= (v << nextin);
|
||||
if (nextin == 0) {
|
||||
nextin = 18; // clear for next
|
||||
nextout = 16;
|
||||
while (nextout >= 0) {
|
||||
b[off++] = (byte)(bits >> nextout);
|
||||
len--;
|
||||
nextout -= 8;
|
||||
if (len == 0 && nextout >= 0) { // don't clean "bits"
|
||||
return off - oldOff;
|
||||
}
|
||||
}
|
||||
bits = 0;
|
||||
} else {
|
||||
nextin -= 6;
|
||||
}
|
||||
}
|
||||
return off - oldOff;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
if (closed)
|
||||
throw new IOException("Stream is closed");
|
||||
return is.available(); // TBD:
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (!closed) {
|
||||
closed = true;
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1248
jdkSrc/jdk8/java/util/BitSet.java
Normal file
1248
jdkSrc/jdk8/java/util/BitSet.java
Normal file
File diff suppressed because it is too large
Load Diff
3634
jdkSrc/jdk8/java/util/Calendar.java
Normal file
3634
jdkSrc/jdk8/java/util/Calendar.java
Normal file
File diff suppressed because it is too large
Load Diff
604
jdkSrc/jdk8/java/util/Collection.java
Normal file
604
jdkSrc/jdk8/java/util/Collection.java
Normal file
@@ -0,0 +1,604 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
/**
|
||||
* The root interface in the <i>collection hierarchy</i>. A collection
|
||||
* represents a group of objects, known as its <i>elements</i>. Some
|
||||
* collections allow duplicate elements and others do not. Some are ordered
|
||||
* and others unordered. The JDK does not provide any <i>direct</i>
|
||||
* implementations of this interface: it provides implementations of more
|
||||
* specific subinterfaces like <tt>Set</tt> and <tt>List</tt>. This interface
|
||||
* is typically used to pass collections around and manipulate them where
|
||||
* maximum generality is desired.
|
||||
*
|
||||
* <p><i>Bags</i> or <i>multisets</i> (unordered collections that may contain
|
||||
* duplicate elements) should implement this interface directly.
|
||||
*
|
||||
* <p>All general-purpose <tt>Collection</tt> implementation classes (which
|
||||
* typically implement <tt>Collection</tt> indirectly through one of its
|
||||
* subinterfaces) should provide two "standard" constructors: a void (no
|
||||
* arguments) constructor, which creates an empty collection, and a
|
||||
* constructor with a single argument of type <tt>Collection</tt>, which
|
||||
* creates a new collection with the same elements as its argument. In
|
||||
* effect, the latter constructor allows the user to copy any collection,
|
||||
* producing an equivalent collection of the desired implementation type.
|
||||
* There is no way to enforce this convention (as interfaces cannot contain
|
||||
* constructors) but all of the general-purpose <tt>Collection</tt>
|
||||
* implementations in the Java platform libraries comply.
|
||||
*
|
||||
* <p>The "destructive" methods contained in this interface, that is, the
|
||||
* methods that modify the collection on which they operate, are specified to
|
||||
* throw <tt>UnsupportedOperationException</tt> if this collection does not
|
||||
* support the operation. If this is the case, these methods may, but are not
|
||||
* required to, throw an <tt>UnsupportedOperationException</tt> if the
|
||||
* invocation would have no effect on the collection. For example, invoking
|
||||
* the {@link #addAll(Collection)} method on an unmodifiable collection may,
|
||||
* but is not required to, throw the exception if the collection to be added
|
||||
* is empty.
|
||||
*
|
||||
* <p><a name="optional-restrictions">
|
||||
* Some collection implementations have restrictions on the elements that
|
||||
* they may contain.</a> For example, some implementations prohibit null elements,
|
||||
* and some have restrictions on the types of their elements. Attempting to
|
||||
* add an ineligible element throws an unchecked exception, typically
|
||||
* <tt>NullPointerException</tt> or <tt>ClassCastException</tt>. Attempting
|
||||
* to query the presence of an ineligible element may throw an exception,
|
||||
* or it may simply return false; some implementations will exhibit the former
|
||||
* behavior and some will exhibit the latter. More generally, attempting an
|
||||
* operation on an ineligible element whose completion would not result in
|
||||
* the insertion of an ineligible element into the collection may throw an
|
||||
* exception or it may succeed, at the option of the implementation.
|
||||
* Such exceptions are marked as "optional" in the specification for this
|
||||
* interface.
|
||||
*
|
||||
* <p>It is up to each collection to determine its own synchronization
|
||||
* policy. In the absence of a stronger guarantee by the
|
||||
* implementation, undefined behavior may result from the invocation
|
||||
* of any method on a collection that is being mutated by another
|
||||
* thread; this includes direct invocations, passing the collection to
|
||||
* a method that might perform invocations, and using an existing
|
||||
* iterator to examine the collection.
|
||||
*
|
||||
* <p>Many methods in Collections Framework interfaces are defined in
|
||||
* terms of the {@link Object#equals(Object) equals} method. For example,
|
||||
* the specification for the {@link #contains(Object) contains(Object o)}
|
||||
* method says: "returns <tt>true</tt> if and only if this collection
|
||||
* contains at least one element <tt>e</tt> such that
|
||||
* <tt>(o==null ? e==null : o.equals(e))</tt>." This specification should
|
||||
* <i>not</i> be construed to imply that invoking <tt>Collection.contains</tt>
|
||||
* with a non-null argument <tt>o</tt> will cause <tt>o.equals(e)</tt> to be
|
||||
* invoked for any element <tt>e</tt>. Implementations are free to implement
|
||||
* optimizations whereby the <tt>equals</tt> invocation is avoided, for
|
||||
* example, by first comparing the hash codes of the two elements. (The
|
||||
* {@link Object#hashCode()} specification guarantees that two objects with
|
||||
* unequal hash codes cannot be equal.) More generally, implementations of
|
||||
* the various Collections Framework interfaces are free to take advantage of
|
||||
* the specified behavior of underlying {@link Object} methods wherever the
|
||||
* implementor deems it appropriate.
|
||||
*
|
||||
* <p>Some collection operations which perform recursive traversal of the
|
||||
* collection may fail with an exception for self-referential instances where
|
||||
* the collection directly or indirectly contains itself. This includes the
|
||||
* {@code clone()}, {@code equals()}, {@code hashCode()} and {@code toString()}
|
||||
* methods. Implementations may optionally handle the self-referential scenario,
|
||||
* however most current implementations do not do so.
|
||||
*
|
||||
* <p>This interface is a member of the
|
||||
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
|
||||
* Java Collections Framework</a>.
|
||||
*
|
||||
* @implSpec
|
||||
* The default method implementations (inherited or otherwise) do not apply any
|
||||
* synchronization protocol. If a {@code Collection} implementation has a
|
||||
* specific synchronization protocol, then it must override default
|
||||
* implementations to apply that protocol.
|
||||
*
|
||||
* @param <E> the type of elements in this collection
|
||||
*
|
||||
* @author Josh Bloch
|
||||
* @author Neal Gafter
|
||||
* @see Set
|
||||
* @see List
|
||||
* @see Map
|
||||
* @see SortedSet
|
||||
* @see SortedMap
|
||||
* @see HashSet
|
||||
* @see TreeSet
|
||||
* @see ArrayList
|
||||
* @see LinkedList
|
||||
* @see Vector
|
||||
* @see Collections
|
||||
* @see Arrays
|
||||
* @see AbstractCollection
|
||||
* @since 1.2
|
||||
*/
|
||||
|
||||
public interface Collection<E> extends Iterable<E> {
|
||||
// Query Operations
|
||||
|
||||
/**
|
||||
* Returns the number of elements in this collection. If this collection
|
||||
* contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
|
||||
* <tt>Integer.MAX_VALUE</tt>.
|
||||
*
|
||||
* @return the number of elements in this collection
|
||||
*/
|
||||
int size();
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this collection contains no elements.
|
||||
*
|
||||
* @return <tt>true</tt> if this collection contains no elements
|
||||
*/
|
||||
boolean isEmpty();
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this collection contains the specified element.
|
||||
* More formally, returns <tt>true</tt> if and only if this collection
|
||||
* contains at least one element <tt>e</tt> such that
|
||||
* <tt>(o==null ? e==null : o.equals(e))</tt>.
|
||||
*
|
||||
* @param o element whose presence in this collection is to be tested
|
||||
* @return <tt>true</tt> if this collection contains the specified
|
||||
* element
|
||||
* @throws ClassCastException if the type of the specified element
|
||||
* is incompatible with this collection
|
||||
* (<a href="#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if the specified element is null and this
|
||||
* collection does not permit null elements
|
||||
* (<a href="#optional-restrictions">optional</a>)
|
||||
*/
|
||||
boolean contains(Object o);
|
||||
|
||||
/**
|
||||
* Returns an iterator over the elements in this collection. There are no
|
||||
* guarantees concerning the order in which the elements are returned
|
||||
* (unless this collection is an instance of some class that provides a
|
||||
* guarantee).
|
||||
*
|
||||
* @return an <tt>Iterator</tt> over the elements in this collection
|
||||
*/
|
||||
Iterator<E> iterator();
|
||||
|
||||
/**
|
||||
* Returns an array containing all of the elements in this collection.
|
||||
* If this collection makes any guarantees as to what order its elements
|
||||
* are returned by its iterator, this method must return the elements in
|
||||
* the same order.
|
||||
*
|
||||
* <p>The returned array will be "safe" in that no references to it are
|
||||
* maintained by this collection. (In other words, this method must
|
||||
* allocate a new array even if this collection is backed by an array).
|
||||
* The caller is thus free to modify the returned array.
|
||||
*
|
||||
* <p>This method acts as bridge between array-based and collection-based
|
||||
* APIs.
|
||||
*
|
||||
* @return an array containing all of the elements in this collection
|
||||
*/
|
||||
Object[] toArray();
|
||||
|
||||
/**
|
||||
* Returns an array containing all of the elements in this collection;
|
||||
* the runtime type of the returned array is that of the specified array.
|
||||
* If the collection fits in the specified array, it is returned therein.
|
||||
* Otherwise, a new array is allocated with the runtime type of the
|
||||
* specified array and the size of this collection.
|
||||
*
|
||||
* <p>If this collection fits in the specified array with room to spare
|
||||
* (i.e., the array has more elements than this collection), the element
|
||||
* in the array immediately following the end of the collection is set to
|
||||
* <tt>null</tt>. (This is useful in determining the length of this
|
||||
* collection <i>only</i> if the caller knows that this collection does
|
||||
* not contain any <tt>null</tt> elements.)
|
||||
*
|
||||
* <p>If this collection makes any guarantees as to what order its elements
|
||||
* are returned by its iterator, this method must return the elements in
|
||||
* the same order.
|
||||
*
|
||||
* <p>Like the {@link #toArray()} method, this method acts as bridge between
|
||||
* array-based and collection-based APIs. Further, this method allows
|
||||
* precise control over the runtime type of the output array, and may,
|
||||
* under certain circumstances, be used to save allocation costs.
|
||||
*
|
||||
* <p>Suppose <tt>x</tt> is a collection known to contain only strings.
|
||||
* The following code can be used to dump the collection into a newly
|
||||
* allocated array of <tt>String</tt>:
|
||||
*
|
||||
* <pre>
|
||||
* String[] y = x.toArray(new String[0]);</pre>
|
||||
*
|
||||
* Note that <tt>toArray(new Object[0])</tt> is identical in function to
|
||||
* <tt>toArray()</tt>.
|
||||
*
|
||||
* @param <T> the runtime type of the array to contain the collection
|
||||
* @param a the array into which the elements of this collection are to be
|
||||
* stored, if it is big enough; otherwise, a new array of the same
|
||||
* runtime type is allocated for this purpose.
|
||||
* @return an array containing all of the elements in this collection
|
||||
* @throws ArrayStoreException if the runtime type of the specified array
|
||||
* is not a supertype of the runtime type of every element in
|
||||
* this collection
|
||||
* @throws NullPointerException if the specified array is null
|
||||
*/
|
||||
<T> T[] toArray(T[] a);
|
||||
|
||||
// Modification Operations
|
||||
|
||||
/**
|
||||
* Ensures that this collection contains the specified element (optional
|
||||
* operation). Returns <tt>true</tt> if this collection changed as a
|
||||
* result of the call. (Returns <tt>false</tt> if this collection does
|
||||
* not permit duplicates and already contains the specified element.)<p>
|
||||
*
|
||||
* Collections that support this operation may place limitations on what
|
||||
* elements may be added to this collection. In particular, some
|
||||
* collections will refuse to add <tt>null</tt> elements, and others will
|
||||
* impose restrictions on the type of elements that may be added.
|
||||
* Collection classes should clearly specify in their documentation any
|
||||
* restrictions on what elements may be added.<p>
|
||||
*
|
||||
* If a collection refuses to add a particular element for any reason
|
||||
* other than that it already contains the element, it <i>must</i> throw
|
||||
* an exception (rather than returning <tt>false</tt>). This preserves
|
||||
* the invariant that a collection always contains the specified element
|
||||
* after this call returns.
|
||||
*
|
||||
* @param e element whose presence in this collection is to be ensured
|
||||
* @return <tt>true</tt> if this collection changed as a result of the
|
||||
* call
|
||||
* @throws UnsupportedOperationException if the <tt>add</tt> operation
|
||||
* is not supported by this collection
|
||||
* @throws ClassCastException if the class of the specified element
|
||||
* prevents it from being added to this collection
|
||||
* @throws NullPointerException if the specified element is null and this
|
||||
* collection does not permit null elements
|
||||
* @throws IllegalArgumentException if some property of the element
|
||||
* prevents it from being added to this collection
|
||||
* @throws IllegalStateException if the element cannot be added at this
|
||||
* time due to insertion restrictions
|
||||
*/
|
||||
boolean add(E e);
|
||||
|
||||
/**
|
||||
* Removes a single instance of the specified element from this
|
||||
* collection, if it is present (optional operation). More formally,
|
||||
* removes an element <tt>e</tt> such that
|
||||
* <tt>(o==null ? e==null : o.equals(e))</tt>, if
|
||||
* this collection contains one or more such elements. Returns
|
||||
* <tt>true</tt> if this collection contained the specified element (or
|
||||
* equivalently, if this collection changed as a result of the call).
|
||||
*
|
||||
* @param o element to be removed from this collection, if present
|
||||
* @return <tt>true</tt> if an element was removed as a result of this call
|
||||
* @throws ClassCastException if the type of the specified element
|
||||
* is incompatible with this collection
|
||||
* (<a href="#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if the specified element is null and this
|
||||
* collection does not permit null elements
|
||||
* (<a href="#optional-restrictions">optional</a>)
|
||||
* @throws UnsupportedOperationException if the <tt>remove</tt> operation
|
||||
* is not supported by this collection
|
||||
*/
|
||||
boolean remove(Object o);
|
||||
|
||||
|
||||
// Bulk Operations
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this collection contains all of the elements
|
||||
* in the specified collection.
|
||||
*
|
||||
* @param c collection to be checked for containment in this collection
|
||||
* @return <tt>true</tt> if this collection contains all of the elements
|
||||
* in the specified collection
|
||||
* @throws ClassCastException if the types of one or more elements
|
||||
* in the specified collection are incompatible with this
|
||||
* collection
|
||||
* (<a href="#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if the specified collection contains one
|
||||
* or more null elements and this collection does not permit null
|
||||
* elements
|
||||
* (<a href="#optional-restrictions">optional</a>),
|
||||
* or if the specified collection is null.
|
||||
* @see #contains(Object)
|
||||
*/
|
||||
boolean containsAll(Collection<?> c);
|
||||
|
||||
/**
|
||||
* Adds all of the elements in the specified collection to this collection
|
||||
* (optional operation). The behavior of this operation is undefined if
|
||||
* the specified collection is modified while the operation is in progress.
|
||||
* (This implies that the behavior of this call is undefined if the
|
||||
* specified collection is this collection, and this collection is
|
||||
* nonempty.)
|
||||
*
|
||||
* @param c collection containing elements to be added to this collection
|
||||
* @return <tt>true</tt> if this collection changed as a result of the call
|
||||
* @throws UnsupportedOperationException if the <tt>addAll</tt> operation
|
||||
* is not supported by this collection
|
||||
* @throws ClassCastException if the class of an element of the specified
|
||||
* collection prevents it from being added to this collection
|
||||
* @throws NullPointerException if the specified collection contains a
|
||||
* null element and this collection does not permit null elements,
|
||||
* or if the specified collection is null
|
||||
* @throws IllegalArgumentException if some property of an element of the
|
||||
* specified collection prevents it from being added to this
|
||||
* collection
|
||||
* @throws IllegalStateException if not all the elements can be added at
|
||||
* this time due to insertion restrictions
|
||||
* @see #add(Object)
|
||||
*/
|
||||
boolean addAll(Collection<? extends E> c);
|
||||
|
||||
/**
|
||||
* Removes all of this collection's elements that are also contained in the
|
||||
* specified collection (optional operation). After this call returns,
|
||||
* this collection will contain no elements in common with the specified
|
||||
* collection.
|
||||
*
|
||||
* @param c collection containing elements to be removed from this collection
|
||||
* @return <tt>true</tt> if this collection changed as a result of the
|
||||
* call
|
||||
* @throws UnsupportedOperationException if the <tt>removeAll</tt> method
|
||||
* is not supported by this collection
|
||||
* @throws ClassCastException if the types of one or more elements
|
||||
* in this collection are incompatible with the specified
|
||||
* collection
|
||||
* (<a href="#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if this collection contains one or more
|
||||
* null elements and the specified collection does not support
|
||||
* null elements
|
||||
* (<a href="#optional-restrictions">optional</a>),
|
||||
* or if the specified collection is null
|
||||
* @see #remove(Object)
|
||||
* @see #contains(Object)
|
||||
*/
|
||||
boolean removeAll(Collection<?> c);
|
||||
|
||||
/**
|
||||
* Removes all of the elements of this collection that satisfy the given
|
||||
* predicate. Errors or runtime exceptions thrown during iteration or by
|
||||
* the predicate are relayed to the caller.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation traverses all elements of the collection using
|
||||
* its {@link #iterator}. Each matching element is removed using
|
||||
* {@link Iterator#remove()}. If the collection's iterator does not
|
||||
* support removal then an {@code UnsupportedOperationException} will be
|
||||
* thrown on the first matching element.
|
||||
*
|
||||
* @param filter a predicate which returns {@code true} for elements to be
|
||||
* removed
|
||||
* @return {@code true} if any elements were removed
|
||||
* @throws NullPointerException if the specified filter is null
|
||||
* @throws UnsupportedOperationException if elements cannot be removed
|
||||
* from this collection. Implementations may throw this exception if a
|
||||
* matching element cannot be removed or if, in general, removal is not
|
||||
* supported.
|
||||
* @since 1.8
|
||||
*/
|
||||
default boolean removeIf(Predicate<? super E> filter) {
|
||||
Objects.requireNonNull(filter);
|
||||
boolean removed = false;
|
||||
final Iterator<E> each = iterator();
|
||||
while (each.hasNext()) {
|
||||
if (filter.test(each.next())) {
|
||||
each.remove();
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retains only the elements in this collection that are contained in the
|
||||
* specified collection (optional operation). In other words, removes from
|
||||
* this collection all of its elements that are not contained in the
|
||||
* specified collection.
|
||||
*
|
||||
* @param c collection containing elements to be retained in this collection
|
||||
* @return <tt>true</tt> if this collection changed as a result of the call
|
||||
* @throws UnsupportedOperationException if the <tt>retainAll</tt> operation
|
||||
* is not supported by this collection
|
||||
* @throws ClassCastException if the types of one or more elements
|
||||
* in this collection are incompatible with the specified
|
||||
* collection
|
||||
* (<a href="#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if this collection contains one or more
|
||||
* null elements and the specified collection does not permit null
|
||||
* elements
|
||||
* (<a href="#optional-restrictions">optional</a>),
|
||||
* or if the specified collection is null
|
||||
* @see #remove(Object)
|
||||
* @see #contains(Object)
|
||||
*/
|
||||
boolean retainAll(Collection<?> c);
|
||||
|
||||
/**
|
||||
* Removes all of the elements from this collection (optional operation).
|
||||
* The collection will be empty after this method returns.
|
||||
*
|
||||
* @throws UnsupportedOperationException if the <tt>clear</tt> operation
|
||||
* is not supported by this collection
|
||||
*/
|
||||
void clear();
|
||||
|
||||
|
||||
// Comparison and hashing
|
||||
|
||||
/**
|
||||
* Compares the specified object with this collection for equality. <p>
|
||||
*
|
||||
* While the <tt>Collection</tt> interface adds no stipulations to the
|
||||
* general contract for the <tt>Object.equals</tt>, programmers who
|
||||
* implement the <tt>Collection</tt> interface "directly" (in other words,
|
||||
* create a class that is a <tt>Collection</tt> but is not a <tt>Set</tt>
|
||||
* or a <tt>List</tt>) must exercise care if they choose to override the
|
||||
* <tt>Object.equals</tt>. It is not necessary to do so, and the simplest
|
||||
* course of action is to rely on <tt>Object</tt>'s implementation, but
|
||||
* the implementor may wish to implement a "value comparison" in place of
|
||||
* the default "reference comparison." (The <tt>List</tt> and
|
||||
* <tt>Set</tt> interfaces mandate such value comparisons.)<p>
|
||||
*
|
||||
* The general contract for the <tt>Object.equals</tt> method states that
|
||||
* equals must be symmetric (in other words, <tt>a.equals(b)</tt> if and
|
||||
* only if <tt>b.equals(a)</tt>). The contracts for <tt>List.equals</tt>
|
||||
* and <tt>Set.equals</tt> state that lists are only equal to other lists,
|
||||
* and sets to other sets. Thus, a custom <tt>equals</tt> method for a
|
||||
* collection class that implements neither the <tt>List</tt> nor
|
||||
* <tt>Set</tt> interface must return <tt>false</tt> when this collection
|
||||
* is compared to any list or set. (By the same logic, it is not possible
|
||||
* to write a class that correctly implements both the <tt>Set</tt> and
|
||||
* <tt>List</tt> interfaces.)
|
||||
*
|
||||
* @param o object to be compared for equality with this collection
|
||||
* @return <tt>true</tt> if the specified object is equal to this
|
||||
* collection
|
||||
*
|
||||
* @see Object#equals(Object)
|
||||
* @see Set#equals(Object)
|
||||
* @see List#equals(Object)
|
||||
*/
|
||||
boolean equals(Object o);
|
||||
|
||||
/**
|
||||
* Returns the hash code value for this collection. While the
|
||||
* <tt>Collection</tt> interface adds no stipulations to the general
|
||||
* contract for the <tt>Object.hashCode</tt> method, programmers should
|
||||
* take note that any class that overrides the <tt>Object.equals</tt>
|
||||
* method must also override the <tt>Object.hashCode</tt> method in order
|
||||
* to satisfy the general contract for the <tt>Object.hashCode</tt> method.
|
||||
* In particular, <tt>c1.equals(c2)</tt> implies that
|
||||
* <tt>c1.hashCode()==c2.hashCode()</tt>.
|
||||
*
|
||||
* @return the hash code value for this collection
|
||||
*
|
||||
* @see Object#hashCode()
|
||||
* @see Object#equals(Object)
|
||||
*/
|
||||
int hashCode();
|
||||
|
||||
/**
|
||||
* Creates a {@link Spliterator} over the elements in this collection.
|
||||
*
|
||||
* Implementations should document characteristic values reported by the
|
||||
* spliterator. Such characteristic values are not required to be reported
|
||||
* if the spliterator reports {@link Spliterator#SIZED} and this collection
|
||||
* contains no elements.
|
||||
*
|
||||
* <p>The default implementation should be overridden by subclasses that
|
||||
* can return a more efficient spliterator. In order to
|
||||
* preserve expected laziness behavior for the {@link #stream()} and
|
||||
* {@link #parallelStream()}} methods, spliterators should either have the
|
||||
* characteristic of {@code IMMUTABLE} or {@code CONCURRENT}, or be
|
||||
* <em><a href="Spliterator.html#binding">late-binding</a></em>.
|
||||
* If none of these is practical, the overriding class should describe the
|
||||
* spliterator's documented policy of binding and structural interference,
|
||||
* and should override the {@link #stream()} and {@link #parallelStream()}
|
||||
* methods to create streams using a {@code Supplier} of the spliterator,
|
||||
* as in:
|
||||
* <pre>{@code
|
||||
* Stream<E> s = StreamSupport.stream(() -> spliterator(), spliteratorCharacteristics)
|
||||
* }</pre>
|
||||
* <p>These requirements ensure that streams produced by the
|
||||
* {@link #stream()} and {@link #parallelStream()} methods will reflect the
|
||||
* contents of the collection as of initiation of the terminal stream
|
||||
* operation.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation creates a
|
||||
* <em><a href="Spliterator.html#binding">late-binding</a></em> spliterator
|
||||
* from the collections's {@code Iterator}. The spliterator inherits the
|
||||
* <em>fail-fast</em> properties of the collection's iterator.
|
||||
* <p>
|
||||
* The created {@code Spliterator} reports {@link Spliterator#SIZED}.
|
||||
*
|
||||
* @implNote
|
||||
* The created {@code Spliterator} additionally reports
|
||||
* {@link Spliterator#SUBSIZED}.
|
||||
*
|
||||
* <p>If a spliterator covers no elements then the reporting of additional
|
||||
* characteristic values, beyond that of {@code SIZED} and {@code SUBSIZED},
|
||||
* does not aid clients to control, specialize or simplify computation.
|
||||
* However, this does enable shared use of an immutable and empty
|
||||
* spliterator instance (see {@link Spliterators#emptySpliterator()}) for
|
||||
* empty collections, and enables clients to determine if such a spliterator
|
||||
* covers no elements.
|
||||
*
|
||||
* @return a {@code Spliterator} over the elements in this collection
|
||||
* @since 1.8
|
||||
*/
|
||||
@Override
|
||||
default Spliterator<E> spliterator() {
|
||||
return Spliterators.spliterator(this, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sequential {@code Stream} with this collection as its source.
|
||||
*
|
||||
* <p>This method should be overridden when the {@link #spliterator()}
|
||||
* method cannot return a spliterator that is {@code IMMUTABLE},
|
||||
* {@code CONCURRENT}, or <em>late-binding</em>. (See {@link #spliterator()}
|
||||
* for details.)
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation creates a sequential {@code Stream} from the
|
||||
* collection's {@code Spliterator}.
|
||||
*
|
||||
* @return a sequential {@code Stream} over the elements in this collection
|
||||
* @since 1.8
|
||||
*/
|
||||
default Stream<E> stream() {
|
||||
return StreamSupport.stream(spliterator(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a possibly parallel {@code Stream} with this collection as its
|
||||
* source. It is allowable for this method to return a sequential stream.
|
||||
*
|
||||
* <p>This method should be overridden when the {@link #spliterator()}
|
||||
* method cannot return a spliterator that is {@code IMMUTABLE},
|
||||
* {@code CONCURRENT}, or <em>late-binding</em>. (See {@link #spliterator()}
|
||||
* for details.)
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation creates a parallel {@code Stream} from the
|
||||
* collection's {@code Spliterator}.
|
||||
*
|
||||
* @return a possibly parallel {@code Stream} over the elements in this
|
||||
* collection
|
||||
* @since 1.8
|
||||
*/
|
||||
default Stream<E> parallelStream() {
|
||||
return StreamSupport.stream(spliterator(), true);
|
||||
}
|
||||
}
|
||||
5618
jdkSrc/jdk8/java/util/Collections.java
Normal file
5618
jdkSrc/jdk8/java/util/Collections.java
Normal file
File diff suppressed because it is too large
Load Diff
908
jdkSrc/jdk8/java/util/ComparableTimSort.java
Normal file
908
jdkSrc/jdk8/java/util/ComparableTimSort.java
Normal file
@@ -0,0 +1,908 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2009 Google Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* This is a near duplicate of {@link TimSort}, modified for use with
|
||||
* arrays of objects that implement {@link Comparable}, instead of using
|
||||
* explicit comparators.
|
||||
*
|
||||
* <p>If you are using an optimizing VM, you may find that ComparableTimSort
|
||||
* offers no performance benefit over TimSort in conjunction with a
|
||||
* comparator that simply returns {@code ((Comparable)first).compareTo(Second)}.
|
||||
* If this is the case, you are better off deleting ComparableTimSort to
|
||||
* eliminate the code duplication. (See Arrays.java for details.)
|
||||
*
|
||||
* @author Josh Bloch
|
||||
*/
|
||||
class ComparableTimSort {
|
||||
/**
|
||||
* This is the minimum sized sequence that will be merged. Shorter
|
||||
* sequences will be lengthened by calling binarySort. If the entire
|
||||
* array is less than this length, no merges will be performed.
|
||||
*
|
||||
* This constant should be a power of two. It was 64 in Tim Peter's C
|
||||
* implementation, but 32 was empirically determined to work better in
|
||||
* this implementation. In the unlikely event that you set this constant
|
||||
* to be a number that's not a power of two, you'll need to change the
|
||||
* {@link #minRunLength} computation.
|
||||
*
|
||||
* If you decrease this constant, you must change the stackLen
|
||||
* computation in the TimSort constructor, or you risk an
|
||||
* ArrayOutOfBounds exception. See listsort.txt for a discussion
|
||||
* of the minimum stack length required as a function of the length
|
||||
* of the array being sorted and the minimum merge sequence length.
|
||||
*/
|
||||
private static final int MIN_MERGE = 32;
|
||||
|
||||
/**
|
||||
* The array being sorted.
|
||||
*/
|
||||
private final Object[] a;
|
||||
|
||||
/**
|
||||
* When we get into galloping mode, we stay there until both runs win less
|
||||
* often than MIN_GALLOP consecutive times.
|
||||
*/
|
||||
private static final int MIN_GALLOP = 7;
|
||||
|
||||
/**
|
||||
* This controls when we get *into* galloping mode. It is initialized
|
||||
* to MIN_GALLOP. The mergeLo and mergeHi methods nudge it higher for
|
||||
* random data, and lower for highly structured data.
|
||||
*/
|
||||
private int minGallop = MIN_GALLOP;
|
||||
|
||||
/**
|
||||
* Maximum initial size of tmp array, which is used for merging. The array
|
||||
* can grow to accommodate demand.
|
||||
*
|
||||
* Unlike Tim's original C version, we do not allocate this much storage
|
||||
* when sorting smaller arrays. This change was required for performance.
|
||||
*/
|
||||
private static final int INITIAL_TMP_STORAGE_LENGTH = 256;
|
||||
|
||||
/**
|
||||
* Temp storage for merges. A workspace array may optionally be
|
||||
* provided in constructor, and if so will be used as long as it
|
||||
* is big enough.
|
||||
*/
|
||||
private Object[] tmp;
|
||||
private int tmpBase; // base of tmp array slice
|
||||
private int tmpLen; // length of tmp array slice
|
||||
|
||||
/**
|
||||
* A stack of pending runs yet to be merged. Run i starts at
|
||||
* address base[i] and extends for len[i] elements. It's always
|
||||
* true (so long as the indices are in bounds) that:
|
||||
*
|
||||
* runBase[i] + runLen[i] == runBase[i + 1]
|
||||
*
|
||||
* so we could cut the storage for this, but it's a minor amount,
|
||||
* and keeping all the info explicit simplifies the code.
|
||||
*/
|
||||
private int stackSize = 0; // Number of pending runs on stack
|
||||
private final int[] runBase;
|
||||
private final int[] runLen;
|
||||
|
||||
/**
|
||||
* Creates a TimSort instance to maintain the state of an ongoing sort.
|
||||
*
|
||||
* @param a the array to be sorted
|
||||
* @param work a workspace array (slice)
|
||||
* @param workBase origin of usable space in work array
|
||||
* @param workLen usable size of work array
|
||||
*/
|
||||
private ComparableTimSort(Object[] a, Object[] work, int workBase, int workLen) {
|
||||
this.a = a;
|
||||
|
||||
// Allocate temp storage (which may be increased later if necessary)
|
||||
int len = a.length;
|
||||
int tlen = (len < 2 * INITIAL_TMP_STORAGE_LENGTH) ?
|
||||
len >>> 1 : INITIAL_TMP_STORAGE_LENGTH;
|
||||
if (work == null || workLen < tlen || workBase + tlen > work.length) {
|
||||
tmp = new Object[tlen];
|
||||
tmpBase = 0;
|
||||
tmpLen = tlen;
|
||||
}
|
||||
else {
|
||||
tmp = work;
|
||||
tmpBase = workBase;
|
||||
tmpLen = workLen;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate runs-to-be-merged stack (which cannot be expanded). The
|
||||
* stack length requirements are described in listsort.txt. The C
|
||||
* version always uses the same stack length (85), but this was
|
||||
* measured to be too expensive when sorting "mid-sized" arrays (e.g.,
|
||||
* 100 elements) in Java. Therefore, we use smaller (but sufficiently
|
||||
* large) stack lengths for smaller arrays. The "magic numbers" in the
|
||||
* computation below must be changed if MIN_MERGE is decreased. See
|
||||
* the MIN_MERGE declaration above for more information.
|
||||
* The maximum value of 49 allows for an array up to length
|
||||
* Integer.MAX_VALUE-4, if array is filled by the worst case stack size
|
||||
* increasing scenario. More explanations are given in section 4 of:
|
||||
* http://envisage-project.eu/wp-content/uploads/2015/02/sorting.pdf
|
||||
*/
|
||||
int stackLen = (len < 120 ? 5 :
|
||||
len < 1542 ? 10 :
|
||||
len < 119151 ? 24 : 49);
|
||||
runBase = new int[stackLen];
|
||||
runLen = new int[stackLen];
|
||||
}
|
||||
|
||||
/*
|
||||
* The next method (package private and static) constitutes the
|
||||
* entire API of this class.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sorts the given range, using the given workspace array slice
|
||||
* for temp storage when possible. This method is designed to be
|
||||
* invoked from public methods (in class Arrays) after performing
|
||||
* any necessary array bounds checks and expanding parameters into
|
||||
* the required forms.
|
||||
*
|
||||
* @param a the array to be sorted
|
||||
* @param lo the index of the first element, inclusive, to be sorted
|
||||
* @param hi the index of the last element, exclusive, to be sorted
|
||||
* @param work a workspace array (slice)
|
||||
* @param workBase origin of usable space in work array
|
||||
* @param workLen usable size of work array
|
||||
* @since 1.8
|
||||
*/
|
||||
static void sort(Object[] a, int lo, int hi, Object[] work, int workBase, int workLen) {
|
||||
assert a != null && lo >= 0 && lo <= hi && hi <= a.length;
|
||||
|
||||
int nRemaining = hi - lo;
|
||||
if (nRemaining < 2)
|
||||
return; // Arrays of size 0 and 1 are always sorted
|
||||
|
||||
// If array is small, do a "mini-TimSort" with no merges
|
||||
if (nRemaining < MIN_MERGE) {
|
||||
int initRunLen = countRunAndMakeAscending(a, lo, hi);
|
||||
binarySort(a, lo, hi, lo + initRunLen);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* March over the array once, left to right, finding natural runs,
|
||||
* extending short natural runs to minRun elements, and merging runs
|
||||
* to maintain stack invariant.
|
||||
*/
|
||||
ComparableTimSort ts = new ComparableTimSort(a, work, workBase, workLen);
|
||||
int minRun = minRunLength(nRemaining);
|
||||
do {
|
||||
// Identify next run
|
||||
int runLen = countRunAndMakeAscending(a, lo, hi);
|
||||
|
||||
// If run is short, extend to min(minRun, nRemaining)
|
||||
if (runLen < minRun) {
|
||||
int force = nRemaining <= minRun ? nRemaining : minRun;
|
||||
binarySort(a, lo, lo + force, lo + runLen);
|
||||
runLen = force;
|
||||
}
|
||||
|
||||
// Push run onto pending-run stack, and maybe merge
|
||||
ts.pushRun(lo, runLen);
|
||||
ts.mergeCollapse();
|
||||
|
||||
// Advance to find next run
|
||||
lo += runLen;
|
||||
nRemaining -= runLen;
|
||||
} while (nRemaining != 0);
|
||||
|
||||
// Merge all remaining runs to complete sort
|
||||
assert lo == hi;
|
||||
ts.mergeForceCollapse();
|
||||
assert ts.stackSize == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified portion of the specified array using a binary
|
||||
* insertion sort. This is the best method for sorting small numbers
|
||||
* of elements. It requires O(n log n) compares, but O(n^2) data
|
||||
* movement (worst case).
|
||||
*
|
||||
* If the initial part of the specified range is already sorted,
|
||||
* this method can take advantage of it: the method assumes that the
|
||||
* elements from index {@code lo}, inclusive, to {@code start},
|
||||
* exclusive are already sorted.
|
||||
*
|
||||
* @param a the array in which a range is to be sorted
|
||||
* @param lo the index of the first element in the range to be sorted
|
||||
* @param hi the index after the last element in the range to be sorted
|
||||
* @param start the index of the first element in the range that is
|
||||
* not already known to be sorted ({@code lo <= start <= hi})
|
||||
*/
|
||||
@SuppressWarnings({"fallthrough", "rawtypes", "unchecked"})
|
||||
private static void binarySort(Object[] a, int lo, int hi, int start) {
|
||||
assert lo <= start && start <= hi;
|
||||
if (start == lo)
|
||||
start++;
|
||||
for ( ; start < hi; start++) {
|
||||
Comparable pivot = (Comparable) a[start];
|
||||
|
||||
// Set left (and right) to the index where a[start] (pivot) belongs
|
||||
int left = lo;
|
||||
int right = start;
|
||||
assert left <= right;
|
||||
/*
|
||||
* Invariants:
|
||||
* pivot >= all in [lo, left).
|
||||
* pivot < all in [right, start).
|
||||
*/
|
||||
while (left < right) {
|
||||
int mid = (left + right) >>> 1;
|
||||
if (pivot.compareTo(a[mid]) < 0)
|
||||
right = mid;
|
||||
else
|
||||
left = mid + 1;
|
||||
}
|
||||
assert left == right;
|
||||
|
||||
/*
|
||||
* The invariants still hold: pivot >= all in [lo, left) and
|
||||
* pivot < all in [left, start), so pivot belongs at left. Note
|
||||
* that if there are elements equal to pivot, left points to the
|
||||
* first slot after them -- that's why this sort is stable.
|
||||
* Slide elements over to make room for pivot.
|
||||
*/
|
||||
int n = start - left; // The number of elements to move
|
||||
// Switch is just an optimization for arraycopy in default case
|
||||
switch (n) {
|
||||
case 2: a[left + 2] = a[left + 1];
|
||||
case 1: a[left + 1] = a[left];
|
||||
break;
|
||||
default: System.arraycopy(a, left, a, left + 1, n);
|
||||
}
|
||||
a[left] = pivot;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the run beginning at the specified position in
|
||||
* the specified array and reverses the run if it is descending (ensuring
|
||||
* that the run will always be ascending when the method returns).
|
||||
*
|
||||
* A run is the longest ascending sequence with:
|
||||
*
|
||||
* a[lo] <= a[lo + 1] <= a[lo + 2] <= ...
|
||||
*
|
||||
* or the longest descending sequence with:
|
||||
*
|
||||
* a[lo] > a[lo + 1] > a[lo + 2] > ...
|
||||
*
|
||||
* For its intended use in a stable mergesort, the strictness of the
|
||||
* definition of "descending" is needed so that the call can safely
|
||||
* reverse a descending sequence without violating stability.
|
||||
*
|
||||
* @param a the array in which a run is to be counted and possibly reversed
|
||||
* @param lo index of the first element in the run
|
||||
* @param hi index after the last element that may be contained in the run.
|
||||
It is required that {@code lo < hi}.
|
||||
* @return the length of the run beginning at the specified position in
|
||||
* the specified array
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
private static int countRunAndMakeAscending(Object[] a, int lo, int hi) {
|
||||
assert lo < hi;
|
||||
int runHi = lo + 1;
|
||||
if (runHi == hi)
|
||||
return 1;
|
||||
|
||||
// Find end of run, and reverse range if descending
|
||||
if (((Comparable) a[runHi++]).compareTo(a[lo]) < 0) { // Descending
|
||||
while (runHi < hi && ((Comparable) a[runHi]).compareTo(a[runHi - 1]) < 0)
|
||||
runHi++;
|
||||
reverseRange(a, lo, runHi);
|
||||
} else { // Ascending
|
||||
while (runHi < hi && ((Comparable) a[runHi]).compareTo(a[runHi - 1]) >= 0)
|
||||
runHi++;
|
||||
}
|
||||
|
||||
return runHi - lo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the specified range of the specified array.
|
||||
*
|
||||
* @param a the array in which a range is to be reversed
|
||||
* @param lo the index of the first element in the range to be reversed
|
||||
* @param hi the index after the last element in the range to be reversed
|
||||
*/
|
||||
private static void reverseRange(Object[] a, int lo, int hi) {
|
||||
hi--;
|
||||
while (lo < hi) {
|
||||
Object t = a[lo];
|
||||
a[lo++] = a[hi];
|
||||
a[hi--] = t;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum acceptable run length for an array of the specified
|
||||
* length. Natural runs shorter than this will be extended with
|
||||
* {@link #binarySort}.
|
||||
*
|
||||
* Roughly speaking, the computation is:
|
||||
*
|
||||
* If n < MIN_MERGE, return n (it's too small to bother with fancy stuff).
|
||||
* Else if n is an exact power of 2, return MIN_MERGE/2.
|
||||
* Else return an int k, MIN_MERGE/2 <= k <= MIN_MERGE, such that n/k
|
||||
* is close to, but strictly less than, an exact power of 2.
|
||||
*
|
||||
* For the rationale, see listsort.txt.
|
||||
*
|
||||
* @param n the length of the array to be sorted
|
||||
* @return the length of the minimum run to be merged
|
||||
*/
|
||||
private static int minRunLength(int n) {
|
||||
assert n >= 0;
|
||||
int r = 0; // Becomes 1 if any 1 bits are shifted off
|
||||
while (n >= MIN_MERGE) {
|
||||
r |= (n & 1);
|
||||
n >>= 1;
|
||||
}
|
||||
return n + r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes the specified run onto the pending-run stack.
|
||||
*
|
||||
* @param runBase index of the first element in the run
|
||||
* @param runLen the number of elements in the run
|
||||
*/
|
||||
private void pushRun(int runBase, int runLen) {
|
||||
this.runBase[stackSize] = runBase;
|
||||
this.runLen[stackSize] = runLen;
|
||||
stackSize++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Examines the stack of runs waiting to be merged and merges adjacent runs
|
||||
* until the stack invariants are reestablished:
|
||||
*
|
||||
* 1. runLen[i - 3] > runLen[i - 2] + runLen[i - 1]
|
||||
* 2. runLen[i - 2] > runLen[i - 1]
|
||||
*
|
||||
* This method is called each time a new run is pushed onto the stack,
|
||||
* so the invariants are guaranteed to hold for i < stackSize upon
|
||||
* entry to the method.
|
||||
*/
|
||||
private void mergeCollapse() {
|
||||
while (stackSize > 1) {
|
||||
int n = stackSize - 2;
|
||||
if (n > 0 && runLen[n-1] <= runLen[n] + runLen[n+1]) {
|
||||
if (runLen[n - 1] < runLen[n + 1])
|
||||
n--;
|
||||
mergeAt(n);
|
||||
} else if (runLen[n] <= runLen[n + 1]) {
|
||||
mergeAt(n);
|
||||
} else {
|
||||
break; // Invariant is established
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges all runs on the stack until only one remains. This method is
|
||||
* called once, to complete the sort.
|
||||
*/
|
||||
private void mergeForceCollapse() {
|
||||
while (stackSize > 1) {
|
||||
int n = stackSize - 2;
|
||||
if (n > 0 && runLen[n - 1] < runLen[n + 1])
|
||||
n--;
|
||||
mergeAt(n);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges the two runs at stack indices i and i+1. Run i must be
|
||||
* the penultimate or antepenultimate run on the stack. In other words,
|
||||
* i must be equal to stackSize-2 or stackSize-3.
|
||||
*
|
||||
* @param i stack index of the first of the two runs to merge
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private void mergeAt(int i) {
|
||||
assert stackSize >= 2;
|
||||
assert i >= 0;
|
||||
assert i == stackSize - 2 || i == stackSize - 3;
|
||||
|
||||
int base1 = runBase[i];
|
||||
int len1 = runLen[i];
|
||||
int base2 = runBase[i + 1];
|
||||
int len2 = runLen[i + 1];
|
||||
assert len1 > 0 && len2 > 0;
|
||||
assert base1 + len1 == base2;
|
||||
|
||||
/*
|
||||
* Record the length of the combined runs; if i is the 3rd-last
|
||||
* run now, also slide over the last run (which isn't involved
|
||||
* in this merge). The current run (i+1) goes away in any case.
|
||||
*/
|
||||
runLen[i] = len1 + len2;
|
||||
if (i == stackSize - 3) {
|
||||
runBase[i + 1] = runBase[i + 2];
|
||||
runLen[i + 1] = runLen[i + 2];
|
||||
}
|
||||
stackSize--;
|
||||
|
||||
/*
|
||||
* Find where the first element of run2 goes in run1. Prior elements
|
||||
* in run1 can be ignored (because they're already in place).
|
||||
*/
|
||||
int k = gallopRight((Comparable<Object>) a[base2], a, base1, len1, 0);
|
||||
assert k >= 0;
|
||||
base1 += k;
|
||||
len1 -= k;
|
||||
if (len1 == 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Find where the last element of run1 goes in run2. Subsequent elements
|
||||
* in run2 can be ignored (because they're already in place).
|
||||
*/
|
||||
len2 = gallopLeft((Comparable<Object>) a[base1 + len1 - 1], a,
|
||||
base2, len2, len2 - 1);
|
||||
assert len2 >= 0;
|
||||
if (len2 == 0)
|
||||
return;
|
||||
|
||||
// Merge remaining runs, using tmp array with min(len1, len2) elements
|
||||
if (len1 <= len2)
|
||||
mergeLo(base1, len1, base2, len2);
|
||||
else
|
||||
mergeHi(base1, len1, base2, len2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Locates the position at which to insert the specified key into the
|
||||
* specified sorted range; if the range contains an element equal to key,
|
||||
* returns the index of the leftmost equal element.
|
||||
*
|
||||
* @param key the key whose insertion point to search for
|
||||
* @param a the array in which to search
|
||||
* @param base the index of the first element in the range
|
||||
* @param len the length of the range; must be > 0
|
||||
* @param hint the index at which to begin the search, 0 <= hint < n.
|
||||
* The closer hint is to the result, the faster this method will run.
|
||||
* @return the int k, 0 <= k <= n such that a[b + k - 1] < key <= a[b + k],
|
||||
* pretending that a[b - 1] is minus infinity and a[b + n] is infinity.
|
||||
* In other words, key belongs at index b + k; or in other words,
|
||||
* the first k elements of a should precede key, and the last n - k
|
||||
* should follow it.
|
||||
*/
|
||||
private static int gallopLeft(Comparable<Object> key, Object[] a,
|
||||
int base, int len, int hint) {
|
||||
assert len > 0 && hint >= 0 && hint < len;
|
||||
|
||||
int lastOfs = 0;
|
||||
int ofs = 1;
|
||||
if (key.compareTo(a[base + hint]) > 0) {
|
||||
// Gallop right until a[base+hint+lastOfs] < key <= a[base+hint+ofs]
|
||||
int maxOfs = len - hint;
|
||||
while (ofs < maxOfs && key.compareTo(a[base + hint + ofs]) > 0) {
|
||||
lastOfs = ofs;
|
||||
ofs = (ofs << 1) + 1;
|
||||
if (ofs <= 0) // int overflow
|
||||
ofs = maxOfs;
|
||||
}
|
||||
if (ofs > maxOfs)
|
||||
ofs = maxOfs;
|
||||
|
||||
// Make offsets relative to base
|
||||
lastOfs += hint;
|
||||
ofs += hint;
|
||||
} else { // key <= a[base + hint]
|
||||
// Gallop left until a[base+hint-ofs] < key <= a[base+hint-lastOfs]
|
||||
final int maxOfs = hint + 1;
|
||||
while (ofs < maxOfs && key.compareTo(a[base + hint - ofs]) <= 0) {
|
||||
lastOfs = ofs;
|
||||
ofs = (ofs << 1) + 1;
|
||||
if (ofs <= 0) // int overflow
|
||||
ofs = maxOfs;
|
||||
}
|
||||
if (ofs > maxOfs)
|
||||
ofs = maxOfs;
|
||||
|
||||
// Make offsets relative to base
|
||||
int tmp = lastOfs;
|
||||
lastOfs = hint - ofs;
|
||||
ofs = hint - tmp;
|
||||
}
|
||||
assert -1 <= lastOfs && lastOfs < ofs && ofs <= len;
|
||||
|
||||
/*
|
||||
* Now a[base+lastOfs] < key <= a[base+ofs], so key belongs somewhere
|
||||
* to the right of lastOfs but no farther right than ofs. Do a binary
|
||||
* search, with invariant a[base + lastOfs - 1] < key <= a[base + ofs].
|
||||
*/
|
||||
lastOfs++;
|
||||
while (lastOfs < ofs) {
|
||||
int m = lastOfs + ((ofs - lastOfs) >>> 1);
|
||||
|
||||
if (key.compareTo(a[base + m]) > 0)
|
||||
lastOfs = m + 1; // a[base + m] < key
|
||||
else
|
||||
ofs = m; // key <= a[base + m]
|
||||
}
|
||||
assert lastOfs == ofs; // so a[base + ofs - 1] < key <= a[base + ofs]
|
||||
return ofs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like gallopLeft, except that if the range contains an element equal to
|
||||
* key, gallopRight returns the index after the rightmost equal element.
|
||||
*
|
||||
* @param key the key whose insertion point to search for
|
||||
* @param a the array in which to search
|
||||
* @param base the index of the first element in the range
|
||||
* @param len the length of the range; must be > 0
|
||||
* @param hint the index at which to begin the search, 0 <= hint < n.
|
||||
* The closer hint is to the result, the faster this method will run.
|
||||
* @return the int k, 0 <= k <= n such that a[b + k - 1] <= key < a[b + k]
|
||||
*/
|
||||
private static int gallopRight(Comparable<Object> key, Object[] a,
|
||||
int base, int len, int hint) {
|
||||
assert len > 0 && hint >= 0 && hint < len;
|
||||
|
||||
int ofs = 1;
|
||||
int lastOfs = 0;
|
||||
if (key.compareTo(a[base + hint]) < 0) {
|
||||
// Gallop left until a[b+hint - ofs] <= key < a[b+hint - lastOfs]
|
||||
int maxOfs = hint + 1;
|
||||
while (ofs < maxOfs && key.compareTo(a[base + hint - ofs]) < 0) {
|
||||
lastOfs = ofs;
|
||||
ofs = (ofs << 1) + 1;
|
||||
if (ofs <= 0) // int overflow
|
||||
ofs = maxOfs;
|
||||
}
|
||||
if (ofs > maxOfs)
|
||||
ofs = maxOfs;
|
||||
|
||||
// Make offsets relative to b
|
||||
int tmp = lastOfs;
|
||||
lastOfs = hint - ofs;
|
||||
ofs = hint - tmp;
|
||||
} else { // a[b + hint] <= key
|
||||
// Gallop right until a[b+hint + lastOfs] <= key < a[b+hint + ofs]
|
||||
int maxOfs = len - hint;
|
||||
while (ofs < maxOfs && key.compareTo(a[base + hint + ofs]) >= 0) {
|
||||
lastOfs = ofs;
|
||||
ofs = (ofs << 1) + 1;
|
||||
if (ofs <= 0) // int overflow
|
||||
ofs = maxOfs;
|
||||
}
|
||||
if (ofs > maxOfs)
|
||||
ofs = maxOfs;
|
||||
|
||||
// Make offsets relative to b
|
||||
lastOfs += hint;
|
||||
ofs += hint;
|
||||
}
|
||||
assert -1 <= lastOfs && lastOfs < ofs && ofs <= len;
|
||||
|
||||
/*
|
||||
* Now a[b + lastOfs] <= key < a[b + ofs], so key belongs somewhere to
|
||||
* the right of lastOfs but no farther right than ofs. Do a binary
|
||||
* search, with invariant a[b + lastOfs - 1] <= key < a[b + ofs].
|
||||
*/
|
||||
lastOfs++;
|
||||
while (lastOfs < ofs) {
|
||||
int m = lastOfs + ((ofs - lastOfs) >>> 1);
|
||||
|
||||
if (key.compareTo(a[base + m]) < 0)
|
||||
ofs = m; // key < a[b + m]
|
||||
else
|
||||
lastOfs = m + 1; // a[b + m] <= key
|
||||
}
|
||||
assert lastOfs == ofs; // so a[b + ofs - 1] <= key < a[b + ofs]
|
||||
return ofs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges two adjacent runs in place, in a stable fashion. The first
|
||||
* element of the first run must be greater than the first element of the
|
||||
* second run (a[base1] > a[base2]), and the last element of the first run
|
||||
* (a[base1 + len1-1]) must be greater than all elements of the second run.
|
||||
*
|
||||
* For performance, this method should be called only when len1 <= len2;
|
||||
* its twin, mergeHi should be called if len1 >= len2. (Either method
|
||||
* may be called if len1 == len2.)
|
||||
*
|
||||
* @param base1 index of first element in first run to be merged
|
||||
* @param len1 length of first run to be merged (must be > 0)
|
||||
* @param base2 index of first element in second run to be merged
|
||||
* (must be aBase + aLen)
|
||||
* @param len2 length of second run to be merged (must be > 0)
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
private void mergeLo(int base1, int len1, int base2, int len2) {
|
||||
assert len1 > 0 && len2 > 0 && base1 + len1 == base2;
|
||||
|
||||
// Copy first run into temp array
|
||||
Object[] a = this.a; // For performance
|
||||
Object[] tmp = ensureCapacity(len1);
|
||||
|
||||
int cursor1 = tmpBase; // Indexes into tmp array
|
||||
int cursor2 = base2; // Indexes int a
|
||||
int dest = base1; // Indexes int a
|
||||
System.arraycopy(a, base1, tmp, cursor1, len1);
|
||||
|
||||
// Move first element of second run and deal with degenerate cases
|
||||
a[dest++] = a[cursor2++];
|
||||
if (--len2 == 0) {
|
||||
System.arraycopy(tmp, cursor1, a, dest, len1);
|
||||
return;
|
||||
}
|
||||
if (len1 == 1) {
|
||||
System.arraycopy(a, cursor2, a, dest, len2);
|
||||
a[dest + len2] = tmp[cursor1]; // Last elt of run 1 to end of merge
|
||||
return;
|
||||
}
|
||||
|
||||
int minGallop = this.minGallop; // Use local variable for performance
|
||||
outer:
|
||||
while (true) {
|
||||
int count1 = 0; // Number of times in a row that first run won
|
||||
int count2 = 0; // Number of times in a row that second run won
|
||||
|
||||
/*
|
||||
* Do the straightforward thing until (if ever) one run starts
|
||||
* winning consistently.
|
||||
*/
|
||||
do {
|
||||
assert len1 > 1 && len2 > 0;
|
||||
if (((Comparable) a[cursor2]).compareTo(tmp[cursor1]) < 0) {
|
||||
a[dest++] = a[cursor2++];
|
||||
count2++;
|
||||
count1 = 0;
|
||||
if (--len2 == 0)
|
||||
break outer;
|
||||
} else {
|
||||
a[dest++] = tmp[cursor1++];
|
||||
count1++;
|
||||
count2 = 0;
|
||||
if (--len1 == 1)
|
||||
break outer;
|
||||
}
|
||||
} while ((count1 | count2) < minGallop);
|
||||
|
||||
/*
|
||||
* One run is winning so consistently that galloping may be a
|
||||
* huge win. So try that, and continue galloping until (if ever)
|
||||
* neither run appears to be winning consistently anymore.
|
||||
*/
|
||||
do {
|
||||
assert len1 > 1 && len2 > 0;
|
||||
count1 = gallopRight((Comparable) a[cursor2], tmp, cursor1, len1, 0);
|
||||
if (count1 != 0) {
|
||||
System.arraycopy(tmp, cursor1, a, dest, count1);
|
||||
dest += count1;
|
||||
cursor1 += count1;
|
||||
len1 -= count1;
|
||||
if (len1 <= 1) // len1 == 1 || len1 == 0
|
||||
break outer;
|
||||
}
|
||||
a[dest++] = a[cursor2++];
|
||||
if (--len2 == 0)
|
||||
break outer;
|
||||
|
||||
count2 = gallopLeft((Comparable) tmp[cursor1], a, cursor2, len2, 0);
|
||||
if (count2 != 0) {
|
||||
System.arraycopy(a, cursor2, a, dest, count2);
|
||||
dest += count2;
|
||||
cursor2 += count2;
|
||||
len2 -= count2;
|
||||
if (len2 == 0)
|
||||
break outer;
|
||||
}
|
||||
a[dest++] = tmp[cursor1++];
|
||||
if (--len1 == 1)
|
||||
break outer;
|
||||
minGallop--;
|
||||
} while (count1 >= MIN_GALLOP | count2 >= MIN_GALLOP);
|
||||
if (minGallop < 0)
|
||||
minGallop = 0;
|
||||
minGallop += 2; // Penalize for leaving gallop mode
|
||||
} // End of "outer" loop
|
||||
this.minGallop = minGallop < 1 ? 1 : minGallop; // Write back to field
|
||||
|
||||
if (len1 == 1) {
|
||||
assert len2 > 0;
|
||||
System.arraycopy(a, cursor2, a, dest, len2);
|
||||
a[dest + len2] = tmp[cursor1]; // Last elt of run 1 to end of merge
|
||||
} else if (len1 == 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Comparison method violates its general contract!");
|
||||
} else {
|
||||
assert len2 == 0;
|
||||
assert len1 > 1;
|
||||
System.arraycopy(tmp, cursor1, a, dest, len1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Like mergeLo, except that this method should be called only if
|
||||
* len1 >= len2; mergeLo should be called if len1 <= len2. (Either method
|
||||
* may be called if len1 == len2.)
|
||||
*
|
||||
* @param base1 index of first element in first run to be merged
|
||||
* @param len1 length of first run to be merged (must be > 0)
|
||||
* @param base2 index of first element in second run to be merged
|
||||
* (must be aBase + aLen)
|
||||
* @param len2 length of second run to be merged (must be > 0)
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
private void mergeHi(int base1, int len1, int base2, int len2) {
|
||||
assert len1 > 0 && len2 > 0 && base1 + len1 == base2;
|
||||
|
||||
// Copy second run into temp array
|
||||
Object[] a = this.a; // For performance
|
||||
Object[] tmp = ensureCapacity(len2);
|
||||
int tmpBase = this.tmpBase;
|
||||
System.arraycopy(a, base2, tmp, tmpBase, len2);
|
||||
|
||||
int cursor1 = base1 + len1 - 1; // Indexes into a
|
||||
int cursor2 = tmpBase + len2 - 1; // Indexes into tmp array
|
||||
int dest = base2 + len2 - 1; // Indexes into a
|
||||
|
||||
// Move last element of first run and deal with degenerate cases
|
||||
a[dest--] = a[cursor1--];
|
||||
if (--len1 == 0) {
|
||||
System.arraycopy(tmp, tmpBase, a, dest - (len2 - 1), len2);
|
||||
return;
|
||||
}
|
||||
if (len2 == 1) {
|
||||
dest -= len1;
|
||||
cursor1 -= len1;
|
||||
System.arraycopy(a, cursor1 + 1, a, dest + 1, len1);
|
||||
a[dest] = tmp[cursor2];
|
||||
return;
|
||||
}
|
||||
|
||||
int minGallop = this.minGallop; // Use local variable for performance
|
||||
outer:
|
||||
while (true) {
|
||||
int count1 = 0; // Number of times in a row that first run won
|
||||
int count2 = 0; // Number of times in a row that second run won
|
||||
|
||||
/*
|
||||
* Do the straightforward thing until (if ever) one run
|
||||
* appears to win consistently.
|
||||
*/
|
||||
do {
|
||||
assert len1 > 0 && len2 > 1;
|
||||
if (((Comparable) tmp[cursor2]).compareTo(a[cursor1]) < 0) {
|
||||
a[dest--] = a[cursor1--];
|
||||
count1++;
|
||||
count2 = 0;
|
||||
if (--len1 == 0)
|
||||
break outer;
|
||||
} else {
|
||||
a[dest--] = tmp[cursor2--];
|
||||
count2++;
|
||||
count1 = 0;
|
||||
if (--len2 == 1)
|
||||
break outer;
|
||||
}
|
||||
} while ((count1 | count2) < minGallop);
|
||||
|
||||
/*
|
||||
* One run is winning so consistently that galloping may be a
|
||||
* huge win. So try that, and continue galloping until (if ever)
|
||||
* neither run appears to be winning consistently anymore.
|
||||
*/
|
||||
do {
|
||||
assert len1 > 0 && len2 > 1;
|
||||
count1 = len1 - gallopRight((Comparable) tmp[cursor2], a, base1, len1, len1 - 1);
|
||||
if (count1 != 0) {
|
||||
dest -= count1;
|
||||
cursor1 -= count1;
|
||||
len1 -= count1;
|
||||
System.arraycopy(a, cursor1 + 1, a, dest + 1, count1);
|
||||
if (len1 == 0)
|
||||
break outer;
|
||||
}
|
||||
a[dest--] = tmp[cursor2--];
|
||||
if (--len2 == 1)
|
||||
break outer;
|
||||
|
||||
count2 = len2 - gallopLeft((Comparable) a[cursor1], tmp, tmpBase, len2, len2 - 1);
|
||||
if (count2 != 0) {
|
||||
dest -= count2;
|
||||
cursor2 -= count2;
|
||||
len2 -= count2;
|
||||
System.arraycopy(tmp, cursor2 + 1, a, dest + 1, count2);
|
||||
if (len2 <= 1)
|
||||
break outer; // len2 == 1 || len2 == 0
|
||||
}
|
||||
a[dest--] = a[cursor1--];
|
||||
if (--len1 == 0)
|
||||
break outer;
|
||||
minGallop--;
|
||||
} while (count1 >= MIN_GALLOP | count2 >= MIN_GALLOP);
|
||||
if (minGallop < 0)
|
||||
minGallop = 0;
|
||||
minGallop += 2; // Penalize for leaving gallop mode
|
||||
} // End of "outer" loop
|
||||
this.minGallop = minGallop < 1 ? 1 : minGallop; // Write back to field
|
||||
|
||||
if (len2 == 1) {
|
||||
assert len1 > 0;
|
||||
dest -= len1;
|
||||
cursor1 -= len1;
|
||||
System.arraycopy(a, cursor1 + 1, a, dest + 1, len1);
|
||||
a[dest] = tmp[cursor2]; // Move first elt of run2 to front of merge
|
||||
} else if (len2 == 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Comparison method violates its general contract!");
|
||||
} else {
|
||||
assert len1 == 0;
|
||||
assert len2 > 0;
|
||||
System.arraycopy(tmp, tmpBase, a, dest - (len2 - 1), len2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the external array tmp has at least the specified
|
||||
* number of elements, increasing its size if necessary. The size
|
||||
* increases exponentially to ensure amortized linear time complexity.
|
||||
*
|
||||
* @param minCapacity the minimum required capacity of the tmp array
|
||||
* @return tmp, whether or not it grew
|
||||
*/
|
||||
private Object[] ensureCapacity(int minCapacity) {
|
||||
if (tmpLen < minCapacity) {
|
||||
// Compute smallest power of 2 > minCapacity
|
||||
int newSize = minCapacity;
|
||||
newSize |= newSize >> 1;
|
||||
newSize |= newSize >> 2;
|
||||
newSize |= newSize >> 4;
|
||||
newSize |= newSize >> 8;
|
||||
newSize |= newSize >> 16;
|
||||
newSize++;
|
||||
|
||||
if (newSize < 0) // Not bloody likely!
|
||||
newSize = minCapacity;
|
||||
else
|
||||
newSize = Math.min(newSize, a.length >>> 1);
|
||||
|
||||
@SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"})
|
||||
Object[] newArray = new Object[newSize];
|
||||
tmp = newArray;
|
||||
tmpLen = newSize;
|
||||
tmpBase = 0;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
}
|
||||
534
jdkSrc/jdk8/java/util/Comparator.java
Normal file
534
jdkSrc/jdk8/java/util/Comparator.java
Normal file
@@ -0,0 +1,534 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.ToIntFunction;
|
||||
import java.util.function.ToLongFunction;
|
||||
import java.util.function.ToDoubleFunction;
|
||||
import java.util.Comparators;
|
||||
|
||||
/**
|
||||
* A comparison function, which imposes a <i>total ordering</i> on some
|
||||
* collection of objects. Comparators can be passed to a sort method (such
|
||||
* as {@link Collections#sort(List,Comparator) Collections.sort} or {@link
|
||||
* Arrays#sort(Object[],Comparator) Arrays.sort}) to allow precise control
|
||||
* over the sort order. Comparators can also be used to control the order of
|
||||
* certain data structures (such as {@link SortedSet sorted sets} or {@link
|
||||
* SortedMap sorted maps}), or to provide an ordering for collections of
|
||||
* objects that don't have a {@link Comparable natural ordering}.<p>
|
||||
*
|
||||
* The ordering imposed by a comparator <tt>c</tt> on a set of elements
|
||||
* <tt>S</tt> is said to be <i>consistent with equals</i> if and only if
|
||||
* <tt>c.compare(e1, e2)==0</tt> has the same boolean value as
|
||||
* <tt>e1.equals(e2)</tt> for every <tt>e1</tt> and <tt>e2</tt> in
|
||||
* <tt>S</tt>.<p>
|
||||
*
|
||||
* Caution should be exercised when using a comparator capable of imposing an
|
||||
* ordering inconsistent with equals to order a sorted set (or sorted map).
|
||||
* Suppose a sorted set (or sorted map) with an explicit comparator <tt>c</tt>
|
||||
* is used with elements (or keys) drawn from a set <tt>S</tt>. If the
|
||||
* ordering imposed by <tt>c</tt> on <tt>S</tt> is inconsistent with equals,
|
||||
* the sorted set (or sorted map) will behave "strangely." In particular the
|
||||
* sorted set (or sorted map) will violate the general contract for set (or
|
||||
* map), which is defined in terms of <tt>equals</tt>.<p>
|
||||
*
|
||||
* For example, suppose one adds two elements {@code a} and {@code b} such that
|
||||
* {@code (a.equals(b) && c.compare(a, b) != 0)}
|
||||
* to an empty {@code TreeSet} with comparator {@code c}.
|
||||
* The second {@code add} operation will return
|
||||
* true (and the size of the tree set will increase) because {@code a} and
|
||||
* {@code b} are not equivalent from the tree set's perspective, even though
|
||||
* this is contrary to the specification of the
|
||||
* {@link Set#add Set.add} method.<p>
|
||||
*
|
||||
* Note: It is generally a good idea for comparators to also implement
|
||||
* <tt>java.io.Serializable</tt>, as they may be used as ordering methods in
|
||||
* serializable data structures (like {@link TreeSet}, {@link TreeMap}). In
|
||||
* order for the data structure to serialize successfully, the comparator (if
|
||||
* provided) must implement <tt>Serializable</tt>.<p>
|
||||
*
|
||||
* For the mathematically inclined, the <i>relation</i> that defines the
|
||||
* <i>imposed ordering</i> that a given comparator <tt>c</tt> imposes on a
|
||||
* given set of objects <tt>S</tt> is:<pre>
|
||||
* {(x, y) such that c.compare(x, y) <= 0}.
|
||||
* </pre> The <i>quotient</i> for this total order is:<pre>
|
||||
* {(x, y) such that c.compare(x, y) == 0}.
|
||||
* </pre>
|
||||
*
|
||||
* It follows immediately from the contract for <tt>compare</tt> that the
|
||||
* quotient is an <i>equivalence relation</i> on <tt>S</tt>, and that the
|
||||
* imposed ordering is a <i>total order</i> on <tt>S</tt>. When we say that
|
||||
* the ordering imposed by <tt>c</tt> on <tt>S</tt> is <i>consistent with
|
||||
* equals</i>, we mean that the quotient for the ordering is the equivalence
|
||||
* relation defined by the objects' {@link Object#equals(Object)
|
||||
* equals(Object)} method(s):<pre>
|
||||
* {(x, y) such that x.equals(y)}. </pre>
|
||||
*
|
||||
* <p>Unlike {@code Comparable}, a comparator may optionally permit
|
||||
* comparison of null arguments, while maintaining the requirements for
|
||||
* an equivalence relation.
|
||||
*
|
||||
* <p>This interface is a member of the
|
||||
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
|
||||
* Java Collections Framework</a>.
|
||||
*
|
||||
* @param <T> the type of objects that may be compared by this comparator
|
||||
*
|
||||
* @author Josh Bloch
|
||||
* @author Neal Gafter
|
||||
* @see Comparable
|
||||
* @see java.io.Serializable
|
||||
* @since 1.2
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface Comparator<T> {
|
||||
/**
|
||||
* Compares its two arguments for order. Returns a negative integer,
|
||||
* zero, or a positive integer as the first argument is less than, equal
|
||||
* to, or greater than the second.<p>
|
||||
*
|
||||
* In the foregoing description, the notation
|
||||
* <tt>sgn(</tt><i>expression</i><tt>)</tt> designates the mathematical
|
||||
* <i>signum</i> function, which is defined to return one of <tt>-1</tt>,
|
||||
* <tt>0</tt>, or <tt>1</tt> according to whether the value of
|
||||
* <i>expression</i> is negative, zero or positive.<p>
|
||||
*
|
||||
* The implementor must ensure that <tt>sgn(compare(x, y)) ==
|
||||
* -sgn(compare(y, x))</tt> for all <tt>x</tt> and <tt>y</tt>. (This
|
||||
* implies that <tt>compare(x, y)</tt> must throw an exception if and only
|
||||
* if <tt>compare(y, x)</tt> throws an exception.)<p>
|
||||
*
|
||||
* The implementor must also ensure that the relation is transitive:
|
||||
* <tt>((compare(x, y)>0) && (compare(y, z)>0))</tt> implies
|
||||
* <tt>compare(x, z)>0</tt>.<p>
|
||||
*
|
||||
* Finally, the implementor must ensure that <tt>compare(x, y)==0</tt>
|
||||
* implies that <tt>sgn(compare(x, z))==sgn(compare(y, z))</tt> for all
|
||||
* <tt>z</tt>.<p>
|
||||
*
|
||||
* It is generally the case, but <i>not</i> strictly required that
|
||||
* <tt>(compare(x, y)==0) == (x.equals(y))</tt>. Generally speaking,
|
||||
* any comparator that violates this condition should clearly indicate
|
||||
* this fact. The recommended language is "Note: this comparator
|
||||
* imposes orderings that are inconsistent with equals."
|
||||
*
|
||||
* @param o1 the first object to be compared.
|
||||
* @param o2 the second object to be compared.
|
||||
* @return a negative integer, zero, or a positive integer as the
|
||||
* first argument is less than, equal to, or greater than the
|
||||
* second.
|
||||
* @throws NullPointerException if an argument is null and this
|
||||
* comparator does not permit null arguments
|
||||
* @throws ClassCastException if the arguments' types prevent them from
|
||||
* being compared by this comparator.
|
||||
*/
|
||||
int compare(T o1, T o2);
|
||||
|
||||
/**
|
||||
* Indicates whether some other object is "equal to" this
|
||||
* comparator. This method must obey the general contract of
|
||||
* {@link Object#equals(Object)}. Additionally, this method can return
|
||||
* <tt>true</tt> <i>only</i> if the specified object is also a comparator
|
||||
* and it imposes the same ordering as this comparator. Thus,
|
||||
* <code>comp1.equals(comp2)</code> implies that <tt>sgn(comp1.compare(o1,
|
||||
* o2))==sgn(comp2.compare(o1, o2))</tt> for every object reference
|
||||
* <tt>o1</tt> and <tt>o2</tt>.<p>
|
||||
*
|
||||
* Note that it is <i>always</i> safe <i>not</i> to override
|
||||
* <tt>Object.equals(Object)</tt>. However, overriding this method may,
|
||||
* in some cases, improve performance by allowing programs to determine
|
||||
* that two distinct comparators impose the same order.
|
||||
*
|
||||
* @param obj the reference object with which to compare.
|
||||
* @return <code>true</code> only if the specified object is also
|
||||
* a comparator and it imposes the same ordering as this
|
||||
* comparator.
|
||||
* @see Object#equals(Object)
|
||||
* @see Object#hashCode()
|
||||
*/
|
||||
boolean equals(Object obj);
|
||||
|
||||
/**
|
||||
* Returns a comparator that imposes the reverse ordering of this
|
||||
* comparator.
|
||||
*
|
||||
* @return a comparator that imposes the reverse ordering of this
|
||||
* comparator.
|
||||
* @since 1.8
|
||||
*/
|
||||
default Comparator<T> reversed() {
|
||||
return Collections.reverseOrder(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a lexicographic-order comparator with another comparator.
|
||||
* If this {@code Comparator} considers two elements equal, i.e.
|
||||
* {@code compare(a, b) == 0}, {@code other} is used to determine the order.
|
||||
*
|
||||
* <p>The returned comparator is serializable if the specified comparator
|
||||
* is also serializable.
|
||||
*
|
||||
* @apiNote
|
||||
* For example, to sort a collection of {@code String} based on the length
|
||||
* and then case-insensitive natural ordering, the comparator can be
|
||||
* composed using following code,
|
||||
*
|
||||
* <pre>{@code
|
||||
* Comparator<String> cmp = Comparator.comparingInt(String::length)
|
||||
* .thenComparing(String.CASE_INSENSITIVE_ORDER);
|
||||
* }</pre>
|
||||
*
|
||||
* @param other the other comparator to be used when this comparator
|
||||
* compares two objects that are equal.
|
||||
* @return a lexicographic-order comparator composed of this and then the
|
||||
* other comparator
|
||||
* @throws NullPointerException if the argument is null.
|
||||
* @since 1.8
|
||||
*/
|
||||
default Comparator<T> thenComparing(Comparator<? super T> other) {
|
||||
Objects.requireNonNull(other);
|
||||
return (Comparator<T> & Serializable) (c1, c2) -> {
|
||||
int res = compare(c1, c2);
|
||||
return (res != 0) ? res : other.compare(c1, c2);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a lexicographic-order comparator with a function that
|
||||
* extracts a key to be compared with the given {@code Comparator}.
|
||||
*
|
||||
* @implSpec This default implementation behaves as if {@code
|
||||
* thenComparing(comparing(keyExtractor, cmp))}.
|
||||
*
|
||||
* @param <U> the type of the sort key
|
||||
* @param keyExtractor the function used to extract the sort key
|
||||
* @param keyComparator the {@code Comparator} used to compare the sort key
|
||||
* @return a lexicographic-order comparator composed of this comparator
|
||||
* and then comparing on the key extracted by the keyExtractor function
|
||||
* @throws NullPointerException if either argument is null.
|
||||
* @see #comparing(Function, Comparator)
|
||||
* @see #thenComparing(Comparator)
|
||||
* @since 1.8
|
||||
*/
|
||||
default <U> Comparator<T> thenComparing(
|
||||
Function<? super T, ? extends U> keyExtractor,
|
||||
Comparator<? super U> keyComparator)
|
||||
{
|
||||
return thenComparing(comparing(keyExtractor, keyComparator));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a lexicographic-order comparator with a function that
|
||||
* extracts a {@code Comparable} sort key.
|
||||
*
|
||||
* @implSpec This default implementation behaves as if {@code
|
||||
* thenComparing(comparing(keyExtractor))}.
|
||||
*
|
||||
* @param <U> the type of the {@link Comparable} sort key
|
||||
* @param keyExtractor the function used to extract the {@link
|
||||
* Comparable} sort key
|
||||
* @return a lexicographic-order comparator composed of this and then the
|
||||
* {@link Comparable} sort key.
|
||||
* @throws NullPointerException if the argument is null.
|
||||
* @see #comparing(Function)
|
||||
* @see #thenComparing(Comparator)
|
||||
* @since 1.8
|
||||
*/
|
||||
default <U extends Comparable<? super U>> Comparator<T> thenComparing(
|
||||
Function<? super T, ? extends U> keyExtractor)
|
||||
{
|
||||
return thenComparing(comparing(keyExtractor));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a lexicographic-order comparator with a function that
|
||||
* extracts a {@code int} sort key.
|
||||
*
|
||||
* @implSpec This default implementation behaves as if {@code
|
||||
* thenComparing(comparingInt(keyExtractor))}.
|
||||
*
|
||||
* @param keyExtractor the function used to extract the integer sort key
|
||||
* @return a lexicographic-order comparator composed of this and then the
|
||||
* {@code int} sort key
|
||||
* @throws NullPointerException if the argument is null.
|
||||
* @see #comparingInt(ToIntFunction)
|
||||
* @see #thenComparing(Comparator)
|
||||
* @since 1.8
|
||||
*/
|
||||
default Comparator<T> thenComparingInt(ToIntFunction<? super T> keyExtractor) {
|
||||
return thenComparing(comparingInt(keyExtractor));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a lexicographic-order comparator with a function that
|
||||
* extracts a {@code long} sort key.
|
||||
*
|
||||
* @implSpec This default implementation behaves as if {@code
|
||||
* thenComparing(comparingLong(keyExtractor))}.
|
||||
*
|
||||
* @param keyExtractor the function used to extract the long sort key
|
||||
* @return a lexicographic-order comparator composed of this and then the
|
||||
* {@code long} sort key
|
||||
* @throws NullPointerException if the argument is null.
|
||||
* @see #comparingLong(ToLongFunction)
|
||||
* @see #thenComparing(Comparator)
|
||||
* @since 1.8
|
||||
*/
|
||||
default Comparator<T> thenComparingLong(ToLongFunction<? super T> keyExtractor) {
|
||||
return thenComparing(comparingLong(keyExtractor));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a lexicographic-order comparator with a function that
|
||||
* extracts a {@code double} sort key.
|
||||
*
|
||||
* @implSpec This default implementation behaves as if {@code
|
||||
* thenComparing(comparingDouble(keyExtractor))}.
|
||||
*
|
||||
* @param keyExtractor the function used to extract the double sort key
|
||||
* @return a lexicographic-order comparator composed of this and then the
|
||||
* {@code double} sort key
|
||||
* @throws NullPointerException if the argument is null.
|
||||
* @see #comparingDouble(ToDoubleFunction)
|
||||
* @see #thenComparing(Comparator)
|
||||
* @since 1.8
|
||||
*/
|
||||
default Comparator<T> thenComparingDouble(ToDoubleFunction<? super T> keyExtractor) {
|
||||
return thenComparing(comparingDouble(keyExtractor));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a comparator that imposes the reverse of the <em>natural
|
||||
* ordering</em>.
|
||||
*
|
||||
* <p>The returned comparator is serializable and throws {@link
|
||||
* NullPointerException} when comparing {@code null}.
|
||||
*
|
||||
* @param <T> the {@link Comparable} type of element to be compared
|
||||
* @return a comparator that imposes the reverse of the <i>natural
|
||||
* ordering</i> on {@code Comparable} objects.
|
||||
* @see Comparable
|
||||
* @since 1.8
|
||||
*/
|
||||
public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() {
|
||||
return Collections.reverseOrder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a comparator that compares {@link Comparable} objects in natural
|
||||
* order.
|
||||
*
|
||||
* <p>The returned comparator is serializable and throws {@link
|
||||
* NullPointerException} when comparing {@code null}.
|
||||
*
|
||||
* @param <T> the {@link Comparable} type of element to be compared
|
||||
* @return a comparator that imposes the <i>natural ordering</i> on {@code
|
||||
* Comparable} objects.
|
||||
* @see Comparable
|
||||
* @since 1.8
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
|
||||
return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a null-friendly comparator that considers {@code null} to be
|
||||
* less than non-null. When both are {@code null}, they are considered
|
||||
* equal. If both are non-null, the specified {@code Comparator} is used
|
||||
* to determine the order. If the specified comparator is {@code null},
|
||||
* then the returned comparator considers all non-null values to be equal.
|
||||
*
|
||||
* <p>The returned comparator is serializable if the specified comparator
|
||||
* is serializable.
|
||||
*
|
||||
* @param <T> the type of the elements to be compared
|
||||
* @param comparator a {@code Comparator} for comparing non-null values
|
||||
* @return a comparator that considers {@code null} to be less than
|
||||
* non-null, and compares non-null objects with the supplied
|
||||
* {@code Comparator}.
|
||||
* @since 1.8
|
||||
*/
|
||||
public static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator) {
|
||||
return new Comparators.NullComparator<>(true, comparator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a null-friendly comparator that considers {@code null} to be
|
||||
* greater than non-null. When both are {@code null}, they are considered
|
||||
* equal. If both are non-null, the specified {@code Comparator} is used
|
||||
* to determine the order. If the specified comparator is {@code null},
|
||||
* then the returned comparator considers all non-null values to be equal.
|
||||
*
|
||||
* <p>The returned comparator is serializable if the specified comparator
|
||||
* is serializable.
|
||||
*
|
||||
* @param <T> the type of the elements to be compared
|
||||
* @param comparator a {@code Comparator} for comparing non-null values
|
||||
* @return a comparator that considers {@code null} to be greater than
|
||||
* non-null, and compares non-null objects with the supplied
|
||||
* {@code Comparator}.
|
||||
* @since 1.8
|
||||
*/
|
||||
public static <T> Comparator<T> nullsLast(Comparator<? super T> comparator) {
|
||||
return new Comparators.NullComparator<>(false, comparator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts a function that extracts a sort key from a type {@code T}, and
|
||||
* returns a {@code Comparator<T>} that compares by that sort key using
|
||||
* the specified {@link Comparator}.
|
||||
*
|
||||
* <p>The returned comparator is serializable if the specified function
|
||||
* and comparator are both serializable.
|
||||
*
|
||||
* @apiNote
|
||||
* For example, to obtain a {@code Comparator} that compares {@code
|
||||
* Person} objects by their last name ignoring case differences,
|
||||
*
|
||||
* <pre>{@code
|
||||
* Comparator<Person> cmp = Comparator.comparing(
|
||||
* Person::getLastName,
|
||||
* String.CASE_INSENSITIVE_ORDER);
|
||||
* }</pre>
|
||||
*
|
||||
* @param <T> the type of element to be compared
|
||||
* @param <U> the type of the sort key
|
||||
* @param keyExtractor the function used to extract the sort key
|
||||
* @param keyComparator the {@code Comparator} used to compare the sort key
|
||||
* @return a comparator that compares by an extracted key using the
|
||||
* specified {@code Comparator}
|
||||
* @throws NullPointerException if either argument is null
|
||||
* @since 1.8
|
||||
*/
|
||||
public static <T, U> Comparator<T> comparing(
|
||||
Function<? super T, ? extends U> keyExtractor,
|
||||
Comparator<? super U> keyComparator)
|
||||
{
|
||||
Objects.requireNonNull(keyExtractor);
|
||||
Objects.requireNonNull(keyComparator);
|
||||
return (Comparator<T> & Serializable)
|
||||
(c1, c2) -> keyComparator.compare(keyExtractor.apply(c1),
|
||||
keyExtractor.apply(c2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts a function that extracts a {@link java.lang.Comparable
|
||||
* Comparable} sort key from a type {@code T}, and returns a {@code
|
||||
* Comparator<T>} that compares by that sort key.
|
||||
*
|
||||
* <p>The returned comparator is serializable if the specified function
|
||||
* is also serializable.
|
||||
*
|
||||
* @apiNote
|
||||
* For example, to obtain a {@code Comparator} that compares {@code
|
||||
* Person} objects by their last name,
|
||||
*
|
||||
* <pre>{@code
|
||||
* Comparator<Person> byLastName = Comparator.comparing(Person::getLastName);
|
||||
* }</pre>
|
||||
*
|
||||
* @param <T> the type of element to be compared
|
||||
* @param <U> the type of the {@code Comparable} sort key
|
||||
* @param keyExtractor the function used to extract the {@link
|
||||
* Comparable} sort key
|
||||
* @return a comparator that compares by an extracted key
|
||||
* @throws NullPointerException if the argument is null
|
||||
* @since 1.8
|
||||
*/
|
||||
public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
|
||||
Function<? super T, ? extends U> keyExtractor)
|
||||
{
|
||||
Objects.requireNonNull(keyExtractor);
|
||||
return (Comparator<T> & Serializable)
|
||||
(c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts a function that extracts an {@code int} sort key from a type
|
||||
* {@code T}, and returns a {@code Comparator<T>} that compares by that
|
||||
* sort key.
|
||||
*
|
||||
* <p>The returned comparator is serializable if the specified function
|
||||
* is also serializable.
|
||||
*
|
||||
* @param <T> the type of element to be compared
|
||||
* @param keyExtractor the function used to extract the integer sort key
|
||||
* @return a comparator that compares by an extracted key
|
||||
* @see #comparing(Function)
|
||||
* @throws NullPointerException if the argument is null
|
||||
* @since 1.8
|
||||
*/
|
||||
public static <T> Comparator<T> comparingInt(ToIntFunction<? super T> keyExtractor) {
|
||||
Objects.requireNonNull(keyExtractor);
|
||||
return (Comparator<T> & Serializable)
|
||||
(c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts a function that extracts a {@code long} sort key from a type
|
||||
* {@code T}, and returns a {@code Comparator<T>} that compares by that
|
||||
* sort key.
|
||||
*
|
||||
* <p>The returned comparator is serializable if the specified function is
|
||||
* also serializable.
|
||||
*
|
||||
* @param <T> the type of element to be compared
|
||||
* @param keyExtractor the function used to extract the long sort key
|
||||
* @return a comparator that compares by an extracted key
|
||||
* @see #comparing(Function)
|
||||
* @throws NullPointerException if the argument is null
|
||||
* @since 1.8
|
||||
*/
|
||||
public static <T> Comparator<T> comparingLong(ToLongFunction<? super T> keyExtractor) {
|
||||
Objects.requireNonNull(keyExtractor);
|
||||
return (Comparator<T> & Serializable)
|
||||
(c1, c2) -> Long.compare(keyExtractor.applyAsLong(c1), keyExtractor.applyAsLong(c2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts a function that extracts a {@code double} sort key from a type
|
||||
* {@code T}, and returns a {@code Comparator<T>} that compares by that
|
||||
* sort key.
|
||||
*
|
||||
* <p>The returned comparator is serializable if the specified function
|
||||
* is also serializable.
|
||||
*
|
||||
* @param <T> the type of element to be compared
|
||||
* @param keyExtractor the function used to extract the double sort key
|
||||
* @return a comparator that compares by an extracted key
|
||||
* @see #comparing(Function)
|
||||
* @throws NullPointerException if the argument is null
|
||||
* @since 1.8
|
||||
*/
|
||||
public static<T> Comparator<T> comparingDouble(ToDoubleFunction<? super T> keyExtractor) {
|
||||
Objects.requireNonNull(keyExtractor);
|
||||
return (Comparator<T> & Serializable)
|
||||
(c1, c2) -> Double.compare(keyExtractor.applyAsDouble(c1), keyExtractor.applyAsDouble(c2));
|
||||
}
|
||||
}
|
||||
98
jdkSrc/jdk8/java/util/Comparators.java
Normal file
98
jdkSrc/jdk8/java/util/Comparators.java
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.util;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.function.BinaryOperator;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.ToDoubleFunction;
|
||||
import java.util.function.ToIntFunction;
|
||||
import java.util.function.ToLongFunction;
|
||||
|
||||
/**
|
||||
* Package private supporting class for {@link Comparator}.
|
||||
*/
|
||||
class Comparators {
|
||||
private Comparators() {
|
||||
throw new AssertionError("no instances");
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares {@link Comparable} objects in natural order.
|
||||
*
|
||||
* @see Comparable
|
||||
*/
|
||||
enum NaturalOrderComparator implements Comparator<Comparable<Object>> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public int compare(Comparable<Object> c1, Comparable<Object> c2) {
|
||||
return c1.compareTo(c2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Comparator<Comparable<Object>> reversed() {
|
||||
return Comparator.reverseOrder();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Null-friendly comparators
|
||||
*/
|
||||
final static class NullComparator<T> implements Comparator<T>, Serializable {
|
||||
private static final long serialVersionUID = -7569533591570686392L;
|
||||
private final boolean nullFirst;
|
||||
// if null, non-null Ts are considered equal
|
||||
private final Comparator<T> real;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
NullComparator(boolean nullFirst, Comparator<? super T> real) {
|
||||
this.nullFirst = nullFirst;
|
||||
this.real = (Comparator<T>) real;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(T a, T b) {
|
||||
if (a == null) {
|
||||
return (b == null) ? 0 : (nullFirst ? -1 : 1);
|
||||
} else if (b == null) {
|
||||
return nullFirst ? 1: -1;
|
||||
} else {
|
||||
return (real == null) ? 0 : real.compare(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Comparator<T> thenComparing(Comparator<? super T> other) {
|
||||
Objects.requireNonNull(other);
|
||||
return new NullComparator<>(nullFirst, real == null ? other : real.thenComparing(other));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Comparator<T> reversed() {
|
||||
return new NullComparator<>(!nullFirst, real == null ? null : real.reversed());
|
||||
}
|
||||
}
|
||||
}
|
||||
124
jdkSrc/jdk8/java/util/ConcurrentModificationException.java
Normal file
124
jdkSrc/jdk8/java/util/ConcurrentModificationException.java
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* This exception may be thrown by methods that have detected concurrent
|
||||
* modification of an object when such modification is not permissible.
|
||||
* <p>
|
||||
* For example, it is not generally permissible for one thread to modify a Collection
|
||||
* while another thread is iterating over it. In general, the results of the
|
||||
* iteration are undefined under these circumstances. Some Iterator
|
||||
* implementations (including those of all the general purpose collection implementations
|
||||
* provided by the JRE) may choose to throw this exception if this behavior is
|
||||
* detected. Iterators that do this are known as <i>fail-fast</i> iterators,
|
||||
* as they fail quickly and cleanly, rather that risking arbitrary,
|
||||
* non-deterministic behavior at an undetermined time in the future.
|
||||
* <p>
|
||||
* Note that this exception does not always indicate that an object has
|
||||
* been concurrently modified by a <i>different</i> thread. If a single
|
||||
* thread issues a sequence of method invocations that violates the
|
||||
* contract of an object, the object may throw this exception. For
|
||||
* example, if a thread modifies a collection directly while it is
|
||||
* iterating over the collection with a fail-fast iterator, the iterator
|
||||
* will throw this exception.
|
||||
*
|
||||
* <p>Note that fail-fast behavior cannot be guaranteed as it is, generally
|
||||
* speaking, impossible to make any hard guarantees in the presence of
|
||||
* unsynchronized concurrent modification. Fail-fast operations
|
||||
* throw {@code ConcurrentModificationException} on a best-effort basis.
|
||||
* Therefore, it would be wrong to write a program that depended on this
|
||||
* exception for its correctness: <i>{@code ConcurrentModificationException}
|
||||
* should be used only to detect bugs.</i>
|
||||
*
|
||||
* @author Josh Bloch
|
||||
* @see Collection
|
||||
* @see Iterator
|
||||
* @see Spliterator
|
||||
* @see ListIterator
|
||||
* @see Vector
|
||||
* @see LinkedList
|
||||
* @see HashSet
|
||||
* @see Hashtable
|
||||
* @see TreeMap
|
||||
* @see AbstractList
|
||||
* @since 1.2
|
||||
*/
|
||||
public class ConcurrentModificationException extends RuntimeException {
|
||||
private static final long serialVersionUID = -3666751008965953603L;
|
||||
|
||||
/**
|
||||
* Constructs a ConcurrentModificationException with no
|
||||
* detail message.
|
||||
*/
|
||||
public ConcurrentModificationException() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a {@code ConcurrentModificationException} with the
|
||||
* specified detail message.
|
||||
*
|
||||
* @param message the detail message pertaining to this exception.
|
||||
*/
|
||||
public ConcurrentModificationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new exception with the specified cause and a detail
|
||||
* message of {@code (cause==null ? null : cause.toString())} (which
|
||||
* typically contains the class and detail message of {@code cause}.
|
||||
*
|
||||
* @param cause the cause (which is saved for later retrieval by the
|
||||
* {@link Throwable#getCause()} method). (A {@code null} value is
|
||||
* permitted, and indicates that the cause is nonexistent or
|
||||
* unknown.)
|
||||
* @since 1.7
|
||||
*/
|
||||
public ConcurrentModificationException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new exception with the specified detail message and
|
||||
* cause.
|
||||
*
|
||||
* <p>Note that the detail message associated with <code>cause</code> is
|
||||
* <i>not</i> automatically incorporated in this exception's detail
|
||||
* message.
|
||||
*
|
||||
* @param message the detail message (which is saved for later retrieval
|
||||
* by the {@link Throwable#getMessage()} method).
|
||||
* @param cause the cause (which is saved for later retrieval by the
|
||||
* {@link Throwable#getCause()} method). (A {@code null} value
|
||||
* is permitted, and indicates that the cause is nonexistent or
|
||||
* unknown.)
|
||||
* @since 1.7
|
||||
*/
|
||||
public ConcurrentModificationException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
783
jdkSrc/jdk8/java/util/Currency.java
Normal file
783
jdkSrc/jdk8/java/util/Currency.java
Normal file
@@ -0,0 +1,783 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.spi.CurrencyNameProvider;
|
||||
import sun.util.locale.provider.LocaleServiceProviderPool;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
|
||||
/**
|
||||
* Represents a currency. Currencies are identified by their ISO 4217 currency
|
||||
* codes. Visit the <a href="http://www.iso.org/iso/home/standards/currency_codes.htm">
|
||||
* ISO web site</a> for more information.
|
||||
* <p>
|
||||
* The class is designed so that there's never more than one
|
||||
* <code>Currency</code> instance for any given currency. Therefore, there's
|
||||
* no public constructor. You obtain a <code>Currency</code> instance using
|
||||
* the <code>getInstance</code> methods.
|
||||
* <p>
|
||||
* Users can supersede the Java runtime currency data by means of the system
|
||||
* property {@code java.util.currency.data}. If this system property is
|
||||
* defined then its value is the location of a properties file, the contents of
|
||||
* which are key/value pairs of the ISO 3166 country codes and the ISO 4217
|
||||
* currency data respectively. The value part consists of three ISO 4217 values
|
||||
* of a currency, i.e., an alphabetic code, a numeric code, and a minor unit.
|
||||
* Those three ISO 4217 values are separated by commas.
|
||||
* The lines which start with '#'s are considered comment lines. An optional UTC
|
||||
* timestamp may be specified per currency entry if users need to specify a
|
||||
* cutover date indicating when the new data comes into effect. The timestamp is
|
||||
* appended to the end of the currency properties and uses a comma as a separator.
|
||||
* If a UTC datestamp is present and valid, the JRE will only use the new currency
|
||||
* properties if the current UTC date is later than the date specified at class
|
||||
* loading time. The format of the timestamp must be of ISO 8601 format :
|
||||
* {@code 'yyyy-MM-dd'T'HH:mm:ss'}. For example,
|
||||
* <p>
|
||||
* <code>
|
||||
* #Sample currency properties<br>
|
||||
* JP=JPZ,999,0
|
||||
* </code>
|
||||
* <p>
|
||||
* will supersede the currency data for Japan.
|
||||
*
|
||||
* <p>
|
||||
* <code>
|
||||
* #Sample currency properties with cutover date<br>
|
||||
* JP=JPZ,999,0,2014-01-01T00:00:00
|
||||
* </code>
|
||||
* <p>
|
||||
* will supersede the currency data for Japan if {@code Currency} class is loaded after
|
||||
* 1st January 2014 00:00:00 GMT.
|
||||
* <p>
|
||||
* Where syntactically malformed entries are encountered, the entry is ignored
|
||||
* and the remainder of entries in file are processed. For instances where duplicate
|
||||
* country code entries exist, the behavior of the Currency information for that
|
||||
* {@code Currency} is undefined and the remainder of entries in file are processed.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
public final class Currency implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -158308464356906721L;
|
||||
|
||||
/**
|
||||
* ISO 4217 currency code for this currency.
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
private final String currencyCode;
|
||||
|
||||
/**
|
||||
* Default fraction digits for this currency.
|
||||
* Set from currency data tables.
|
||||
*/
|
||||
transient private final int defaultFractionDigits;
|
||||
|
||||
/**
|
||||
* ISO 4217 numeric code for this currency.
|
||||
* Set from currency data tables.
|
||||
*/
|
||||
transient private final int numericCode;
|
||||
|
||||
|
||||
// class data: instance map
|
||||
|
||||
private static ConcurrentMap<String, Currency> instances = new ConcurrentHashMap<>(7);
|
||||
private static HashSet<Currency> available;
|
||||
|
||||
// Class data: currency data obtained from currency.data file.
|
||||
// Purpose:
|
||||
// - determine valid country codes
|
||||
// - determine valid currency codes
|
||||
// - map country codes to currency codes
|
||||
// - obtain default fraction digits for currency codes
|
||||
//
|
||||
// sc = special case; dfd = default fraction digits
|
||||
// Simple countries are those where the country code is a prefix of the
|
||||
// currency code, and there are no known plans to change the currency.
|
||||
//
|
||||
// table formats:
|
||||
// - mainTable:
|
||||
// - maps country code to 32-bit int
|
||||
// - 26*26 entries, corresponding to [A-Z]*[A-Z]
|
||||
// - \u007F -> not valid country
|
||||
// - bits 20-31: unused
|
||||
// - bits 10-19: numeric code (0 to 1023)
|
||||
// - bit 9: 1 - special case, bits 0-4 indicate which one
|
||||
// 0 - simple country, bits 0-4 indicate final char of currency code
|
||||
// - bits 5-8: fraction digits for simple countries, 0 for special cases
|
||||
// - bits 0-4: final char for currency code for simple country, or ID of special case
|
||||
// - special case IDs:
|
||||
// - 0: country has no currency
|
||||
// - other: index into sc* arrays + 1
|
||||
// - scCutOverTimes: cut-over time in millis as returned by
|
||||
// System.currentTimeMillis for special case countries that are changing
|
||||
// currencies; Long.MAX_VALUE for countries that are not changing currencies
|
||||
// - scOldCurrencies: old currencies for special case countries
|
||||
// - scNewCurrencies: new currencies for special case countries that are
|
||||
// changing currencies; null for others
|
||||
// - scOldCurrenciesDFD: default fraction digits for old currencies
|
||||
// - scNewCurrenciesDFD: default fraction digits for new currencies, 0 for
|
||||
// countries that are not changing currencies
|
||||
// - otherCurrencies: concatenation of all currency codes that are not the
|
||||
// main currency of a simple country, separated by "-"
|
||||
// - otherCurrenciesDFD: decimal format digits for currencies in otherCurrencies, same order
|
||||
|
||||
static int formatVersion;
|
||||
static int dataVersion;
|
||||
static int[] mainTable;
|
||||
static long[] scCutOverTimes;
|
||||
static String[] scOldCurrencies;
|
||||
static String[] scNewCurrencies;
|
||||
static int[] scOldCurrenciesDFD;
|
||||
static int[] scNewCurrenciesDFD;
|
||||
static int[] scOldCurrenciesNumericCode;
|
||||
static int[] scNewCurrenciesNumericCode;
|
||||
static String otherCurrencies;
|
||||
static int[] otherCurrenciesDFD;
|
||||
static int[] otherCurrenciesNumericCode;
|
||||
|
||||
// handy constants - must match definitions in GenerateCurrencyData
|
||||
// magic number
|
||||
private static final int MAGIC_NUMBER = 0x43757244;
|
||||
// number of characters from A to Z
|
||||
private static final int A_TO_Z = ('Z' - 'A') + 1;
|
||||
// entry for invalid country codes
|
||||
private static final int INVALID_COUNTRY_ENTRY = 0x0000007F;
|
||||
// entry for countries without currency
|
||||
private static final int COUNTRY_WITHOUT_CURRENCY_ENTRY = 0x00000200;
|
||||
// mask for simple case country entries
|
||||
private static final int SIMPLE_CASE_COUNTRY_MASK = 0x00000000;
|
||||
// mask for simple case country entry final character
|
||||
private static final int SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK = 0x0000001F;
|
||||
// mask for simple case country entry default currency digits
|
||||
private static final int SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK = 0x000001E0;
|
||||
// shift count for simple case country entry default currency digits
|
||||
private static final int SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT = 5;
|
||||
// maximum number for simple case country entry default currency digits
|
||||
private static final int SIMPLE_CASE_COUNTRY_MAX_DEFAULT_DIGITS = 9;
|
||||
// mask for special case country entries
|
||||
private static final int SPECIAL_CASE_COUNTRY_MASK = 0x00000200;
|
||||
// mask for special case country index
|
||||
private static final int SPECIAL_CASE_COUNTRY_INDEX_MASK = 0x0000001F;
|
||||
// delta from entry index component in main table to index into special case tables
|
||||
private static final int SPECIAL_CASE_COUNTRY_INDEX_DELTA = 1;
|
||||
// mask for distinguishing simple and special case countries
|
||||
private static final int COUNTRY_TYPE_MASK = SIMPLE_CASE_COUNTRY_MASK | SPECIAL_CASE_COUNTRY_MASK;
|
||||
// mask for the numeric code of the currency
|
||||
private static final int NUMERIC_CODE_MASK = 0x000FFC00;
|
||||
// shift count for the numeric code of the currency
|
||||
private static final int NUMERIC_CODE_SHIFT = 10;
|
||||
|
||||
// Currency data format version
|
||||
private static final int VALID_FORMAT_VERSION = 2;
|
||||
|
||||
static {
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
@Override
|
||||
public Void run() {
|
||||
String homeDir = System.getProperty("java.home");
|
||||
try {
|
||||
String dataFile = homeDir + File.separator +
|
||||
"lib" + File.separator + "currency.data";
|
||||
try (DataInputStream dis = new DataInputStream(
|
||||
new BufferedInputStream(
|
||||
new FileInputStream(dataFile)))) {
|
||||
if (dis.readInt() != MAGIC_NUMBER) {
|
||||
throw new InternalError("Currency data is possibly corrupted");
|
||||
}
|
||||
formatVersion = dis.readInt();
|
||||
if (formatVersion != VALID_FORMAT_VERSION) {
|
||||
throw new InternalError("Currency data format is incorrect");
|
||||
}
|
||||
dataVersion = dis.readInt();
|
||||
mainTable = readIntArray(dis, A_TO_Z * A_TO_Z);
|
||||
int scCount = dis.readInt();
|
||||
scCutOverTimes = readLongArray(dis, scCount);
|
||||
scOldCurrencies = readStringArray(dis, scCount);
|
||||
scNewCurrencies = readStringArray(dis, scCount);
|
||||
scOldCurrenciesDFD = readIntArray(dis, scCount);
|
||||
scNewCurrenciesDFD = readIntArray(dis, scCount);
|
||||
scOldCurrenciesNumericCode = readIntArray(dis, scCount);
|
||||
scNewCurrenciesNumericCode = readIntArray(dis, scCount);
|
||||
int ocCount = dis.readInt();
|
||||
otherCurrencies = dis.readUTF();
|
||||
otherCurrenciesDFD = readIntArray(dis, ocCount);
|
||||
otherCurrenciesNumericCode = readIntArray(dis, ocCount);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new InternalError(e);
|
||||
}
|
||||
|
||||
// look for the properties file for overrides
|
||||
String propsFile = System.getProperty("java.util.currency.data");
|
||||
if (propsFile == null) {
|
||||
propsFile = homeDir + File.separator + "lib" +
|
||||
File.separator + "currency.properties";
|
||||
}
|
||||
try {
|
||||
File propFile = new File(propsFile);
|
||||
if (propFile.exists()) {
|
||||
Properties props = new Properties();
|
||||
try (FileReader fr = new FileReader(propFile)) {
|
||||
props.load(fr);
|
||||
}
|
||||
Set<String> keys = props.stringPropertyNames();
|
||||
Pattern propertiesPattern =
|
||||
Pattern.compile("([A-Z]{3})\\s*,\\s*(\\d{3})\\s*,\\s*" +
|
||||
"(\\d+)\\s*,?\\s*(\\d{4}-\\d{2}-\\d{2}T\\d{2}:" +
|
||||
"\\d{2}:\\d{2})?");
|
||||
for (String key : keys) {
|
||||
replaceCurrencyData(propertiesPattern,
|
||||
key.toUpperCase(Locale.ROOT),
|
||||
props.getProperty(key).toUpperCase(Locale.ROOT));
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
info("currency.properties is ignored because of an IOException", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Constants for retrieving localized names from the name providers.
|
||||
*/
|
||||
private static final int SYMBOL = 0;
|
||||
private static final int DISPLAYNAME = 1;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a <code>Currency</code> instance. The constructor is private
|
||||
* so that we can insure that there's never more than one instance for a
|
||||
* given currency.
|
||||
*/
|
||||
private Currency(String currencyCode, int defaultFractionDigits, int numericCode) {
|
||||
this.currencyCode = currencyCode;
|
||||
this.defaultFractionDigits = defaultFractionDigits;
|
||||
this.numericCode = numericCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>Currency</code> instance for the given currency code.
|
||||
*
|
||||
* @param currencyCode the ISO 4217 code of the currency
|
||||
* @return the <code>Currency</code> instance for the given currency code
|
||||
* @exception NullPointerException if <code>currencyCode</code> is null
|
||||
* @exception IllegalArgumentException if <code>currencyCode</code> is not
|
||||
* a supported ISO 4217 code.
|
||||
*/
|
||||
public static Currency getInstance(String currencyCode) {
|
||||
return getInstance(currencyCode, Integer.MIN_VALUE, 0);
|
||||
}
|
||||
|
||||
private static Currency getInstance(String currencyCode, int defaultFractionDigits,
|
||||
int numericCode) {
|
||||
// Try to look up the currency code in the instances table.
|
||||
// This does the null pointer check as a side effect.
|
||||
// Also, if there already is an entry, the currencyCode must be valid.
|
||||
Currency instance = instances.get(currencyCode);
|
||||
if (instance != null) {
|
||||
return instance;
|
||||
}
|
||||
|
||||
if (defaultFractionDigits == Integer.MIN_VALUE) {
|
||||
// Currency code not internally generated, need to verify first
|
||||
// A currency code must have 3 characters and exist in the main table
|
||||
// or in the list of other currencies.
|
||||
if (currencyCode.length() != 3) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
char char1 = currencyCode.charAt(0);
|
||||
char char2 = currencyCode.charAt(1);
|
||||
int tableEntry = getMainTableEntry(char1, char2);
|
||||
if ((tableEntry & COUNTRY_TYPE_MASK) == SIMPLE_CASE_COUNTRY_MASK
|
||||
&& tableEntry != INVALID_COUNTRY_ENTRY
|
||||
&& currencyCode.charAt(2) - 'A' == (tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK)) {
|
||||
defaultFractionDigits = (tableEntry & SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK) >> SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT;
|
||||
numericCode = (tableEntry & NUMERIC_CODE_MASK) >> NUMERIC_CODE_SHIFT;
|
||||
} else {
|
||||
// Check for '-' separately so we don't get false hits in the table.
|
||||
if (currencyCode.charAt(2) == '-') {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
int index = otherCurrencies.indexOf(currencyCode);
|
||||
if (index == -1) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
defaultFractionDigits = otherCurrenciesDFD[index / 4];
|
||||
numericCode = otherCurrenciesNumericCode[index / 4];
|
||||
}
|
||||
}
|
||||
|
||||
Currency currencyVal =
|
||||
new Currency(currencyCode, defaultFractionDigits, numericCode);
|
||||
instance = instances.putIfAbsent(currencyCode, currencyVal);
|
||||
return (instance != null ? instance : currencyVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>Currency</code> instance for the country of the
|
||||
* given locale. The language and variant components of the locale
|
||||
* are ignored. The result may vary over time, as countries change their
|
||||
* currencies. For example, for the original member countries of the
|
||||
* European Monetary Union, the method returns the old national currencies
|
||||
* until December 31, 2001, and the Euro from January 1, 2002, local time
|
||||
* of the respective countries.
|
||||
* <p>
|
||||
* The method returns <code>null</code> for territories that don't
|
||||
* have a currency, such as Antarctica.
|
||||
*
|
||||
* @param locale the locale for whose country a <code>Currency</code>
|
||||
* instance is needed
|
||||
* @return the <code>Currency</code> instance for the country of the given
|
||||
* locale, or {@code null}
|
||||
* @exception NullPointerException if <code>locale</code> or its country
|
||||
* code is {@code null}
|
||||
* @exception IllegalArgumentException if the country of the given {@code locale}
|
||||
* is not a supported ISO 3166 country code.
|
||||
*/
|
||||
public static Currency getInstance(Locale locale) {
|
||||
String country = locale.getCountry();
|
||||
if (country == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
if (country.length() != 2) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
char char1 = country.charAt(0);
|
||||
char char2 = country.charAt(1);
|
||||
int tableEntry = getMainTableEntry(char1, char2);
|
||||
if ((tableEntry & COUNTRY_TYPE_MASK) == SIMPLE_CASE_COUNTRY_MASK
|
||||
&& tableEntry != INVALID_COUNTRY_ENTRY) {
|
||||
char finalChar = (char) ((tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK) + 'A');
|
||||
int defaultFractionDigits = (tableEntry & SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK) >> SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT;
|
||||
int numericCode = (tableEntry & NUMERIC_CODE_MASK) >> NUMERIC_CODE_SHIFT;
|
||||
StringBuilder sb = new StringBuilder(country);
|
||||
sb.append(finalChar);
|
||||
return getInstance(sb.toString(), defaultFractionDigits, numericCode);
|
||||
} else {
|
||||
// special cases
|
||||
if (tableEntry == INVALID_COUNTRY_ENTRY) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
if (tableEntry == COUNTRY_WITHOUT_CURRENCY_ENTRY) {
|
||||
return null;
|
||||
} else {
|
||||
int index = (tableEntry & SPECIAL_CASE_COUNTRY_INDEX_MASK) - SPECIAL_CASE_COUNTRY_INDEX_DELTA;
|
||||
if (scCutOverTimes[index] == Long.MAX_VALUE || System.currentTimeMillis() < scCutOverTimes[index]) {
|
||||
return getInstance(scOldCurrencies[index], scOldCurrenciesDFD[index],
|
||||
scOldCurrenciesNumericCode[index]);
|
||||
} else {
|
||||
return getInstance(scNewCurrencies[index], scNewCurrenciesDFD[index],
|
||||
scNewCurrenciesNumericCode[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the set of available currencies. The returned set of currencies
|
||||
* contains all of the available currencies, which may include currencies
|
||||
* that represent obsolete ISO 4217 codes. The set can be modified
|
||||
* without affecting the available currencies in the runtime.
|
||||
*
|
||||
* @return the set of available currencies. If there is no currency
|
||||
* available in the runtime, the returned set is empty.
|
||||
* @since 1.7
|
||||
*/
|
||||
public static Set<Currency> getAvailableCurrencies() {
|
||||
synchronized(Currency.class) {
|
||||
if (available == null) {
|
||||
available = new HashSet<>(256);
|
||||
|
||||
// Add simple currencies first
|
||||
for (char c1 = 'A'; c1 <= 'Z'; c1 ++) {
|
||||
for (char c2 = 'A'; c2 <= 'Z'; c2 ++) {
|
||||
int tableEntry = getMainTableEntry(c1, c2);
|
||||
if ((tableEntry & COUNTRY_TYPE_MASK) == SIMPLE_CASE_COUNTRY_MASK
|
||||
&& tableEntry != INVALID_COUNTRY_ENTRY) {
|
||||
char finalChar = (char) ((tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK) + 'A');
|
||||
int defaultFractionDigits = (tableEntry & SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK) >> SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT;
|
||||
int numericCode = (tableEntry & NUMERIC_CODE_MASK) >> NUMERIC_CODE_SHIFT;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(c1);
|
||||
sb.append(c2);
|
||||
sb.append(finalChar);
|
||||
available.add(getInstance(sb.toString(), defaultFractionDigits, numericCode));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now add other currencies
|
||||
StringTokenizer st = new StringTokenizer(otherCurrencies, "-");
|
||||
while (st.hasMoreElements()) {
|
||||
available.add(getInstance((String)st.nextElement()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Set<Currency> result = (Set<Currency>) available.clone();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ISO 4217 currency code of this currency.
|
||||
*
|
||||
* @return the ISO 4217 currency code of this currency.
|
||||
*/
|
||||
public String getCurrencyCode() {
|
||||
return currencyCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the symbol of this currency for the default
|
||||
* {@link Locale.Category#DISPLAY DISPLAY} locale.
|
||||
* For example, for the US Dollar, the symbol is "$" if the default
|
||||
* locale is the US, while for other locales it may be "US$". If no
|
||||
* symbol can be determined, the ISO 4217 currency code is returned.
|
||||
* <p>
|
||||
* This is equivalent to calling
|
||||
* {@link #getSymbol(Locale)
|
||||
* getSymbol(Locale.getDefault(Locale.Category.DISPLAY))}.
|
||||
*
|
||||
* @return the symbol of this currency for the default
|
||||
* {@link Locale.Category#DISPLAY DISPLAY} locale
|
||||
*/
|
||||
public String getSymbol() {
|
||||
return getSymbol(Locale.getDefault(Locale.Category.DISPLAY));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the symbol of this currency for the specified locale.
|
||||
* For example, for the US Dollar, the symbol is "$" if the specified
|
||||
* locale is the US, while for other locales it may be "US$". If no
|
||||
* symbol can be determined, the ISO 4217 currency code is returned.
|
||||
*
|
||||
* @param locale the locale for which a display name for this currency is
|
||||
* needed
|
||||
* @return the symbol of this currency for the specified locale
|
||||
* @exception NullPointerException if <code>locale</code> is null
|
||||
*/
|
||||
public String getSymbol(Locale locale) {
|
||||
LocaleServiceProviderPool pool =
|
||||
LocaleServiceProviderPool.getPool(CurrencyNameProvider.class);
|
||||
String symbol = pool.getLocalizedObject(
|
||||
CurrencyNameGetter.INSTANCE,
|
||||
locale, currencyCode, SYMBOL);
|
||||
if (symbol != null) {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
// use currency code as symbol of last resort
|
||||
return currencyCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default number of fraction digits used with this currency.
|
||||
* For example, the default number of fraction digits for the Euro is 2,
|
||||
* while for the Japanese Yen it's 0.
|
||||
* In the case of pseudo-currencies, such as IMF Special Drawing Rights,
|
||||
* -1 is returned.
|
||||
*
|
||||
* @return the default number of fraction digits used with this currency
|
||||
*/
|
||||
public int getDefaultFractionDigits() {
|
||||
return defaultFractionDigits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ISO 4217 numeric code of this currency.
|
||||
*
|
||||
* @return the ISO 4217 numeric code of this currency
|
||||
* @since 1.7
|
||||
*/
|
||||
public int getNumericCode() {
|
||||
return numericCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name that is suitable for displaying this currency for
|
||||
* the default {@link Locale.Category#DISPLAY DISPLAY} locale.
|
||||
* If there is no suitable display name found
|
||||
* for the default locale, the ISO 4217 currency code is returned.
|
||||
* <p>
|
||||
* This is equivalent to calling
|
||||
* {@link #getDisplayName(Locale)
|
||||
* getDisplayName(Locale.getDefault(Locale.Category.DISPLAY))}.
|
||||
*
|
||||
* @return the display name of this currency for the default
|
||||
* {@link Locale.Category#DISPLAY DISPLAY} locale
|
||||
* @since 1.7
|
||||
*/
|
||||
public String getDisplayName() {
|
||||
return getDisplayName(Locale.getDefault(Locale.Category.DISPLAY));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name that is suitable for displaying this currency for
|
||||
* the specified locale. If there is no suitable display name found
|
||||
* for the specified locale, the ISO 4217 currency code is returned.
|
||||
*
|
||||
* @param locale the locale for which a display name for this currency is
|
||||
* needed
|
||||
* @return the display name of this currency for the specified locale
|
||||
* @exception NullPointerException if <code>locale</code> is null
|
||||
* @since 1.7
|
||||
*/
|
||||
public String getDisplayName(Locale locale) {
|
||||
LocaleServiceProviderPool pool =
|
||||
LocaleServiceProviderPool.getPool(CurrencyNameProvider.class);
|
||||
String result = pool.getLocalizedObject(
|
||||
CurrencyNameGetter.INSTANCE,
|
||||
locale, currencyCode, DISPLAYNAME);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// use currency code as symbol of last resort
|
||||
return currencyCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ISO 4217 currency code of this currency.
|
||||
*
|
||||
* @return the ISO 4217 currency code of this currency
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return currencyCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves instances being deserialized to a single instance per currency.
|
||||
*/
|
||||
private Object readResolve() {
|
||||
return getInstance(currencyCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the main table entry for the country whose country code consists
|
||||
* of char1 and char2.
|
||||
*/
|
||||
private static int getMainTableEntry(char char1, char char2) {
|
||||
if (char1 < 'A' || char1 > 'Z' || char2 < 'A' || char2 > 'Z') {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return mainTable[(char1 - 'A') * A_TO_Z + (char2 - 'A')];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the main table entry for the country whose country code consists
|
||||
* of char1 and char2.
|
||||
*/
|
||||
private static void setMainTableEntry(char char1, char char2, int entry) {
|
||||
if (char1 < 'A' || char1 > 'Z' || char2 < 'A' || char2 > 'Z') {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
mainTable[(char1 - 'A') * A_TO_Z + (char2 - 'A')] = entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains a localized currency names from a CurrencyNameProvider
|
||||
* implementation.
|
||||
*/
|
||||
private static class CurrencyNameGetter
|
||||
implements LocaleServiceProviderPool.LocalizedObjectGetter<CurrencyNameProvider,
|
||||
String> {
|
||||
private static final CurrencyNameGetter INSTANCE = new CurrencyNameGetter();
|
||||
|
||||
@Override
|
||||
public String getObject(CurrencyNameProvider currencyNameProvider,
|
||||
Locale locale,
|
||||
String key,
|
||||
Object... params) {
|
||||
assert params.length == 1;
|
||||
int type = (Integer)params[0];
|
||||
|
||||
switch(type) {
|
||||
case SYMBOL:
|
||||
return currencyNameProvider.getSymbol(key, locale);
|
||||
case DISPLAYNAME:
|
||||
return currencyNameProvider.getDisplayName(key, locale);
|
||||
default:
|
||||
assert false; // shouldn't happen
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static int[] readIntArray(DataInputStream dis, int count) throws IOException {
|
||||
int[] ret = new int[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
ret[i] = dis.readInt();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static long[] readLongArray(DataInputStream dis, int count) throws IOException {
|
||||
long[] ret = new long[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
ret[i] = dis.readLong();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static String[] readStringArray(DataInputStream dis, int count) throws IOException {
|
||||
String[] ret = new String[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
ret[i] = dis.readUTF();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces currency data found in the currencydata.properties file
|
||||
*
|
||||
* @param pattern regex pattern for the properties
|
||||
* @param ctry country code
|
||||
* @param curdata currency data. This is a comma separated string that
|
||||
* consists of "three-letter alphabet code", "three-digit numeric code",
|
||||
* and "one-digit (0-9) default fraction digit".
|
||||
* For example, "JPZ,392,0".
|
||||
* An optional UTC date can be appended to the string (comma separated)
|
||||
* to allow a currency change take effect after date specified.
|
||||
* For example, "JP=JPZ,999,0,2014-01-01T00:00:00" has no effect unless
|
||||
* UTC time is past 1st January 2014 00:00:00 GMT.
|
||||
*/
|
||||
private static void replaceCurrencyData(Pattern pattern, String ctry, String curdata) {
|
||||
|
||||
if (ctry.length() != 2) {
|
||||
// ignore invalid country code
|
||||
info("currency.properties entry for " + ctry +
|
||||
" is ignored because of the invalid country code.", null);
|
||||
return;
|
||||
}
|
||||
|
||||
Matcher m = pattern.matcher(curdata);
|
||||
if (!m.find() || (m.group(4) == null && countOccurrences(curdata, ',') >= 3)) {
|
||||
// format is not recognized. ignore the data
|
||||
// if group(4) date string is null and we've 4 values, bad date value
|
||||
info("currency.properties entry for " + ctry +
|
||||
" ignored because the value format is not recognized.", null);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (m.group(4) != null && !isPastCutoverDate(m.group(4))) {
|
||||
info("currency.properties entry for " + ctry +
|
||||
" ignored since cutover date has not passed :" + curdata, null);
|
||||
return;
|
||||
}
|
||||
} catch (ParseException ex) {
|
||||
info("currency.properties entry for " + ctry +
|
||||
" ignored since exception encountered :" + ex.getMessage(), null);
|
||||
return;
|
||||
}
|
||||
|
||||
String code = m.group(1);
|
||||
int numeric = Integer.parseInt(m.group(2));
|
||||
int entry = numeric << NUMERIC_CODE_SHIFT;
|
||||
int fraction = Integer.parseInt(m.group(3));
|
||||
if (fraction > SIMPLE_CASE_COUNTRY_MAX_DEFAULT_DIGITS) {
|
||||
info("currency.properties entry for " + ctry +
|
||||
" ignored since the fraction is more than " +
|
||||
SIMPLE_CASE_COUNTRY_MAX_DEFAULT_DIGITS + ":" + curdata, null);
|
||||
return;
|
||||
}
|
||||
|
||||
int index;
|
||||
for (index = 0; index < scOldCurrencies.length; index++) {
|
||||
if (scOldCurrencies[index].equals(code)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index == scOldCurrencies.length) {
|
||||
// simple case
|
||||
entry |= (fraction << SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT) |
|
||||
(code.charAt(2) - 'A');
|
||||
} else {
|
||||
// special case
|
||||
entry |= SPECIAL_CASE_COUNTRY_MASK |
|
||||
(index + SPECIAL_CASE_COUNTRY_INDEX_DELTA);
|
||||
}
|
||||
setMainTableEntry(ctry.charAt(0), ctry.charAt(1), entry);
|
||||
}
|
||||
|
||||
private static boolean isPastCutoverDate(String s) throws ParseException {
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ROOT);
|
||||
format.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
format.setLenient(false);
|
||||
long time = format.parse(s.trim()).getTime();
|
||||
return System.currentTimeMillis() > time;
|
||||
|
||||
}
|
||||
|
||||
private static int countOccurrences(String value, char match) {
|
||||
int count = 0;
|
||||
for (char c : value.toCharArray()) {
|
||||
if (c == match) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
private static void info(String message, Throwable t) {
|
||||
PlatformLogger logger = PlatformLogger.getLogger("java.util.Currency");
|
||||
if (logger.isLoggable(PlatformLogger.Level.INFO)) {
|
||||
if (t != null) {
|
||||
logger.info(message, t);
|
||||
} else {
|
||||
logger.info(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1376
jdkSrc/jdk8/java/util/Date.java
Normal file
1376
jdkSrc/jdk8/java/util/Date.java
Normal file
File diff suppressed because it is too large
Load Diff
584
jdkSrc/jdk8/java/util/Deque.java
Normal file
584
jdkSrc/jdk8/java/util/Deque.java
Normal file
@@ -0,0 +1,584 @@
|
||||
/*
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is available under and governed by the GNU General Public
|
||||
* License version 2 only, as published by the Free Software Foundation.
|
||||
* However, the following notice accompanied the original version of this
|
||||
* file:
|
||||
*
|
||||
* Written by Doug Lea and Josh Bloch with assistance from members of
|
||||
* JCP JSR-166 Expert Group and released to the public domain, as explained
|
||||
* at http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* A linear collection that supports element insertion and removal at
|
||||
* both ends. The name <i>deque</i> is short for "double ended queue"
|
||||
* and is usually pronounced "deck". Most {@code Deque}
|
||||
* implementations place no fixed limits on the number of elements
|
||||
* they may contain, but this interface supports capacity-restricted
|
||||
* deques as well as those with no fixed size limit.
|
||||
*
|
||||
* <p>This interface defines methods to access the elements at both
|
||||
* ends of the deque. Methods are provided to insert, remove, and
|
||||
* examine the element. Each of these methods exists in two forms:
|
||||
* one throws an exception if the operation fails, the other returns a
|
||||
* special value (either {@code null} or {@code false}, depending on
|
||||
* the operation). The latter form of the insert operation is
|
||||
* designed specifically for use with capacity-restricted
|
||||
* {@code Deque} implementations; in most implementations, insert
|
||||
* operations cannot fail.
|
||||
*
|
||||
* <p>The twelve methods described above are summarized in the
|
||||
* following table:
|
||||
*
|
||||
* <table BORDER CELLPADDING=3 CELLSPACING=1>
|
||||
* <caption>Summary of Deque methods</caption>
|
||||
* <tr>
|
||||
* <td></td>
|
||||
* <td ALIGN=CENTER COLSPAN = 2> <b>First Element (Head)</b></td>
|
||||
* <td ALIGN=CENTER COLSPAN = 2> <b>Last Element (Tail)</b></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td></td>
|
||||
* <td ALIGN=CENTER><em>Throws exception</em></td>
|
||||
* <td ALIGN=CENTER><em>Special value</em></td>
|
||||
* <td ALIGN=CENTER><em>Throws exception</em></td>
|
||||
* <td ALIGN=CENTER><em>Special value</em></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Insert</b></td>
|
||||
* <td>{@link Deque#addFirst addFirst(e)}</td>
|
||||
* <td>{@link Deque#offerFirst offerFirst(e)}</td>
|
||||
* <td>{@link Deque#addLast addLast(e)}</td>
|
||||
* <td>{@link Deque#offerLast offerLast(e)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Remove</b></td>
|
||||
* <td>{@link Deque#removeFirst removeFirst()}</td>
|
||||
* <td>{@link Deque#pollFirst pollFirst()}</td>
|
||||
* <td>{@link Deque#removeLast removeLast()}</td>
|
||||
* <td>{@link Deque#pollLast pollLast()}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Examine</b></td>
|
||||
* <td>{@link Deque#getFirst getFirst()}</td>
|
||||
* <td>{@link Deque#peekFirst peekFirst()}</td>
|
||||
* <td>{@link Deque#getLast getLast()}</td>
|
||||
* <td>{@link Deque#peekLast peekLast()}</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* <p>This interface extends the {@link Queue} interface. When a deque is
|
||||
* used as a queue, FIFO (First-In-First-Out) behavior results. Elements are
|
||||
* added at the end of the deque and removed from the beginning. The methods
|
||||
* inherited from the {@code Queue} interface are precisely equivalent to
|
||||
* {@code Deque} methods as indicated in the following table:
|
||||
*
|
||||
* <table BORDER CELLPADDING=3 CELLSPACING=1>
|
||||
* <caption>Comparison of Queue and Deque methods</caption>
|
||||
* <tr>
|
||||
* <td ALIGN=CENTER> <b>{@code Queue} Method</b></td>
|
||||
* <td ALIGN=CENTER> <b>Equivalent {@code Deque} Method</b></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link java.util.Queue#add add(e)}</td>
|
||||
* <td>{@link #addLast addLast(e)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link java.util.Queue#offer offer(e)}</td>
|
||||
* <td>{@link #offerLast offerLast(e)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link java.util.Queue#remove remove()}</td>
|
||||
* <td>{@link #removeFirst removeFirst()}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link java.util.Queue#poll poll()}</td>
|
||||
* <td>{@link #pollFirst pollFirst()}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link java.util.Queue#element element()}</td>
|
||||
* <td>{@link #getFirst getFirst()}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link java.util.Queue#peek peek()}</td>
|
||||
* <td>{@link #peek peekFirst()}</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* <p>Deques can also be used as LIFO (Last-In-First-Out) stacks. This
|
||||
* interface should be used in preference to the legacy {@link Stack} class.
|
||||
* When a deque is used as a stack, elements are pushed and popped from the
|
||||
* beginning of the deque. Stack methods are precisely equivalent to
|
||||
* {@code Deque} methods as indicated in the table below:
|
||||
*
|
||||
* <table BORDER CELLPADDING=3 CELLSPACING=1>
|
||||
* <caption>Comparison of Stack and Deque methods</caption>
|
||||
* <tr>
|
||||
* <td ALIGN=CENTER> <b>Stack Method</b></td>
|
||||
* <td ALIGN=CENTER> <b>Equivalent {@code Deque} Method</b></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link #push push(e)}</td>
|
||||
* <td>{@link #addFirst addFirst(e)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link #pop pop()}</td>
|
||||
* <td>{@link #removeFirst removeFirst()}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link #peek peek()}</td>
|
||||
* <td>{@link #peekFirst peekFirst()}</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* <p>Note that the {@link #peek peek} method works equally well when
|
||||
* a deque is used as a queue or a stack; in either case, elements are
|
||||
* drawn from the beginning of the deque.
|
||||
*
|
||||
* <p>This interface provides two methods to remove interior
|
||||
* elements, {@link #removeFirstOccurrence removeFirstOccurrence} and
|
||||
* {@link #removeLastOccurrence removeLastOccurrence}.
|
||||
*
|
||||
* <p>Unlike the {@link List} interface, this interface does not
|
||||
* provide support for indexed access to elements.
|
||||
*
|
||||
* <p>While {@code Deque} implementations are not strictly required
|
||||
* to prohibit the insertion of null elements, they are strongly
|
||||
* encouraged to do so. Users of any {@code Deque} implementations
|
||||
* that do allow null elements are strongly encouraged <i>not</i> to
|
||||
* take advantage of the ability to insert nulls. This is so because
|
||||
* {@code null} is used as a special return value by various methods
|
||||
* to indicated that the deque is empty.
|
||||
*
|
||||
* <p>{@code Deque} implementations generally do not define
|
||||
* element-based versions of the {@code equals} and {@code hashCode}
|
||||
* methods, but instead inherit the identity-based versions from class
|
||||
* {@code Object}.
|
||||
*
|
||||
* <p>This interface is a member of the <a
|
||||
* href="{@docRoot}/../technotes/guides/collections/index.html"> Java Collections
|
||||
* Framework</a>.
|
||||
*
|
||||
* @author Doug Lea
|
||||
* @author Josh Bloch
|
||||
* @since 1.6
|
||||
* @param <E> the type of elements held in this collection
|
||||
*/
|
||||
public interface Deque<E> extends Queue<E> {
|
||||
/**
|
||||
* Inserts the specified element at the front of this deque if it is
|
||||
* possible to do so immediately without violating capacity restrictions,
|
||||
* throwing an {@code IllegalStateException} if no space is currently
|
||||
* available. When using a capacity-restricted deque, it is generally
|
||||
* preferable to use method {@link #offerFirst}.
|
||||
*
|
||||
* @param e the element to add
|
||||
* @throws IllegalStateException if the element cannot be added at this
|
||||
* time due to capacity restrictions
|
||||
* @throws ClassCastException if the class of the specified element
|
||||
* prevents it from being added to this deque
|
||||
* @throws NullPointerException if the specified element is null and this
|
||||
* deque does not permit null elements
|
||||
* @throws IllegalArgumentException if some property of the specified
|
||||
* element prevents it from being added to this deque
|
||||
*/
|
||||
void addFirst(E e);
|
||||
|
||||
/**
|
||||
* Inserts the specified element at the end of this deque if it is
|
||||
* possible to do so immediately without violating capacity restrictions,
|
||||
* throwing an {@code IllegalStateException} if no space is currently
|
||||
* available. When using a capacity-restricted deque, it is generally
|
||||
* preferable to use method {@link #offerLast}.
|
||||
*
|
||||
* <p>This method is equivalent to {@link #add}.
|
||||
*
|
||||
* @param e the element to add
|
||||
* @throws IllegalStateException if the element cannot be added at this
|
||||
* time due to capacity restrictions
|
||||
* @throws ClassCastException if the class of the specified element
|
||||
* prevents it from being added to this deque
|
||||
* @throws NullPointerException if the specified element is null and this
|
||||
* deque does not permit null elements
|
||||
* @throws IllegalArgumentException if some property of the specified
|
||||
* element prevents it from being added to this deque
|
||||
*/
|
||||
void addLast(E e);
|
||||
|
||||
/**
|
||||
* Inserts the specified element at the front of this deque unless it would
|
||||
* violate capacity restrictions. When using a capacity-restricted deque,
|
||||
* this method is generally preferable to the {@link #addFirst} method,
|
||||
* which can fail to insert an element only by throwing an exception.
|
||||
*
|
||||
* @param e the element to add
|
||||
* @return {@code true} if the element was added to this deque, else
|
||||
* {@code false}
|
||||
* @throws ClassCastException if the class of the specified element
|
||||
* prevents it from being added to this deque
|
||||
* @throws NullPointerException if the specified element is null and this
|
||||
* deque does not permit null elements
|
||||
* @throws IllegalArgumentException if some property of the specified
|
||||
* element prevents it from being added to this deque
|
||||
*/
|
||||
boolean offerFirst(E e);
|
||||
|
||||
/**
|
||||
* Inserts the specified element at the end of this deque unless it would
|
||||
* violate capacity restrictions. When using a capacity-restricted deque,
|
||||
* this method is generally preferable to the {@link #addLast} method,
|
||||
* which can fail to insert an element only by throwing an exception.
|
||||
*
|
||||
* @param e the element to add
|
||||
* @return {@code true} if the element was added to this deque, else
|
||||
* {@code false}
|
||||
* @throws ClassCastException if the class of the specified element
|
||||
* prevents it from being added to this deque
|
||||
* @throws NullPointerException if the specified element is null and this
|
||||
* deque does not permit null elements
|
||||
* @throws IllegalArgumentException if some property of the specified
|
||||
* element prevents it from being added to this deque
|
||||
*/
|
||||
boolean offerLast(E e);
|
||||
|
||||
/**
|
||||
* Retrieves and removes the first element of this deque. This method
|
||||
* differs from {@link #pollFirst pollFirst} only in that it throws an
|
||||
* exception if this deque is empty.
|
||||
*
|
||||
* @return the head of this deque
|
||||
* @throws NoSuchElementException if this deque is empty
|
||||
*/
|
||||
E removeFirst();
|
||||
|
||||
/**
|
||||
* Retrieves and removes the last element of this deque. This method
|
||||
* differs from {@link #pollLast pollLast} only in that it throws an
|
||||
* exception if this deque is empty.
|
||||
*
|
||||
* @return the tail of this deque
|
||||
* @throws NoSuchElementException if this deque is empty
|
||||
*/
|
||||
E removeLast();
|
||||
|
||||
/**
|
||||
* Retrieves and removes the first element of this deque,
|
||||
* or returns {@code null} if this deque is empty.
|
||||
*
|
||||
* @return the head of this deque, or {@code null} if this deque is empty
|
||||
*/
|
||||
E pollFirst();
|
||||
|
||||
/**
|
||||
* Retrieves and removes the last element of this deque,
|
||||
* or returns {@code null} if this deque is empty.
|
||||
*
|
||||
* @return the tail of this deque, or {@code null} if this deque is empty
|
||||
*/
|
||||
E pollLast();
|
||||
|
||||
/**
|
||||
* Retrieves, but does not remove, the first element of this deque.
|
||||
*
|
||||
* This method differs from {@link #peekFirst peekFirst} only in that it
|
||||
* throws an exception if this deque is empty.
|
||||
*
|
||||
* @return the head of this deque
|
||||
* @throws NoSuchElementException if this deque is empty
|
||||
*/
|
||||
E getFirst();
|
||||
|
||||
/**
|
||||
* Retrieves, but does not remove, the last element of this deque.
|
||||
* This method differs from {@link #peekLast peekLast} only in that it
|
||||
* throws an exception if this deque is empty.
|
||||
*
|
||||
* @return the tail of this deque
|
||||
* @throws NoSuchElementException if this deque is empty
|
||||
*/
|
||||
E getLast();
|
||||
|
||||
/**
|
||||
* Retrieves, but does not remove, the first element of this deque,
|
||||
* or returns {@code null} if this deque is empty.
|
||||
*
|
||||
* @return the head of this deque, or {@code null} if this deque is empty
|
||||
*/
|
||||
E peekFirst();
|
||||
|
||||
/**
|
||||
* Retrieves, but does not remove, the last element of this deque,
|
||||
* or returns {@code null} if this deque is empty.
|
||||
*
|
||||
* @return the tail of this deque, or {@code null} if this deque is empty
|
||||
*/
|
||||
E peekLast();
|
||||
|
||||
/**
|
||||
* Removes the first occurrence of the specified element from this deque.
|
||||
* If the deque does not contain the element, it is unchanged.
|
||||
* More formally, removes the first element {@code e} such that
|
||||
* <tt>(o==null ? e==null : o.equals(e))</tt>
|
||||
* (if such an element exists).
|
||||
* Returns {@code true} if this deque contained the specified element
|
||||
* (or equivalently, if this deque changed as a result of the call).
|
||||
*
|
||||
* @param o element to be removed from this deque, if present
|
||||
* @return {@code true} if an element was removed as a result of this call
|
||||
* @throws ClassCastException if the class of the specified element
|
||||
* is incompatible with this deque
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if the specified element is null and this
|
||||
* deque does not permit null elements
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
*/
|
||||
boolean removeFirstOccurrence(Object o);
|
||||
|
||||
/**
|
||||
* Removes the last occurrence of the specified element from this deque.
|
||||
* If the deque does not contain the element, it is unchanged.
|
||||
* More formally, removes the last element {@code e} such that
|
||||
* <tt>(o==null ? e==null : o.equals(e))</tt>
|
||||
* (if such an element exists).
|
||||
* Returns {@code true} if this deque contained the specified element
|
||||
* (or equivalently, if this deque changed as a result of the call).
|
||||
*
|
||||
* @param o element to be removed from this deque, if present
|
||||
* @return {@code true} if an element was removed as a result of this call
|
||||
* @throws ClassCastException if the class of the specified element
|
||||
* is incompatible with this deque
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if the specified element is null and this
|
||||
* deque does not permit null elements
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
*/
|
||||
boolean removeLastOccurrence(Object o);
|
||||
|
||||
// *** Queue methods ***
|
||||
|
||||
/**
|
||||
* Inserts the specified element into the queue represented by this deque
|
||||
* (in other words, at the tail of this deque) if it is possible to do so
|
||||
* immediately without violating capacity restrictions, returning
|
||||
* {@code true} upon success and throwing an
|
||||
* {@code IllegalStateException} if no space is currently available.
|
||||
* When using a capacity-restricted deque, it is generally preferable to
|
||||
* use {@link #offer(Object) offer}.
|
||||
*
|
||||
* <p>This method is equivalent to {@link #addLast}.
|
||||
*
|
||||
* @param e the element to add
|
||||
* @return {@code true} (as specified by {@link Collection#add})
|
||||
* @throws IllegalStateException if the element cannot be added at this
|
||||
* time due to capacity restrictions
|
||||
* @throws ClassCastException if the class of the specified element
|
||||
* prevents it from being added to this deque
|
||||
* @throws NullPointerException if the specified element is null and this
|
||||
* deque does not permit null elements
|
||||
* @throws IllegalArgumentException if some property of the specified
|
||||
* element prevents it from being added to this deque
|
||||
*/
|
||||
boolean add(E e);
|
||||
|
||||
/**
|
||||
* Inserts the specified element into the queue represented by this deque
|
||||
* (in other words, at the tail of this deque) if it is possible to do so
|
||||
* immediately without violating capacity restrictions, returning
|
||||
* {@code true} upon success and {@code false} if no space is currently
|
||||
* available. When using a capacity-restricted deque, this method is
|
||||
* generally preferable to the {@link #add} method, which can fail to
|
||||
* insert an element only by throwing an exception.
|
||||
*
|
||||
* <p>This method is equivalent to {@link #offerLast}.
|
||||
*
|
||||
* @param e the element to add
|
||||
* @return {@code true} if the element was added to this deque, else
|
||||
* {@code false}
|
||||
* @throws ClassCastException if the class of the specified element
|
||||
* prevents it from being added to this deque
|
||||
* @throws NullPointerException if the specified element is null and this
|
||||
* deque does not permit null elements
|
||||
* @throws IllegalArgumentException if some property of the specified
|
||||
* element prevents it from being added to this deque
|
||||
*/
|
||||
boolean offer(E e);
|
||||
|
||||
/**
|
||||
* Retrieves and removes the head of the queue represented by this deque
|
||||
* (in other words, the first element of this deque).
|
||||
* This method differs from {@link #poll poll} only in that it throws an
|
||||
* exception if this deque is empty.
|
||||
*
|
||||
* <p>This method is equivalent to {@link #removeFirst()}.
|
||||
*
|
||||
* @return the head of the queue represented by this deque
|
||||
* @throws NoSuchElementException if this deque is empty
|
||||
*/
|
||||
E remove();
|
||||
|
||||
/**
|
||||
* Retrieves and removes the head of the queue represented by this deque
|
||||
* (in other words, the first element of this deque), or returns
|
||||
* {@code null} if this deque is empty.
|
||||
*
|
||||
* <p>This method is equivalent to {@link #pollFirst()}.
|
||||
*
|
||||
* @return the first element of this deque, or {@code null} if
|
||||
* this deque is empty
|
||||
*/
|
||||
E poll();
|
||||
|
||||
/**
|
||||
* Retrieves, but does not remove, the head of the queue represented by
|
||||
* this deque (in other words, the first element of this deque).
|
||||
* This method differs from {@link #peek peek} only in that it throws an
|
||||
* exception if this deque is empty.
|
||||
*
|
||||
* <p>This method is equivalent to {@link #getFirst()}.
|
||||
*
|
||||
* @return the head of the queue represented by this deque
|
||||
* @throws NoSuchElementException if this deque is empty
|
||||
*/
|
||||
E element();
|
||||
|
||||
/**
|
||||
* Retrieves, but does not remove, the head of the queue represented by
|
||||
* this deque (in other words, the first element of this deque), or
|
||||
* returns {@code null} if this deque is empty.
|
||||
*
|
||||
* <p>This method is equivalent to {@link #peekFirst()}.
|
||||
*
|
||||
* @return the head of the queue represented by this deque, or
|
||||
* {@code null} if this deque is empty
|
||||
*/
|
||||
E peek();
|
||||
|
||||
|
||||
// *** Stack methods ***
|
||||
|
||||
/**
|
||||
* Pushes an element onto the stack represented by this deque (in other
|
||||
* words, at the head of this deque) if it is possible to do so
|
||||
* immediately without violating capacity restrictions, throwing an
|
||||
* {@code IllegalStateException} if no space is currently available.
|
||||
*
|
||||
* <p>This method is equivalent to {@link #addFirst}.
|
||||
*
|
||||
* @param e the element to push
|
||||
* @throws IllegalStateException if the element cannot be added at this
|
||||
* time due to capacity restrictions
|
||||
* @throws ClassCastException if the class of the specified element
|
||||
* prevents it from being added to this deque
|
||||
* @throws NullPointerException if the specified element is null and this
|
||||
* deque does not permit null elements
|
||||
* @throws IllegalArgumentException if some property of the specified
|
||||
* element prevents it from being added to this deque
|
||||
*/
|
||||
void push(E e);
|
||||
|
||||
/**
|
||||
* Pops an element from the stack represented by this deque. In other
|
||||
* words, removes and returns the first element of this deque.
|
||||
*
|
||||
* <p>This method is equivalent to {@link #removeFirst()}.
|
||||
*
|
||||
* @return the element at the front of this deque (which is the top
|
||||
* of the stack represented by this deque)
|
||||
* @throws NoSuchElementException if this deque is empty
|
||||
*/
|
||||
E pop();
|
||||
|
||||
|
||||
// *** Collection methods ***
|
||||
|
||||
/**
|
||||
* Removes the first occurrence of the specified element from this deque.
|
||||
* If the deque does not contain the element, it is unchanged.
|
||||
* More formally, removes the first element {@code e} such that
|
||||
* <tt>(o==null ? e==null : o.equals(e))</tt>
|
||||
* (if such an element exists).
|
||||
* Returns {@code true} if this deque contained the specified element
|
||||
* (or equivalently, if this deque changed as a result of the call).
|
||||
*
|
||||
* <p>This method is equivalent to {@link #removeFirstOccurrence(Object)}.
|
||||
*
|
||||
* @param o element to be removed from this deque, if present
|
||||
* @return {@code true} if an element was removed as a result of this call
|
||||
* @throws ClassCastException if the class of the specified element
|
||||
* is incompatible with this deque
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if the specified element is null and this
|
||||
* deque does not permit null elements
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
*/
|
||||
boolean remove(Object o);
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this deque contains the specified element.
|
||||
* More formally, returns {@code true} if and only if this deque contains
|
||||
* at least one element {@code e} such that
|
||||
* <tt>(o==null ? e==null : o.equals(e))</tt>.
|
||||
*
|
||||
* @param o element whose presence in this deque is to be tested
|
||||
* @return {@code true} if this deque contains the specified element
|
||||
* @throws ClassCastException if the type of the specified element
|
||||
* is incompatible with this deque
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if the specified element is null and this
|
||||
* deque does not permit null elements
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
*/
|
||||
boolean contains(Object o);
|
||||
|
||||
/**
|
||||
* Returns the number of elements in this deque.
|
||||
*
|
||||
* @return the number of elements in this deque
|
||||
*/
|
||||
public int size();
|
||||
|
||||
/**
|
||||
* Returns an iterator over the elements in this deque in proper sequence.
|
||||
* The elements will be returned in order from first (head) to last (tail).
|
||||
*
|
||||
* @return an iterator over the elements in this deque in proper sequence
|
||||
*/
|
||||
Iterator<E> iterator();
|
||||
|
||||
/**
|
||||
* Returns an iterator over the elements in this deque in reverse
|
||||
* sequential order. The elements will be returned in order from
|
||||
* last (tail) to first (head).
|
||||
*
|
||||
* @return an iterator over the elements in this deque in reverse
|
||||
* sequence
|
||||
*/
|
||||
Iterator<E> descendingIterator();
|
||||
|
||||
}
|
||||
155
jdkSrc/jdk8/java/util/Dictionary.java
Normal file
155
jdkSrc/jdk8/java/util/Dictionary.java
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* The <code>Dictionary</code> class is the abstract parent of any
|
||||
* class, such as <code>Hashtable</code>, which maps keys to values.
|
||||
* Every key and every value is an object. In any one <tt>Dictionary</tt>
|
||||
* object, every key is associated with at most one value. Given a
|
||||
* <tt>Dictionary</tt> and a key, the associated element can be looked up.
|
||||
* Any non-<code>null</code> object can be used as a key and as a value.
|
||||
* <p>
|
||||
* As a rule, the <code>equals</code> method should be used by
|
||||
* implementations of this class to decide if two keys are the same.
|
||||
* <p>
|
||||
* <strong>NOTE: This class is obsolete. New implementations should
|
||||
* implement the Map interface, rather than extending this class.</strong>
|
||||
*
|
||||
* @author unascribed
|
||||
* @see java.util.Map
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
* @see java.lang.Object#hashCode()
|
||||
* @see java.util.Hashtable
|
||||
* @since JDK1.0
|
||||
*/
|
||||
public abstract
|
||||
class Dictionary<K,V> {
|
||||
/**
|
||||
* Sole constructor. (For invocation by subclass constructors, typically
|
||||
* implicit.)
|
||||
*/
|
||||
public Dictionary() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of entries (distinct keys) in this dictionary.
|
||||
*
|
||||
* @return the number of keys in this dictionary.
|
||||
*/
|
||||
abstract public int size();
|
||||
|
||||
/**
|
||||
* Tests if this dictionary maps no keys to value. The general contract
|
||||
* for the <tt>isEmpty</tt> method is that the result is true if and only
|
||||
* if this dictionary contains no entries.
|
||||
*
|
||||
* @return <code>true</code> if this dictionary maps no keys to values;
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
abstract public boolean isEmpty();
|
||||
|
||||
/**
|
||||
* Returns an enumeration of the keys in this dictionary. The general
|
||||
* contract for the keys method is that an <tt>Enumeration</tt> object
|
||||
* is returned that will generate all the keys for which this dictionary
|
||||
* contains entries.
|
||||
*
|
||||
* @return an enumeration of the keys in this dictionary.
|
||||
* @see java.util.Dictionary#elements()
|
||||
* @see java.util.Enumeration
|
||||
*/
|
||||
abstract public Enumeration<K> keys();
|
||||
|
||||
/**
|
||||
* Returns an enumeration of the values in this dictionary. The general
|
||||
* contract for the <tt>elements</tt> method is that an
|
||||
* <tt>Enumeration</tt> is returned that will generate all the elements
|
||||
* contained in entries in this dictionary.
|
||||
*
|
||||
* @return an enumeration of the values in this dictionary.
|
||||
* @see java.util.Dictionary#keys()
|
||||
* @see java.util.Enumeration
|
||||
*/
|
||||
abstract public Enumeration<V> elements();
|
||||
|
||||
/**
|
||||
* Returns the value to which the key is mapped in this dictionary.
|
||||
* The general contract for the <tt>isEmpty</tt> method is that if this
|
||||
* dictionary contains an entry for the specified key, the associated
|
||||
* value is returned; otherwise, <tt>null</tt> is returned.
|
||||
*
|
||||
* @return the value to which the key is mapped in this dictionary;
|
||||
* @param key a key in this dictionary.
|
||||
* <code>null</code> if the key is not mapped to any value in
|
||||
* this dictionary.
|
||||
* @exception NullPointerException if the <tt>key</tt> is <tt>null</tt>.
|
||||
* @see java.util.Dictionary#put(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
abstract public V get(Object key);
|
||||
|
||||
/**
|
||||
* Maps the specified <code>key</code> to the specified
|
||||
* <code>value</code> in this dictionary. Neither the key nor the
|
||||
* value can be <code>null</code>.
|
||||
* <p>
|
||||
* If this dictionary already contains an entry for the specified
|
||||
* <tt>key</tt>, the value already in this dictionary for that
|
||||
* <tt>key</tt> is returned, after modifying the entry to contain the
|
||||
* new element. <p>If this dictionary does not already have an entry
|
||||
* for the specified <tt>key</tt>, an entry is created for the
|
||||
* specified <tt>key</tt> and <tt>value</tt>, and <tt>null</tt> is
|
||||
* returned.
|
||||
* <p>
|
||||
* The <code>value</code> can be retrieved by calling the
|
||||
* <code>get</code> method with a <code>key</code> that is equal to
|
||||
* the original <code>key</code>.
|
||||
*
|
||||
* @param key the hashtable key.
|
||||
* @param value the value.
|
||||
* @return the previous value to which the <code>key</code> was mapped
|
||||
* in this dictionary, or <code>null</code> if the key did not
|
||||
* have a previous mapping.
|
||||
* @exception NullPointerException if the <code>key</code> or
|
||||
* <code>value</code> is <code>null</code>.
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
* @see java.util.Dictionary#get(java.lang.Object)
|
||||
*/
|
||||
abstract public V put(K key, V value);
|
||||
|
||||
/**
|
||||
* Removes the <code>key</code> (and its corresponding
|
||||
* <code>value</code>) from this dictionary. This method does nothing
|
||||
* if the <code>key</code> is not in this dictionary.
|
||||
*
|
||||
* @param key the key that needs to be removed.
|
||||
* @return the value to which the <code>key</code> had been mapped in this
|
||||
* dictionary, or <code>null</code> if the key did not have a
|
||||
* mapping.
|
||||
* @exception NullPointerException if <tt>key</tt> is <tt>null</tt>.
|
||||
*/
|
||||
abstract public V remove(Object key);
|
||||
}
|
||||
233
jdkSrc/jdk8/java/util/DoubleSummaryStatistics.java
Normal file
233
jdkSrc/jdk8/java/util/DoubleSummaryStatistics.java
Normal file
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.util;
|
||||
|
||||
import java.util.function.DoubleConsumer;
|
||||
import java.util.stream.Collector;
|
||||
|
||||
/**
|
||||
* A state object for collecting statistics such as count, min, max, sum, and
|
||||
* average.
|
||||
*
|
||||
* <p>This class is designed to work with (though does not require)
|
||||
* {@linkplain java.util.stream streams}. For example, you can compute
|
||||
* summary statistics on a stream of doubles with:
|
||||
* <pre> {@code
|
||||
* DoubleSummaryStatistics stats = doubleStream.collect(DoubleSummaryStatistics::new,
|
||||
* DoubleSummaryStatistics::accept,
|
||||
* DoubleSummaryStatistics::combine);
|
||||
* }</pre>
|
||||
*
|
||||
* <p>{@code DoubleSummaryStatistics} can be used as a
|
||||
* {@linkplain java.util.stream.Stream#collect(Collector) reduction}
|
||||
* target for a {@linkplain java.util.stream.Stream stream}. For example:
|
||||
*
|
||||
* <pre> {@code
|
||||
* DoubleSummaryStatistics stats = people.stream()
|
||||
* .collect(Collectors.summarizingDouble(Person::getWeight));
|
||||
*}</pre>
|
||||
*
|
||||
* This computes, in a single pass, the count of people, as well as the minimum,
|
||||
* maximum, sum, and average of their weights.
|
||||
*
|
||||
* @implNote This implementation is not thread safe. However, it is safe to use
|
||||
* {@link java.util.stream.Collectors#summarizingDouble(java.util.function.ToDoubleFunction)
|
||||
* Collectors.toDoubleStatistics()} on a parallel stream, because the parallel
|
||||
* implementation of {@link java.util.stream.Stream#collect Stream.collect()}
|
||||
* provides the necessary partitioning, isolation, and merging of results for
|
||||
* safe and efficient parallel execution.
|
||||
* @since 1.8
|
||||
*/
|
||||
public class DoubleSummaryStatistics implements DoubleConsumer {
|
||||
private long count;
|
||||
private double sum;
|
||||
private double sumCompensation; // Low order bits of sum
|
||||
private double simpleSum; // Used to compute right sum for non-finite inputs
|
||||
private double min = Double.POSITIVE_INFINITY;
|
||||
private double max = Double.NEGATIVE_INFINITY;
|
||||
|
||||
/**
|
||||
* Construct an empty instance with zero count, zero sum,
|
||||
* {@code Double.POSITIVE_INFINITY} min, {@code Double.NEGATIVE_INFINITY}
|
||||
* max and zero average.
|
||||
*/
|
||||
public DoubleSummaryStatistics() { }
|
||||
|
||||
/**
|
||||
* Records another value into the summary information.
|
||||
*
|
||||
* @param value the input value
|
||||
*/
|
||||
@Override
|
||||
public void accept(double value) {
|
||||
++count;
|
||||
simpleSum += value;
|
||||
sumWithCompensation(value);
|
||||
min = Math.min(min, value);
|
||||
max = Math.max(max, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines the state of another {@code DoubleSummaryStatistics} into this
|
||||
* one.
|
||||
*
|
||||
* @param other another {@code DoubleSummaryStatistics}
|
||||
* @throws NullPointerException if {@code other} is null
|
||||
*/
|
||||
public void combine(DoubleSummaryStatistics other) {
|
||||
count += other.count;
|
||||
simpleSum += other.simpleSum;
|
||||
sumWithCompensation(other.sum);
|
||||
sumWithCompensation(other.sumCompensation);
|
||||
min = Math.min(min, other.min);
|
||||
max = Math.max(max, other.max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Incorporate a new double value using Kahan summation /
|
||||
* compensated summation.
|
||||
*/
|
||||
private void sumWithCompensation(double value) {
|
||||
double tmp = value - sumCompensation;
|
||||
double velvel = sum + tmp; // Little wolf of rounding error
|
||||
sumCompensation = (velvel - sum) - tmp;
|
||||
sum = velvel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the count of values recorded.
|
||||
*
|
||||
* @return the count of values
|
||||
*/
|
||||
public final long getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of values recorded, or zero if no values have been
|
||||
* recorded.
|
||||
*
|
||||
* If any recorded value is a NaN or the sum is at any point a NaN
|
||||
* then the sum will be NaN.
|
||||
*
|
||||
* <p> The value of a floating-point sum is a function both of the
|
||||
* input values as well as the order of addition operations. The
|
||||
* order of addition operations of this method is intentionally
|
||||
* not defined to allow for implementation flexibility to improve
|
||||
* the speed and accuracy of the computed result.
|
||||
*
|
||||
* In particular, this method may be implemented using compensated
|
||||
* summation or other technique to reduce the error bound in the
|
||||
* numerical sum compared to a simple summation of {@code double}
|
||||
* values.
|
||||
*
|
||||
* @apiNote Values sorted by increasing absolute magnitude tend to yield
|
||||
* more accurate results.
|
||||
*
|
||||
* @return the sum of values, or zero if none
|
||||
*/
|
||||
public final double getSum() {
|
||||
// Better error bounds to add both terms as the final sum
|
||||
double tmp = sum + sumCompensation;
|
||||
if (Double.isNaN(tmp) && Double.isInfinite(simpleSum))
|
||||
// If the compensated sum is spuriously NaN from
|
||||
// accumulating one or more same-signed infinite values,
|
||||
// return the correctly-signed infinity stored in
|
||||
// simpleSum.
|
||||
return simpleSum;
|
||||
else
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum recorded value, {@code Double.NaN} if any recorded
|
||||
* value was NaN or {@code Double.POSITIVE_INFINITY} if no values were
|
||||
* recorded. Unlike the numerical comparison operators, this method
|
||||
* considers negative zero to be strictly smaller than positive zero.
|
||||
*
|
||||
* @return the minimum recorded value, {@code Double.NaN} if any recorded
|
||||
* value was NaN or {@code Double.POSITIVE_INFINITY} if no values were
|
||||
* recorded
|
||||
*/
|
||||
public final double getMin() {
|
||||
return min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum recorded value, {@code Double.NaN} if any recorded
|
||||
* value was NaN or {@code Double.NEGATIVE_INFINITY} if no values were
|
||||
* recorded. Unlike the numerical comparison operators, this method
|
||||
* considers negative zero to be strictly smaller than positive zero.
|
||||
*
|
||||
* @return the maximum recorded value, {@code Double.NaN} if any recorded
|
||||
* value was NaN or {@code Double.NEGATIVE_INFINITY} if no values were
|
||||
* recorded
|
||||
*/
|
||||
public final double getMax() {
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the arithmetic mean of values recorded, or zero if no
|
||||
* values have been recorded.
|
||||
*
|
||||
* If any recorded value is a NaN or the sum is at any point a NaN
|
||||
* then the average will be code NaN.
|
||||
*
|
||||
* <p>The average returned can vary depending upon the order in
|
||||
* which values are recorded.
|
||||
*
|
||||
* This method may be implemented using compensated summation or
|
||||
* other technique to reduce the error bound in the {@link #getSum
|
||||
* numerical sum} used to compute the average.
|
||||
*
|
||||
* @apiNote Values sorted by increasing absolute magnitude tend to yield
|
||||
* more accurate results.
|
||||
*
|
||||
* @return the arithmetic mean of values, or zero if none
|
||||
*/
|
||||
public final double getAverage() {
|
||||
return getCount() > 0 ? getSum() / getCount() : 0.0d;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* Returns a non-empty string representation of this object suitable for
|
||||
* debugging. The exact presentation format is unspecified and may vary
|
||||
* between implementations and versions.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format(
|
||||
"%s{count=%d, sum=%f, min=%f, average=%f, max=%f}",
|
||||
this.getClass().getSimpleName(),
|
||||
getCount(),
|
||||
getSum(),
|
||||
getMin(),
|
||||
getAverage(),
|
||||
getMax());
|
||||
}
|
||||
}
|
||||
3078
jdkSrc/jdk8/java/util/DualPivotQuicksort.java
Normal file
3078
jdkSrc/jdk8/java/util/DualPivotQuicksort.java
Normal file
File diff suppressed because it is too large
Load Diff
68
jdkSrc/jdk8/java/util/DuplicateFormatFlagsException.java
Normal file
68
jdkSrc/jdk8/java/util/DuplicateFormatFlagsException.java
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* Unchecked exception thrown when duplicate flags are provided in the format
|
||||
* specifier.
|
||||
*
|
||||
* <p> Unless otherwise specified, passing a <tt>null</tt> argument to any
|
||||
* method or constructor in this class will cause a {@link
|
||||
* NullPointerException} to be thrown.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class DuplicateFormatFlagsException extends IllegalFormatException {
|
||||
|
||||
private static final long serialVersionUID = 18890531L;
|
||||
|
||||
private String flags;
|
||||
|
||||
/**
|
||||
* Constructs an instance of this class with the specified flags.
|
||||
*
|
||||
* @param f
|
||||
* The set of format flags which contain a duplicate flag.
|
||||
*/
|
||||
public DuplicateFormatFlagsException(String f) {
|
||||
if (f == null)
|
||||
throw new NullPointerException();
|
||||
this.flags = f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of flags which contains a duplicate flag.
|
||||
*
|
||||
* @return The flags
|
||||
*/
|
||||
public String getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return String.format("Flags = '%s'", flags);
|
||||
}
|
||||
}
|
||||
46
jdkSrc/jdk8/java/util/EmptyStackException.java
Normal file
46
jdkSrc/jdk8/java/util/EmptyStackException.java
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* Thrown by methods in the <code>Stack</code> class to indicate
|
||||
* that the stack is empty.
|
||||
*
|
||||
* @author Jonathan Payne
|
||||
* @see java.util.Stack
|
||||
* @since JDK1.0
|
||||
*/
|
||||
public
|
||||
class EmptyStackException extends RuntimeException {
|
||||
private static final long serialVersionUID = 5084686378493302095L;
|
||||
|
||||
/**
|
||||
* Constructs a new <code>EmptyStackException</code> with <tt>null</tt>
|
||||
* as its error message string.
|
||||
*/
|
||||
public EmptyStackException() {
|
||||
}
|
||||
}
|
||||
812
jdkSrc/jdk8/java/util/EnumMap.java
Normal file
812
jdkSrc/jdk8/java/util/EnumMap.java
Normal file
@@ -0,0 +1,812 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
import java.util.Map.Entry;
|
||||
import sun.misc.SharedSecrets;
|
||||
|
||||
/**
|
||||
* A specialized {@link Map} implementation for use with enum type keys. All
|
||||
* of the keys in an enum map must come from a single enum type that is
|
||||
* specified, explicitly or implicitly, when the map is created. Enum maps
|
||||
* are represented internally as arrays. This representation is extremely
|
||||
* compact and efficient.
|
||||
*
|
||||
* <p>Enum maps are maintained in the <i>natural order</i> of their keys
|
||||
* (the order in which the enum constants are declared). This is reflected
|
||||
* in the iterators returned by the collections views ({@link #keySet()},
|
||||
* {@link #entrySet()}, and {@link #values()}).
|
||||
*
|
||||
* <p>Iterators returned by the collection views are <i>weakly consistent</i>:
|
||||
* they will never throw {@link ConcurrentModificationException} and they may
|
||||
* or may not show the effects of any modifications to the map that occur while
|
||||
* the iteration is in progress.
|
||||
*
|
||||
* <p>Null keys are not permitted. Attempts to insert a null key will
|
||||
* throw {@link NullPointerException}. Attempts to test for the
|
||||
* presence of a null key or to remove one will, however, function properly.
|
||||
* Null values are permitted.
|
||||
|
||||
* <P>Like most collection implementations <tt>EnumMap</tt> is not
|
||||
* synchronized. If multiple threads access an enum map concurrently, and at
|
||||
* least one of the threads modifies the map, it should be synchronized
|
||||
* externally. This is typically accomplished by synchronizing on some
|
||||
* object that naturally encapsulates the enum map. If no such object exists,
|
||||
* the map should be "wrapped" using the {@link Collections#synchronizedMap}
|
||||
* method. This is best done at creation time, to prevent accidental
|
||||
* unsynchronized access:
|
||||
*
|
||||
* <pre>
|
||||
* Map<EnumKey, V> m
|
||||
* = Collections.synchronizedMap(new EnumMap<EnumKey, V>(...));
|
||||
* </pre>
|
||||
*
|
||||
* <p>Implementation note: All basic operations execute in constant time.
|
||||
* They are likely (though not guaranteed) to be faster than their
|
||||
* {@link HashMap} counterparts.
|
||||
*
|
||||
* <p>This class is a member of the
|
||||
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
|
||||
* Java Collections Framework</a>.
|
||||
*
|
||||
* @author Josh Bloch
|
||||
* @see EnumSet
|
||||
* @since 1.5
|
||||
*/
|
||||
public class EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V>
|
||||
implements java.io.Serializable, Cloneable
|
||||
{
|
||||
/**
|
||||
* The <tt>Class</tt> object for the enum type of all the keys of this map.
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
private final Class<K> keyType;
|
||||
|
||||
/**
|
||||
* All of the values comprising K. (Cached for performance.)
|
||||
*/
|
||||
private transient K[] keyUniverse;
|
||||
|
||||
/**
|
||||
* Array representation of this map. The ith element is the value
|
||||
* to which universe[i] is currently mapped, or null if it isn't
|
||||
* mapped to anything, or NULL if it's mapped to null.
|
||||
*/
|
||||
private transient Object[] vals;
|
||||
|
||||
/**
|
||||
* The number of mappings in this map.
|
||||
*/
|
||||
private transient int size = 0;
|
||||
|
||||
/**
|
||||
* Distinguished non-null value for representing null values.
|
||||
*/
|
||||
private static final Object NULL = new Object() {
|
||||
public int hashCode() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "java.util.EnumMap.NULL";
|
||||
}
|
||||
};
|
||||
|
||||
private Object maskNull(Object value) {
|
||||
return (value == null ? NULL : value);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private V unmaskNull(Object value) {
|
||||
return (V)(value == NULL ? null : value);
|
||||
}
|
||||
|
||||
private static final Enum<?>[] ZERO_LENGTH_ENUM_ARRAY = new Enum<?>[0];
|
||||
|
||||
/**
|
||||
* Creates an empty enum map with the specified key type.
|
||||
*
|
||||
* @param keyType the class object of the key type for this enum map
|
||||
* @throws NullPointerException if <tt>keyType</tt> is null
|
||||
*/
|
||||
public EnumMap(Class<K> keyType) {
|
||||
this.keyType = keyType;
|
||||
keyUniverse = getKeyUniverse(keyType);
|
||||
vals = new Object[keyUniverse.length];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an enum map with the same key type as the specified enum
|
||||
* map, initially containing the same mappings (if any).
|
||||
*
|
||||
* @param m the enum map from which to initialize this enum map
|
||||
* @throws NullPointerException if <tt>m</tt> is null
|
||||
*/
|
||||
public EnumMap(EnumMap<K, ? extends V> m) {
|
||||
keyType = m.keyType;
|
||||
keyUniverse = m.keyUniverse;
|
||||
vals = m.vals.clone();
|
||||
size = m.size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an enum map initialized from the specified map. If the
|
||||
* specified map is an <tt>EnumMap</tt> instance, this constructor behaves
|
||||
* identically to {@link #EnumMap(EnumMap)}. Otherwise, the specified map
|
||||
* must contain at least one mapping (in order to determine the new
|
||||
* enum map's key type).
|
||||
*
|
||||
* @param m the map from which to initialize this enum map
|
||||
* @throws IllegalArgumentException if <tt>m</tt> is not an
|
||||
* <tt>EnumMap</tt> instance and contains no mappings
|
||||
* @throws NullPointerException if <tt>m</tt> is null
|
||||
*/
|
||||
public EnumMap(Map<K, ? extends V> m) {
|
||||
if (m instanceof EnumMap) {
|
||||
EnumMap<K, ? extends V> em = (EnumMap<K, ? extends V>) m;
|
||||
keyType = em.keyType;
|
||||
keyUniverse = em.keyUniverse;
|
||||
vals = em.vals.clone();
|
||||
size = em.size;
|
||||
} else {
|
||||
if (m.isEmpty())
|
||||
throw new IllegalArgumentException("Specified map is empty");
|
||||
keyType = m.keySet().iterator().next().getDeclaringClass();
|
||||
keyUniverse = getKeyUniverse(keyType);
|
||||
vals = new Object[keyUniverse.length];
|
||||
putAll(m);
|
||||
}
|
||||
}
|
||||
|
||||
// Query Operations
|
||||
|
||||
/**
|
||||
* Returns the number of key-value mappings in this map.
|
||||
*
|
||||
* @return the number of key-value mappings in this map
|
||||
*/
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this map maps one or more keys to the
|
||||
* specified value.
|
||||
*
|
||||
* @param value the value whose presence in this map is to be tested
|
||||
* @return <tt>true</tt> if this map maps one or more keys to this value
|
||||
*/
|
||||
public boolean containsValue(Object value) {
|
||||
value = maskNull(value);
|
||||
|
||||
for (Object val : vals)
|
||||
if (value.equals(val))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this map contains a mapping for the specified
|
||||
* key.
|
||||
*
|
||||
* @param key the key whose presence in this map is to be tested
|
||||
* @return <tt>true</tt> if this map contains a mapping for the specified
|
||||
* key
|
||||
*/
|
||||
public boolean containsKey(Object key) {
|
||||
return isValidKey(key) && vals[((Enum<?>)key).ordinal()] != null;
|
||||
}
|
||||
|
||||
private boolean containsMapping(Object key, Object value) {
|
||||
return isValidKey(key) &&
|
||||
maskNull(value).equals(vals[((Enum<?>)key).ordinal()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value to which the specified key is mapped,
|
||||
* or {@code null} if this map contains no mapping for the key.
|
||||
*
|
||||
* <p>More formally, if this map contains a mapping from a key
|
||||
* {@code k} to a value {@code v} such that {@code (key == k)},
|
||||
* then this method returns {@code v}; otherwise it returns
|
||||
* {@code null}. (There can be at most one such mapping.)
|
||||
*
|
||||
* <p>A return value of {@code null} does not <i>necessarily</i>
|
||||
* indicate that the map contains no mapping for the key; it's also
|
||||
* possible that the map explicitly maps the key to {@code null}.
|
||||
* The {@link #containsKey containsKey} operation may be used to
|
||||
* distinguish these two cases.
|
||||
*/
|
||||
public V get(Object key) {
|
||||
return (isValidKey(key) ?
|
||||
unmaskNull(vals[((Enum<?>)key).ordinal()]) : null);
|
||||
}
|
||||
|
||||
// Modification Operations
|
||||
|
||||
/**
|
||||
* Associates the specified value with the specified key in this map.
|
||||
* If the map previously contained a mapping for this key, the old
|
||||
* value is replaced.
|
||||
*
|
||||
* @param key the key with which the specified value is to be associated
|
||||
* @param value the value to be associated with the specified key
|
||||
*
|
||||
* @return the previous value associated with specified key, or
|
||||
* <tt>null</tt> if there was no mapping for key. (A <tt>null</tt>
|
||||
* return can also indicate that the map previously associated
|
||||
* <tt>null</tt> with the specified key.)
|
||||
* @throws NullPointerException if the specified key is null
|
||||
*/
|
||||
public V put(K key, V value) {
|
||||
typeCheck(key);
|
||||
|
||||
int index = key.ordinal();
|
||||
Object oldValue = vals[index];
|
||||
vals[index] = maskNull(value);
|
||||
if (oldValue == null)
|
||||
size++;
|
||||
return unmaskNull(oldValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the mapping for this key from this map if present.
|
||||
*
|
||||
* @param key the key whose mapping is to be removed from the map
|
||||
* @return the previous value associated with specified key, or
|
||||
* <tt>null</tt> if there was no entry for key. (A <tt>null</tt>
|
||||
* return can also indicate that the map previously associated
|
||||
* <tt>null</tt> with the specified key.)
|
||||
*/
|
||||
public V remove(Object key) {
|
||||
if (!isValidKey(key))
|
||||
return null;
|
||||
int index = ((Enum<?>)key).ordinal();
|
||||
Object oldValue = vals[index];
|
||||
vals[index] = null;
|
||||
if (oldValue != null)
|
||||
size--;
|
||||
return unmaskNull(oldValue);
|
||||
}
|
||||
|
||||
private boolean removeMapping(Object key, Object value) {
|
||||
if (!isValidKey(key))
|
||||
return false;
|
||||
int index = ((Enum<?>)key).ordinal();
|
||||
if (maskNull(value).equals(vals[index])) {
|
||||
vals[index] = null;
|
||||
size--;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if key is of the proper type to be a key in this
|
||||
* enum map.
|
||||
*/
|
||||
private boolean isValidKey(Object key) {
|
||||
if (key == null)
|
||||
return false;
|
||||
|
||||
// Cheaper than instanceof Enum followed by getDeclaringClass
|
||||
Class<?> keyClass = key.getClass();
|
||||
return keyClass == keyType || keyClass.getSuperclass() == keyType;
|
||||
}
|
||||
|
||||
// Bulk Operations
|
||||
|
||||
/**
|
||||
* Copies all of the mappings from the specified map to this map.
|
||||
* These mappings will replace any mappings that this map had for
|
||||
* any of the keys currently in the specified map.
|
||||
*
|
||||
* @param m the mappings to be stored in this map
|
||||
* @throws NullPointerException the specified map is null, or if
|
||||
* one or more keys in the specified map are null
|
||||
*/
|
||||
public void putAll(Map<? extends K, ? extends V> m) {
|
||||
if (m instanceof EnumMap) {
|
||||
EnumMap<?, ?> em = (EnumMap<?, ?>)m;
|
||||
if (em.keyType != keyType) {
|
||||
if (em.isEmpty())
|
||||
return;
|
||||
throw new ClassCastException(em.keyType + " != " + keyType);
|
||||
}
|
||||
|
||||
for (int i = 0; i < keyUniverse.length; i++) {
|
||||
Object emValue = em.vals[i];
|
||||
if (emValue != null) {
|
||||
if (vals[i] == null)
|
||||
size++;
|
||||
vals[i] = emValue;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
super.putAll(m);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all mappings from this map.
|
||||
*/
|
||||
public void clear() {
|
||||
Arrays.fill(vals, null);
|
||||
size = 0;
|
||||
}
|
||||
|
||||
// Views
|
||||
|
||||
/**
|
||||
* This field is initialized to contain an instance of the entry set
|
||||
* view the first time this view is requested. The view is stateless,
|
||||
* so there's no reason to create more than one.
|
||||
*/
|
||||
private transient Set<Map.Entry<K,V>> entrySet;
|
||||
|
||||
/**
|
||||
* Returns a {@link Set} view of the keys contained in this map.
|
||||
* The returned set obeys the general contract outlined in
|
||||
* {@link Map#keySet()}. The set's iterator will return the keys
|
||||
* in their natural order (the order in which the enum constants
|
||||
* are declared).
|
||||
*
|
||||
* @return a set view of the keys contained in this enum map
|
||||
*/
|
||||
public Set<K> keySet() {
|
||||
Set<K> ks = keySet;
|
||||
if (ks == null) {
|
||||
ks = new KeySet();
|
||||
keySet = ks;
|
||||
}
|
||||
return ks;
|
||||
}
|
||||
|
||||
private class KeySet extends AbstractSet<K> {
|
||||
public Iterator<K> iterator() {
|
||||
return new KeyIterator();
|
||||
}
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
public boolean contains(Object o) {
|
||||
return containsKey(o);
|
||||
}
|
||||
public boolean remove(Object o) {
|
||||
int oldSize = size;
|
||||
EnumMap.this.remove(o);
|
||||
return size != oldSize;
|
||||
}
|
||||
public void clear() {
|
||||
EnumMap.this.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Collection} view of the values contained in this map.
|
||||
* The returned collection obeys the general contract outlined in
|
||||
* {@link Map#values()}. The collection's iterator will return the
|
||||
* values in the order their corresponding keys appear in map,
|
||||
* which is their natural order (the order in which the enum constants
|
||||
* are declared).
|
||||
*
|
||||
* @return a collection view of the values contained in this map
|
||||
*/
|
||||
public Collection<V> values() {
|
||||
Collection<V> vs = values;
|
||||
if (vs == null) {
|
||||
vs = new Values();
|
||||
values = vs;
|
||||
}
|
||||
return vs;
|
||||
}
|
||||
|
||||
private class Values extends AbstractCollection<V> {
|
||||
public Iterator<V> iterator() {
|
||||
return new ValueIterator();
|
||||
}
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
public boolean contains(Object o) {
|
||||
return containsValue(o);
|
||||
}
|
||||
public boolean remove(Object o) {
|
||||
o = maskNull(o);
|
||||
|
||||
for (int i = 0; i < vals.length; i++) {
|
||||
if (o.equals(vals[i])) {
|
||||
vals[i] = null;
|
||||
size--;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public void clear() {
|
||||
EnumMap.this.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Set} view of the mappings contained in this map.
|
||||
* The returned set obeys the general contract outlined in
|
||||
* {@link Map#keySet()}. The set's iterator will return the
|
||||
* mappings in the order their keys appear in map, which is their
|
||||
* natural order (the order in which the enum constants are declared).
|
||||
*
|
||||
* @return a set view of the mappings contained in this enum map
|
||||
*/
|
||||
public Set<Map.Entry<K,V>> entrySet() {
|
||||
Set<Map.Entry<K,V>> es = entrySet;
|
||||
if (es != null)
|
||||
return es;
|
||||
else
|
||||
return entrySet = new EntrySet();
|
||||
}
|
||||
|
||||
private class EntrySet extends AbstractSet<Map.Entry<K,V>> {
|
||||
public Iterator<Map.Entry<K,V>> iterator() {
|
||||
return new EntryIterator();
|
||||
}
|
||||
|
||||
public boolean contains(Object o) {
|
||||
if (!(o instanceof Map.Entry))
|
||||
return false;
|
||||
Map.Entry<?,?> entry = (Map.Entry<?,?>)o;
|
||||
return containsMapping(entry.getKey(), entry.getValue());
|
||||
}
|
||||
public boolean remove(Object o) {
|
||||
if (!(o instanceof Map.Entry))
|
||||
return false;
|
||||
Map.Entry<?,?> entry = (Map.Entry<?,?>)o;
|
||||
return removeMapping(entry.getKey(), entry.getValue());
|
||||
}
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
public void clear() {
|
||||
EnumMap.this.clear();
|
||||
}
|
||||
public Object[] toArray() {
|
||||
return fillEntryArray(new Object[size]);
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T[] toArray(T[] a) {
|
||||
int size = size();
|
||||
if (a.length < size)
|
||||
a = (T[])java.lang.reflect.Array
|
||||
.newInstance(a.getClass().getComponentType(), size);
|
||||
if (a.length > size)
|
||||
a[size] = null;
|
||||
return (T[]) fillEntryArray(a);
|
||||
}
|
||||
private Object[] fillEntryArray(Object[] a) {
|
||||
int j = 0;
|
||||
for (int i = 0; i < vals.length; i++)
|
||||
if (vals[i] != null)
|
||||
a[j++] = new AbstractMap.SimpleEntry<>(
|
||||
keyUniverse[i], unmaskNull(vals[i]));
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
private abstract class EnumMapIterator<T> implements Iterator<T> {
|
||||
// Lower bound on index of next element to return
|
||||
int index = 0;
|
||||
|
||||
// Index of last returned element, or -1 if none
|
||||
int lastReturnedIndex = -1;
|
||||
|
||||
public boolean hasNext() {
|
||||
while (index < vals.length && vals[index] == null)
|
||||
index++;
|
||||
return index != vals.length;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
checkLastReturnedIndex();
|
||||
|
||||
if (vals[lastReturnedIndex] != null) {
|
||||
vals[lastReturnedIndex] = null;
|
||||
size--;
|
||||
}
|
||||
lastReturnedIndex = -1;
|
||||
}
|
||||
|
||||
private void checkLastReturnedIndex() {
|
||||
if (lastReturnedIndex < 0)
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
private class KeyIterator extends EnumMapIterator<K> {
|
||||
public K next() {
|
||||
if (!hasNext())
|
||||
throw new NoSuchElementException();
|
||||
lastReturnedIndex = index++;
|
||||
return keyUniverse[lastReturnedIndex];
|
||||
}
|
||||
}
|
||||
|
||||
private class ValueIterator extends EnumMapIterator<V> {
|
||||
public V next() {
|
||||
if (!hasNext())
|
||||
throw new NoSuchElementException();
|
||||
lastReturnedIndex = index++;
|
||||
return unmaskNull(vals[lastReturnedIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
private class EntryIterator extends EnumMapIterator<Map.Entry<K,V>> {
|
||||
private Entry lastReturnedEntry;
|
||||
|
||||
public Map.Entry<K,V> next() {
|
||||
if (!hasNext())
|
||||
throw new NoSuchElementException();
|
||||
lastReturnedEntry = new Entry(index++);
|
||||
return lastReturnedEntry;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
lastReturnedIndex =
|
||||
((null == lastReturnedEntry) ? -1 : lastReturnedEntry.index);
|
||||
super.remove();
|
||||
lastReturnedEntry.index = lastReturnedIndex;
|
||||
lastReturnedEntry = null;
|
||||
}
|
||||
|
||||
private class Entry implements Map.Entry<K,V> {
|
||||
private int index;
|
||||
|
||||
private Entry(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public K getKey() {
|
||||
checkIndexForEntryUse();
|
||||
return keyUniverse[index];
|
||||
}
|
||||
|
||||
public V getValue() {
|
||||
checkIndexForEntryUse();
|
||||
return unmaskNull(vals[index]);
|
||||
}
|
||||
|
||||
public V setValue(V value) {
|
||||
checkIndexForEntryUse();
|
||||
V oldValue = unmaskNull(vals[index]);
|
||||
vals[index] = maskNull(value);
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (index < 0)
|
||||
return o == this;
|
||||
|
||||
if (!(o instanceof Map.Entry))
|
||||
return false;
|
||||
|
||||
Map.Entry<?,?> e = (Map.Entry<?,?>)o;
|
||||
V ourValue = unmaskNull(vals[index]);
|
||||
Object hisValue = e.getValue();
|
||||
return (e.getKey() == keyUniverse[index] &&
|
||||
(ourValue == hisValue ||
|
||||
(ourValue != null && ourValue.equals(hisValue))));
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
if (index < 0)
|
||||
return super.hashCode();
|
||||
|
||||
return entryHashCode(index);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if (index < 0)
|
||||
return super.toString();
|
||||
|
||||
return keyUniverse[index] + "="
|
||||
+ unmaskNull(vals[index]);
|
||||
}
|
||||
|
||||
private void checkIndexForEntryUse() {
|
||||
if (index < 0)
|
||||
throw new IllegalStateException("Entry was removed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Comparison and hashing
|
||||
|
||||
/**
|
||||
* Compares the specified object with this map for equality. Returns
|
||||
* <tt>true</tt> if the given object is also a map and the two maps
|
||||
* represent the same mappings, as specified in the {@link
|
||||
* Map#equals(Object)} contract.
|
||||
*
|
||||
* @param o the object to be compared for equality with this map
|
||||
* @return <tt>true</tt> if the specified object is equal to this map
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o instanceof EnumMap)
|
||||
return equals((EnumMap<?,?>)o);
|
||||
if (!(o instanceof Map))
|
||||
return false;
|
||||
|
||||
Map<?,?> m = (Map<?,?>)o;
|
||||
if (size != m.size())
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < keyUniverse.length; i++) {
|
||||
if (null != vals[i]) {
|
||||
K key = keyUniverse[i];
|
||||
V value = unmaskNull(vals[i]);
|
||||
if (null == value) {
|
||||
if (!((null == m.get(key)) && m.containsKey(key)))
|
||||
return false;
|
||||
} else {
|
||||
if (!value.equals(m.get(key)))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean equals(EnumMap<?,?> em) {
|
||||
if (em.keyType != keyType)
|
||||
return size == 0 && em.size == 0;
|
||||
|
||||
// Key types match, compare each value
|
||||
for (int i = 0; i < keyUniverse.length; i++) {
|
||||
Object ourValue = vals[i];
|
||||
Object hisValue = em.vals[i];
|
||||
if (hisValue != ourValue &&
|
||||
(hisValue == null || !hisValue.equals(ourValue)))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code value for this map. The hash code of a map is
|
||||
* defined to be the sum of the hash codes of each entry in the map.
|
||||
*/
|
||||
public int hashCode() {
|
||||
int h = 0;
|
||||
|
||||
for (int i = 0; i < keyUniverse.length; i++) {
|
||||
if (null != vals[i]) {
|
||||
h += entryHashCode(i);
|
||||
}
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
private int entryHashCode(int index) {
|
||||
return (keyUniverse[index].hashCode() ^ vals[index].hashCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a shallow copy of this enum map. (The values themselves
|
||||
* are not cloned.
|
||||
*
|
||||
* @return a shallow copy of this enum map
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public EnumMap<K, V> clone() {
|
||||
EnumMap<K, V> result = null;
|
||||
try {
|
||||
result = (EnumMap<K, V>) super.clone();
|
||||
} catch(CloneNotSupportedException e) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
result.vals = result.vals.clone();
|
||||
result.entrySet = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an exception if e is not of the correct type for this enum set.
|
||||
*/
|
||||
private void typeCheck(K key) {
|
||||
Class<?> keyClass = key.getClass();
|
||||
if (keyClass != keyType && keyClass.getSuperclass() != keyType)
|
||||
throw new ClassCastException(keyClass + " != " + keyType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all of the values comprising K.
|
||||
* The result is uncloned, cached, and shared by all callers.
|
||||
*/
|
||||
private static <K extends Enum<K>> K[] getKeyUniverse(Class<K> keyType) {
|
||||
return SharedSecrets.getJavaLangAccess()
|
||||
.getEnumConstantsShared(keyType);
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 458661240069192865L;
|
||||
|
||||
/**
|
||||
* Save the state of the <tt>EnumMap</tt> instance to a stream (i.e.,
|
||||
* serialize it).
|
||||
*
|
||||
* @serialData The <i>size</i> of the enum map (the number of key-value
|
||||
* mappings) is emitted (int), followed by the key (Object)
|
||||
* and value (Object) for each key-value mapping represented
|
||||
* by the enum map.
|
||||
*/
|
||||
private void writeObject(java.io.ObjectOutputStream s)
|
||||
throws java.io.IOException
|
||||
{
|
||||
// Write out the key type and any hidden stuff
|
||||
s.defaultWriteObject();
|
||||
|
||||
// Write out size (number of Mappings)
|
||||
s.writeInt(size);
|
||||
|
||||
// Write out keys and values (alternating)
|
||||
int entriesToBeWritten = size;
|
||||
for (int i = 0; entriesToBeWritten > 0; i++) {
|
||||
if (null != vals[i]) {
|
||||
s.writeObject(keyUniverse[i]);
|
||||
s.writeObject(unmaskNull(vals[i]));
|
||||
entriesToBeWritten--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconstitute the <tt>EnumMap</tt> instance from a stream (i.e.,
|
||||
* deserialize it).
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private void readObject(java.io.ObjectInputStream s)
|
||||
throws java.io.IOException, ClassNotFoundException
|
||||
{
|
||||
// Read in the key type and any hidden stuff
|
||||
s.defaultReadObject();
|
||||
|
||||
keyUniverse = getKeyUniverse(keyType);
|
||||
vals = new Object[keyUniverse.length];
|
||||
|
||||
// Read in size (number of Mappings)
|
||||
int size = s.readInt();
|
||||
|
||||
// Read the keys and values, and put the mappings in the HashMap
|
||||
for (int i = 0; i < size; i++) {
|
||||
K key = (K) s.readObject();
|
||||
V value = (V) s.readObject();
|
||||
put(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
464
jdkSrc/jdk8/java/util/EnumSet.java
Normal file
464
jdkSrc/jdk8/java/util/EnumSet.java
Normal file
@@ -0,0 +1,464 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
import sun.misc.SharedSecrets;
|
||||
|
||||
/**
|
||||
* A specialized {@link Set} implementation for use with enum types. All of
|
||||
* the elements in an enum set must come from a single enum type that is
|
||||
* specified, explicitly or implicitly, when the set is created. Enum sets
|
||||
* are represented internally as bit vectors. This representation is
|
||||
* extremely compact and efficient. The space and time performance of this
|
||||
* class should be good enough to allow its use as a high-quality, typesafe
|
||||
* alternative to traditional <tt>int</tt>-based "bit flags." Even bulk
|
||||
* operations (such as <tt>containsAll</tt> and <tt>retainAll</tt>) should
|
||||
* run very quickly if their argument is also an enum set.
|
||||
*
|
||||
* <p>The iterator returned by the <tt>iterator</tt> method traverses the
|
||||
* elements in their <i>natural order</i> (the order in which the enum
|
||||
* constants are declared). The returned iterator is <i>weakly
|
||||
* consistent</i>: it will never throw {@link ConcurrentModificationException}
|
||||
* and it may or may not show the effects of any modifications to the set that
|
||||
* occur while the iteration is in progress.
|
||||
*
|
||||
* <p>Null elements are not permitted. Attempts to insert a null element
|
||||
* will throw {@link NullPointerException}. Attempts to test for the
|
||||
* presence of a null element or to remove one will, however, function
|
||||
* properly.
|
||||
*
|
||||
* <P>Like most collection implementations, <tt>EnumSet</tt> is not
|
||||
* synchronized. If multiple threads access an enum set concurrently, and at
|
||||
* least one of the threads modifies the set, it should be synchronized
|
||||
* externally. This is typically accomplished by synchronizing on some
|
||||
* object that naturally encapsulates the enum set. If no such object exists,
|
||||
* the set should be "wrapped" using the {@link Collections#synchronizedSet}
|
||||
* method. This is best done at creation time, to prevent accidental
|
||||
* unsynchronized access:
|
||||
*
|
||||
* <pre>
|
||||
* Set<MyEnum> s = Collections.synchronizedSet(EnumSet.noneOf(MyEnum.class));
|
||||
* </pre>
|
||||
*
|
||||
* <p>Implementation note: All basic operations execute in constant time.
|
||||
* They are likely (though not guaranteed) to be much faster than their
|
||||
* {@link HashSet} counterparts. Even bulk operations execute in
|
||||
* constant time if their argument is also an enum set.
|
||||
*
|
||||
* <p>This class is a member of the
|
||||
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
|
||||
* Java Collections Framework</a>.
|
||||
*
|
||||
* @author Josh Bloch
|
||||
* @since 1.5
|
||||
* @see EnumMap
|
||||
* @serial exclude
|
||||
*/
|
||||
public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
|
||||
implements Cloneable, java.io.Serializable
|
||||
{
|
||||
/**
|
||||
* The class of all the elements of this set.
|
||||
*/
|
||||
final Class<E> elementType;
|
||||
|
||||
/**
|
||||
* All of the values comprising T. (Cached for performance.)
|
||||
*/
|
||||
final Enum<?>[] universe;
|
||||
|
||||
private static Enum<?>[] ZERO_LENGTH_ENUM_ARRAY = new Enum<?>[0];
|
||||
|
||||
EnumSet(Class<E>elementType, Enum<?>[] universe) {
|
||||
this.elementType = elementType;
|
||||
this.universe = universe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an empty enum set with the specified element type.
|
||||
*
|
||||
* @param <E> The class of the elements in the set
|
||||
* @param elementType the class object of the element type for this enum
|
||||
* set
|
||||
* @return An empty enum set of the specified type.
|
||||
* @throws NullPointerException if <tt>elementType</tt> is null
|
||||
*/
|
||||
public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
|
||||
Enum<?>[] universe = getUniverse(elementType);
|
||||
if (universe == null)
|
||||
throw new ClassCastException(elementType + " not an enum");
|
||||
|
||||
if (universe.length <= 64)
|
||||
return new RegularEnumSet<>(elementType, universe);
|
||||
else
|
||||
return new JumboEnumSet<>(elementType, universe);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an enum set containing all of the elements in the specified
|
||||
* element type.
|
||||
*
|
||||
* @param <E> The class of the elements in the set
|
||||
* @param elementType the class object of the element type for this enum
|
||||
* set
|
||||
* @return An enum set containing all the elements in the specified type.
|
||||
* @throws NullPointerException if <tt>elementType</tt> is null
|
||||
*/
|
||||
public static <E extends Enum<E>> EnumSet<E> allOf(Class<E> elementType) {
|
||||
EnumSet<E> result = noneOf(elementType);
|
||||
result.addAll();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all of the elements from the appropriate enum type to this enum
|
||||
* set, which is empty prior to the call.
|
||||
*/
|
||||
abstract void addAll();
|
||||
|
||||
/**
|
||||
* Creates an enum set with the same element type as the specified enum
|
||||
* set, initially containing the same elements (if any).
|
||||
*
|
||||
* @param <E> The class of the elements in the set
|
||||
* @param s the enum set from which to initialize this enum set
|
||||
* @return A copy of the specified enum set.
|
||||
* @throws NullPointerException if <tt>s</tt> is null
|
||||
*/
|
||||
public static <E extends Enum<E>> EnumSet<E> copyOf(EnumSet<E> s) {
|
||||
return s.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an enum set initialized from the specified collection. If
|
||||
* the specified collection is an <tt>EnumSet</tt> instance, this static
|
||||
* factory method behaves identically to {@link #copyOf(EnumSet)}.
|
||||
* Otherwise, the specified collection must contain at least one element
|
||||
* (in order to determine the new enum set's element type).
|
||||
*
|
||||
* @param <E> The class of the elements in the collection
|
||||
* @param c the collection from which to initialize this enum set
|
||||
* @return An enum set initialized from the given collection.
|
||||
* @throws IllegalArgumentException if <tt>c</tt> is not an
|
||||
* <tt>EnumSet</tt> instance and contains no elements
|
||||
* @throws NullPointerException if <tt>c</tt> is null
|
||||
*/
|
||||
public static <E extends Enum<E>> EnumSet<E> copyOf(Collection<E> c) {
|
||||
if (c instanceof EnumSet) {
|
||||
return ((EnumSet<E>)c).clone();
|
||||
} else {
|
||||
if (c.isEmpty())
|
||||
throw new IllegalArgumentException("Collection is empty");
|
||||
Iterator<E> i = c.iterator();
|
||||
E first = i.next();
|
||||
EnumSet<E> result = EnumSet.of(first);
|
||||
while (i.hasNext())
|
||||
result.add(i.next());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an enum set with the same element type as the specified enum
|
||||
* set, initially containing all the elements of this type that are
|
||||
* <i>not</i> contained in the specified set.
|
||||
*
|
||||
* @param <E> The class of the elements in the enum set
|
||||
* @param s the enum set from whose complement to initialize this enum set
|
||||
* @return The complement of the specified set in this set
|
||||
* @throws NullPointerException if <tt>s</tt> is null
|
||||
*/
|
||||
public static <E extends Enum<E>> EnumSet<E> complementOf(EnumSet<E> s) {
|
||||
EnumSet<E> result = copyOf(s);
|
||||
result.complement();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an enum set initially containing the specified element.
|
||||
*
|
||||
* Overloadings of this method exist to initialize an enum set with
|
||||
* one through five elements. A sixth overloading is provided that
|
||||
* uses the varargs feature. This overloading may be used to create
|
||||
* an enum set initially containing an arbitrary number of elements, but
|
||||
* is likely to run slower than the overloadings that do not use varargs.
|
||||
*
|
||||
* @param <E> The class of the specified element and of the set
|
||||
* @param e the element that this set is to contain initially
|
||||
* @throws NullPointerException if <tt>e</tt> is null
|
||||
* @return an enum set initially containing the specified element
|
||||
*/
|
||||
public static <E extends Enum<E>> EnumSet<E> of(E e) {
|
||||
EnumSet<E> result = noneOf(e.getDeclaringClass());
|
||||
result.add(e);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an enum set initially containing the specified elements.
|
||||
*
|
||||
* Overloadings of this method exist to initialize an enum set with
|
||||
* one through five elements. A sixth overloading is provided that
|
||||
* uses the varargs feature. This overloading may be used to create
|
||||
* an enum set initially containing an arbitrary number of elements, but
|
||||
* is likely to run slower than the overloadings that do not use varargs.
|
||||
*
|
||||
* @param <E> The class of the parameter elements and of the set
|
||||
* @param e1 an element that this set is to contain initially
|
||||
* @param e2 another element that this set is to contain initially
|
||||
* @throws NullPointerException if any parameters are null
|
||||
* @return an enum set initially containing the specified elements
|
||||
*/
|
||||
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2) {
|
||||
EnumSet<E> result = noneOf(e1.getDeclaringClass());
|
||||
result.add(e1);
|
||||
result.add(e2);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an enum set initially containing the specified elements.
|
||||
*
|
||||
* Overloadings of this method exist to initialize an enum set with
|
||||
* one through five elements. A sixth overloading is provided that
|
||||
* uses the varargs feature. This overloading may be used to create
|
||||
* an enum set initially containing an arbitrary number of elements, but
|
||||
* is likely to run slower than the overloadings that do not use varargs.
|
||||
*
|
||||
* @param <E> The class of the parameter elements and of the set
|
||||
* @param e1 an element that this set is to contain initially
|
||||
* @param e2 another element that this set is to contain initially
|
||||
* @param e3 another element that this set is to contain initially
|
||||
* @throws NullPointerException if any parameters are null
|
||||
* @return an enum set initially containing the specified elements
|
||||
*/
|
||||
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3) {
|
||||
EnumSet<E> result = noneOf(e1.getDeclaringClass());
|
||||
result.add(e1);
|
||||
result.add(e2);
|
||||
result.add(e3);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an enum set initially containing the specified elements.
|
||||
*
|
||||
* Overloadings of this method exist to initialize an enum set with
|
||||
* one through five elements. A sixth overloading is provided that
|
||||
* uses the varargs feature. This overloading may be used to create
|
||||
* an enum set initially containing an arbitrary number of elements, but
|
||||
* is likely to run slower than the overloadings that do not use varargs.
|
||||
*
|
||||
* @param <E> The class of the parameter elements and of the set
|
||||
* @param e1 an element that this set is to contain initially
|
||||
* @param e2 another element that this set is to contain initially
|
||||
* @param e3 another element that this set is to contain initially
|
||||
* @param e4 another element that this set is to contain initially
|
||||
* @throws NullPointerException if any parameters are null
|
||||
* @return an enum set initially containing the specified elements
|
||||
*/
|
||||
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4) {
|
||||
EnumSet<E> result = noneOf(e1.getDeclaringClass());
|
||||
result.add(e1);
|
||||
result.add(e2);
|
||||
result.add(e3);
|
||||
result.add(e4);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an enum set initially containing the specified elements.
|
||||
*
|
||||
* Overloadings of this method exist to initialize an enum set with
|
||||
* one through five elements. A sixth overloading is provided that
|
||||
* uses the varargs feature. This overloading may be used to create
|
||||
* an enum set initially containing an arbitrary number of elements, but
|
||||
* is likely to run slower than the overloadings that do not use varargs.
|
||||
*
|
||||
* @param <E> The class of the parameter elements and of the set
|
||||
* @param e1 an element that this set is to contain initially
|
||||
* @param e2 another element that this set is to contain initially
|
||||
* @param e3 another element that this set is to contain initially
|
||||
* @param e4 another element that this set is to contain initially
|
||||
* @param e5 another element that this set is to contain initially
|
||||
* @throws NullPointerException if any parameters are null
|
||||
* @return an enum set initially containing the specified elements
|
||||
*/
|
||||
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4,
|
||||
E e5)
|
||||
{
|
||||
EnumSet<E> result = noneOf(e1.getDeclaringClass());
|
||||
result.add(e1);
|
||||
result.add(e2);
|
||||
result.add(e3);
|
||||
result.add(e4);
|
||||
result.add(e5);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an enum set initially containing the specified elements.
|
||||
* This factory, whose parameter list uses the varargs feature, may
|
||||
* be used to create an enum set initially containing an arbitrary
|
||||
* number of elements, but it is likely to run slower than the overloadings
|
||||
* that do not use varargs.
|
||||
*
|
||||
* @param <E> The class of the parameter elements and of the set
|
||||
* @param first an element that the set is to contain initially
|
||||
* @param rest the remaining elements the set is to contain initially
|
||||
* @throws NullPointerException if any of the specified elements are null,
|
||||
* or if <tt>rest</tt> is null
|
||||
* @return an enum set initially containing the specified elements
|
||||
*/
|
||||
@SafeVarargs
|
||||
public static <E extends Enum<E>> EnumSet<E> of(E first, E... rest) {
|
||||
EnumSet<E> result = noneOf(first.getDeclaringClass());
|
||||
result.add(first);
|
||||
for (E e : rest)
|
||||
result.add(e);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an enum set initially containing all of the elements in the
|
||||
* range defined by the two specified endpoints. The returned set will
|
||||
* contain the endpoints themselves, which may be identical but must not
|
||||
* be out of order.
|
||||
*
|
||||
* @param <E> The class of the parameter elements and of the set
|
||||
* @param from the first element in the range
|
||||
* @param to the last element in the range
|
||||
* @throws NullPointerException if {@code from} or {@code to} are null
|
||||
* @throws IllegalArgumentException if {@code from.compareTo(to) > 0}
|
||||
* @return an enum set initially containing all of the elements in the
|
||||
* range defined by the two specified endpoints
|
||||
*/
|
||||
public static <E extends Enum<E>> EnumSet<E> range(E from, E to) {
|
||||
if (from.compareTo(to) > 0)
|
||||
throw new IllegalArgumentException(from + " > " + to);
|
||||
EnumSet<E> result = noneOf(from.getDeclaringClass());
|
||||
result.addRange(from, to);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified range to this enum set, which is empty prior
|
||||
* to the call.
|
||||
*/
|
||||
abstract void addRange(E from, E to);
|
||||
|
||||
/**
|
||||
* Returns a copy of this set.
|
||||
*
|
||||
* @return a copy of this set
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public EnumSet<E> clone() {
|
||||
try {
|
||||
return (EnumSet<E>) super.clone();
|
||||
} catch(CloneNotSupportedException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Complements the contents of this enum set.
|
||||
*/
|
||||
abstract void complement();
|
||||
|
||||
/**
|
||||
* Throws an exception if e is not of the correct type for this enum set.
|
||||
*/
|
||||
final void typeCheck(E e) {
|
||||
Class<?> eClass = e.getClass();
|
||||
if (eClass != elementType && eClass.getSuperclass() != elementType)
|
||||
throw new ClassCastException(eClass + " != " + elementType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all of the values comprising E.
|
||||
* The result is uncloned, cached, and shared by all callers.
|
||||
*/
|
||||
private static <E extends Enum<E>> E[] getUniverse(Class<E> elementType) {
|
||||
return SharedSecrets.getJavaLangAccess()
|
||||
.getEnumConstantsShared(elementType);
|
||||
}
|
||||
|
||||
/**
|
||||
* This class is used to serialize all EnumSet instances, regardless of
|
||||
* implementation type. It captures their "logical contents" and they
|
||||
* are reconstructed using public static factories. This is necessary
|
||||
* to ensure that the existence of a particular implementation type is
|
||||
* an implementation detail.
|
||||
*
|
||||
* @serial include
|
||||
*/
|
||||
private static class SerializationProxy <E extends Enum<E>>
|
||||
implements java.io.Serializable
|
||||
{
|
||||
/**
|
||||
* The element type of this enum set.
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
private final Class<E> elementType;
|
||||
|
||||
/**
|
||||
* The elements contained in this enum set.
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
private final Enum<?>[] elements;
|
||||
|
||||
SerializationProxy(EnumSet<E> set) {
|
||||
elementType = set.elementType;
|
||||
elements = set.toArray(ZERO_LENGTH_ENUM_ARRAY);
|
||||
}
|
||||
|
||||
// instead of cast to E, we should perhaps use elementType.cast()
|
||||
// to avoid injection of forged stream, but it will slow the implementation
|
||||
@SuppressWarnings("unchecked")
|
||||
private Object readResolve() {
|
||||
EnumSet<E> result = EnumSet.noneOf(elementType);
|
||||
for (Enum<?> e : elements)
|
||||
result.add((E)e);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 362491234563181265L;
|
||||
}
|
||||
|
||||
Object writeReplace() {
|
||||
return new SerializationProxy<>(this);
|
||||
}
|
||||
|
||||
// readObject method for the serialization proxy pattern
|
||||
// See Effective Java, Second Ed., Item 78.
|
||||
private void readObject(java.io.ObjectInputStream stream)
|
||||
throws java.io.InvalidObjectException {
|
||||
throw new java.io.InvalidObjectException("Proxy required");
|
||||
}
|
||||
}
|
||||
79
jdkSrc/jdk8/java/util/Enumeration.java
Normal file
79
jdkSrc/jdk8/java/util/Enumeration.java
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* An object that implements the Enumeration interface generates a
|
||||
* series of elements, one at a time. Successive calls to the
|
||||
* <code>nextElement</code> method return successive elements of the
|
||||
* series.
|
||||
* <p>
|
||||
* For example, to print all elements of a <tt>Vector<E></tt> <i>v</i>:
|
||||
* <pre>
|
||||
* for (Enumeration<E> e = v.elements(); e.hasMoreElements();)
|
||||
* System.out.println(e.nextElement());</pre>
|
||||
* <p>
|
||||
* Methods are provided to enumerate through the elements of a
|
||||
* vector, the keys of a hashtable, and the values in a hashtable.
|
||||
* Enumerations are also used to specify the input streams to a
|
||||
* <code>SequenceInputStream</code>.
|
||||
* <p>
|
||||
* NOTE: The functionality of this interface is duplicated by the Iterator
|
||||
* interface. In addition, Iterator adds an optional remove operation, and
|
||||
* has shorter method names. New implementations should consider using
|
||||
* Iterator in preference to Enumeration.
|
||||
*
|
||||
* @see java.util.Iterator
|
||||
* @see java.io.SequenceInputStream
|
||||
* @see java.util.Enumeration#nextElement()
|
||||
* @see java.util.Hashtable
|
||||
* @see java.util.Hashtable#elements()
|
||||
* @see java.util.Hashtable#keys()
|
||||
* @see java.util.Vector
|
||||
* @see java.util.Vector#elements()
|
||||
*
|
||||
* @author Lee Boynton
|
||||
* @since JDK1.0
|
||||
*/
|
||||
public interface Enumeration<E> {
|
||||
/**
|
||||
* Tests if this enumeration contains more elements.
|
||||
*
|
||||
* @return <code>true</code> if and only if this enumeration object
|
||||
* contains at least one more element to provide;
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
boolean hasMoreElements();
|
||||
|
||||
/**
|
||||
* Returns the next element of this enumeration if this enumeration
|
||||
* object has at least one more element to provide.
|
||||
*
|
||||
* @return the next element of this enumeration.
|
||||
* @exception NoSuchElementException if no more elements exist.
|
||||
*/
|
||||
E nextElement();
|
||||
}
|
||||
33
jdkSrc/jdk8/java/util/EventListener.java
Normal file
33
jdkSrc/jdk8/java/util/EventListener.java
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 1999, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* A tagging interface that all event listener interfaces must extend.
|
||||
* @since JDK1.1
|
||||
*/
|
||||
public interface EventListener {
|
||||
}
|
||||
75
jdkSrc/jdk8/java/util/EventListenerProxy.java
Normal file
75
jdkSrc/jdk8/java/util/EventListenerProxy.java
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* An abstract wrapper class for an {@code EventListener} class
|
||||
* which associates a set of additional parameters with the listener.
|
||||
* Subclasses must provide the storage and accessor methods
|
||||
* for the additional arguments or parameters.
|
||||
* <p>
|
||||
* For example, a bean which supports named properties
|
||||
* would have a two argument method signature for adding
|
||||
* a {@code PropertyChangeListener} for a property:
|
||||
* <pre>
|
||||
* public void addPropertyChangeListener(String propertyName,
|
||||
* PropertyChangeListener listener)
|
||||
* </pre>
|
||||
* If the bean also implemented the zero argument get listener method:
|
||||
* <pre>
|
||||
* public PropertyChangeListener[] getPropertyChangeListeners()
|
||||
* </pre>
|
||||
* then the array may contain inner {@code PropertyChangeListeners}
|
||||
* which are also {@code PropertyChangeListenerProxy} objects.
|
||||
* <p>
|
||||
* If the calling method is interested in retrieving the named property
|
||||
* then it would have to test the element to see if it is a proxy class.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
public abstract class EventListenerProxy<T extends EventListener>
|
||||
implements EventListener {
|
||||
|
||||
private final T listener;
|
||||
|
||||
/**
|
||||
* Creates a proxy for the specified listener.
|
||||
*
|
||||
* @param listener the listener object
|
||||
*/
|
||||
public EventListenerProxy(T listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the listener associated with the proxy.
|
||||
*
|
||||
* @return the listener associated with the proxy
|
||||
*/
|
||||
public T getListener() {
|
||||
return this.listener;
|
||||
}
|
||||
}
|
||||
78
jdkSrc/jdk8/java/util/EventObject.java
Normal file
78
jdkSrc/jdk8/java/util/EventObject.java
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* The root class from which all event state objects shall be derived.
|
||||
* <p>
|
||||
* All Events are constructed with a reference to the object, the "source",
|
||||
* that is logically deemed to be the object upon which the Event in question
|
||||
* initially occurred upon.
|
||||
*
|
||||
* @since JDK1.1
|
||||
*/
|
||||
|
||||
public class EventObject implements java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = 5516075349620653480L;
|
||||
|
||||
/**
|
||||
* The object on which the Event initially occurred.
|
||||
*/
|
||||
protected transient Object source;
|
||||
|
||||
/**
|
||||
* Constructs a prototypical Event.
|
||||
*
|
||||
* @param source The object on which the Event initially occurred.
|
||||
* @exception IllegalArgumentException if source is null.
|
||||
*/
|
||||
public EventObject(Object source) {
|
||||
if (source == null)
|
||||
throw new IllegalArgumentException("null source");
|
||||
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
/**
|
||||
* The object on which the Event initially occurred.
|
||||
*
|
||||
* @return The object on which the Event initially occurred.
|
||||
*/
|
||||
public Object getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a String representation of this EventObject.
|
||||
*
|
||||
* @return A a String representation of this EventObject.
|
||||
*/
|
||||
public String toString() {
|
||||
return getClass().getName() + "[source=" + source + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* Unchecked exception thrown when a conversion and flag are incompatible.
|
||||
*
|
||||
* <p> Unless otherwise specified, passing a <tt>null</tt> argument to any
|
||||
* method or constructor in this class will cause a {@link
|
||||
* NullPointerException} to be thrown.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class FormatFlagsConversionMismatchException
|
||||
extends IllegalFormatException
|
||||
{
|
||||
private static final long serialVersionUID = 19120414L;
|
||||
|
||||
private String f;
|
||||
|
||||
private char c;
|
||||
|
||||
/**
|
||||
* Constructs an instance of this class with the specified flag
|
||||
* and conversion.
|
||||
*
|
||||
* @param f
|
||||
* The flag
|
||||
*
|
||||
* @param c
|
||||
* The conversion
|
||||
*/
|
||||
public FormatFlagsConversionMismatchException(String f, char c) {
|
||||
if (f == null)
|
||||
throw new NullPointerException();
|
||||
this.f = f;
|
||||
this.c = c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the incompatible flag.
|
||||
*
|
||||
* @return The flag
|
||||
*/
|
||||
public String getFlags() {
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the incompatible conversion.
|
||||
*
|
||||
* @return The conversion
|
||||
*/
|
||||
public char getConversion() {
|
||||
return c;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return "Conversion = " + c + ", Flags = " + f;
|
||||
}
|
||||
}
|
||||
164
jdkSrc/jdk8/java/util/Formattable.java
Normal file
164
jdkSrc/jdk8/java/util/Formattable.java
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* The <tt>Formattable</tt> interface must be implemented by any class that
|
||||
* needs to perform custom formatting using the <tt>'s'</tt> conversion
|
||||
* specifier of {@link java.util.Formatter}. This interface allows basic
|
||||
* control for formatting arbitrary objects.
|
||||
*
|
||||
* For example, the following class prints out different representations of a
|
||||
* stock's name depending on the flags and length constraints:
|
||||
*
|
||||
* <pre> {@code
|
||||
* import java.nio.CharBuffer;
|
||||
* import java.util.Formatter;
|
||||
* import java.util.Formattable;
|
||||
* import java.util.Locale;
|
||||
* import static java.util.FormattableFlags.*;
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* public class StockName implements Formattable {
|
||||
* private String symbol, companyName, frenchCompanyName;
|
||||
* public StockName(String symbol, String companyName,
|
||||
* String frenchCompanyName) {
|
||||
* ...
|
||||
* }
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* public void formatTo(Formatter fmt, int f, int width, int precision) {
|
||||
* StringBuilder sb = new StringBuilder();
|
||||
*
|
||||
* // decide form of name
|
||||
* String name = companyName;
|
||||
* if (fmt.locale().equals(Locale.FRANCE))
|
||||
* name = frenchCompanyName;
|
||||
* boolean alternate = (f & ALTERNATE) == ALTERNATE;
|
||||
* boolean usesymbol = alternate || (precision != -1 && precision < 10);
|
||||
* String out = (usesymbol ? symbol : name);
|
||||
*
|
||||
* // apply precision
|
||||
* if (precision == -1 || out.length() < precision) {
|
||||
* // write it all
|
||||
* sb.append(out);
|
||||
* } else {
|
||||
* sb.append(out.substring(0, precision - 1)).append('*');
|
||||
* }
|
||||
*
|
||||
* // apply width and justification
|
||||
* int len = sb.length();
|
||||
* if (len < width)
|
||||
* for (int i = 0; i < width - len; i++)
|
||||
* if ((f & LEFT_JUSTIFY) == LEFT_JUSTIFY)
|
||||
* sb.append(' ');
|
||||
* else
|
||||
* sb.insert(0, ' ');
|
||||
*
|
||||
* fmt.format(sb.toString());
|
||||
* }
|
||||
*
|
||||
* public String toString() {
|
||||
* return String.format("%s - %s", symbol, companyName);
|
||||
* }
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p> When used in conjunction with the {@link java.util.Formatter}, the above
|
||||
* class produces the following output for various format strings.
|
||||
*
|
||||
* <pre> {@code
|
||||
* Formatter fmt = new Formatter();
|
||||
* StockName sn = new StockName("HUGE", "Huge Fruit, Inc.",
|
||||
* "Fruit Titanesque, Inc.");
|
||||
* fmt.format("%s", sn); // -> "Huge Fruit, Inc."
|
||||
* fmt.format("%s", sn.toString()); // -> "HUGE - Huge Fruit, Inc."
|
||||
* fmt.format("%#s", sn); // -> "HUGE"
|
||||
* fmt.format("%-10.8s", sn); // -> "HUGE "
|
||||
* fmt.format("%.12s", sn); // -> "Huge Fruit,*"
|
||||
* fmt.format(Locale.FRANCE, "%25s", sn); // -> " Fruit Titanesque, Inc."
|
||||
* }</pre>
|
||||
*
|
||||
* <p> Formattables are not necessarily safe for multithreaded access. Thread
|
||||
* safety is optional and may be enforced by classes that extend and implement
|
||||
* this interface.
|
||||
*
|
||||
* <p> Unless otherwise specified, passing a <tt>null</tt> argument to
|
||||
* any method in this interface will cause a {@link
|
||||
* NullPointerException} to be thrown.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public interface Formattable {
|
||||
|
||||
/**
|
||||
* Formats the object using the provided {@link Formatter formatter}.
|
||||
*
|
||||
* @param formatter
|
||||
* The {@link Formatter formatter}. Implementing classes may call
|
||||
* {@link Formatter#out() formatter.out()} or {@link
|
||||
* Formatter#locale() formatter.locale()} to obtain the {@link
|
||||
* Appendable} or {@link Locale} used by this
|
||||
* <tt>formatter</tt> respectively.
|
||||
*
|
||||
* @param flags
|
||||
* The flags modify the output format. The value is interpreted as
|
||||
* a bitmask. Any combination of the following flags may be set:
|
||||
* {@link FormattableFlags#LEFT_JUSTIFY}, {@link
|
||||
* FormattableFlags#UPPERCASE}, and {@link
|
||||
* FormattableFlags#ALTERNATE}. If no flags are set, the default
|
||||
* formatting of the implementing class will apply.
|
||||
*
|
||||
* @param width
|
||||
* The minimum number of characters to be written to the output.
|
||||
* If the length of the converted value is less than the
|
||||
* <tt>width</tt> then the output will be padded by
|
||||
* <tt>' '</tt> until the total number of characters
|
||||
* equals width. The padding is at the beginning by default. If
|
||||
* the {@link FormattableFlags#LEFT_JUSTIFY} flag is set then the
|
||||
* padding will be at the end. If <tt>width</tt> is <tt>-1</tt>
|
||||
* then there is no minimum.
|
||||
*
|
||||
* @param precision
|
||||
* The maximum number of characters to be written to the output.
|
||||
* The precision is applied before the width, thus the output will
|
||||
* be truncated to <tt>precision</tt> characters even if the
|
||||
* <tt>width</tt> is greater than the <tt>precision</tt>. If
|
||||
* <tt>precision</tt> is <tt>-1</tt> then there is no explicit
|
||||
* limit on the number of characters.
|
||||
*
|
||||
* @throws IllegalFormatException
|
||||
* If any of the parameters are invalid. For specification of all
|
||||
* possible formatting errors, see the <a
|
||||
* href="../util/Formatter.html#detail">Details</a> section of the
|
||||
* formatter class specification.
|
||||
*/
|
||||
void formatTo(Formatter formatter, int flags, int width, int precision);
|
||||
}
|
||||
75
jdkSrc/jdk8/java/util/FormattableFlags.java
Normal file
75
jdkSrc/jdk8/java/util/FormattableFlags.java
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* FomattableFlags are passed to the {@link Formattable#formatTo
|
||||
* Formattable.formatTo()} method and modify the output format for {@linkplain
|
||||
* Formattable Formattables}. Implementations of {@link Formattable} are
|
||||
* responsible for interpreting and validating any flags.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class FormattableFlags {
|
||||
|
||||
// Explicit instantiation of this class is prohibited.
|
||||
private FormattableFlags() {}
|
||||
|
||||
/**
|
||||
* Left-justifies the output. Spaces (<tt>'\u0020'</tt>) will be added
|
||||
* at the end of the converted value as required to fill the minimum width
|
||||
* of the field. If this flag is not set then the output will be
|
||||
* right-justified.
|
||||
*
|
||||
* <p> This flag corresponds to <tt>'-'</tt> (<tt>'\u002d'</tt>) in
|
||||
* the format specifier.
|
||||
*/
|
||||
public static final int LEFT_JUSTIFY = 1<<0; // '-'
|
||||
|
||||
/**
|
||||
* Converts the output to upper case according to the rules of the
|
||||
* {@linkplain java.util.Locale locale} given during creation of the
|
||||
* <tt>formatter</tt> argument of the {@link Formattable#formatTo
|
||||
* formatTo()} method. The output should be equivalent the following
|
||||
* invocation of {@link String#toUpperCase(java.util.Locale)}
|
||||
*
|
||||
* <pre>
|
||||
* out.toUpperCase() </pre>
|
||||
*
|
||||
* <p> This flag corresponds to <tt>'S'</tt> (<tt>'\u0053'</tt>) in
|
||||
* the format specifier.
|
||||
*/
|
||||
public static final int UPPERCASE = 1<<1; // 'S'
|
||||
|
||||
/**
|
||||
* Requires the output to use an alternate form. The definition of the
|
||||
* form is specified by the <tt>Formattable</tt>.
|
||||
*
|
||||
* <p> This flag corresponds to <tt>'#'</tt> (<tt>'\u0023'</tt>) in
|
||||
* the format specifier.
|
||||
*/
|
||||
public static final int ALTERNATE = 1<<2; // '#'
|
||||
}
|
||||
4700
jdkSrc/jdk8/java/util/Formatter.java
Normal file
4700
jdkSrc/jdk8/java/util/Formatter.java
Normal file
File diff suppressed because it is too large
Load Diff
45
jdkSrc/jdk8/java/util/FormatterClosedException.java
Normal file
45
jdkSrc/jdk8/java/util/FormatterClosedException.java
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* Unchecked exception thrown when the formatter has been closed.
|
||||
*
|
||||
* <p> Unless otherwise specified, passing a <tt>null</tt> argument to any
|
||||
* method or constructor in this class will cause a {@link
|
||||
* NullPointerException} to be thrown.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class FormatterClosedException extends IllegalStateException {
|
||||
|
||||
private static final long serialVersionUID = 18111216L;
|
||||
|
||||
/**
|
||||
* Constructs an instance of this class.
|
||||
*/
|
||||
public FormatterClosedException() { }
|
||||
}
|
||||
3297
jdkSrc/jdk8/java/util/GregorianCalendar.java
Normal file
3297
jdkSrc/jdk8/java/util/GregorianCalendar.java
Normal file
File diff suppressed because it is too large
Load Diff
2421
jdkSrc/jdk8/java/util/HashMap.java
Normal file
2421
jdkSrc/jdk8/java/util/HashMap.java
Normal file
File diff suppressed because it is too large
Load Diff
362
jdkSrc/jdk8/java/util/HashSet.java
Normal file
362
jdkSrc/jdk8/java/util/HashSet.java
Normal file
@@ -0,0 +1,362 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
import java.io.InvalidObjectException;
|
||||
import sun.misc.SharedSecrets;
|
||||
|
||||
/**
|
||||
* This class implements the <tt>Set</tt> interface, backed by a hash table
|
||||
* (actually a <tt>HashMap</tt> instance). It makes no guarantees as to the
|
||||
* iteration order of the set; in particular, it does not guarantee that the
|
||||
* order will remain constant over time. This class permits the <tt>null</tt>
|
||||
* element.
|
||||
*
|
||||
* <p>This class offers constant time performance for the basic operations
|
||||
* (<tt>add</tt>, <tt>remove</tt>, <tt>contains</tt> and <tt>size</tt>),
|
||||
* assuming the hash function disperses the elements properly among the
|
||||
* buckets. Iterating over this set requires time proportional to the sum of
|
||||
* the <tt>HashSet</tt> instance's size (the number of elements) plus the
|
||||
* "capacity" of the backing <tt>HashMap</tt> instance (the number of
|
||||
* buckets). Thus, it's very important not to set the initial capacity too
|
||||
* high (or the load factor too low) if iteration performance is important.
|
||||
*
|
||||
* <p><strong>Note that this implementation is not synchronized.</strong>
|
||||
* If multiple threads access a hash set concurrently, and at least one of
|
||||
* the threads modifies the set, it <i>must</i> be synchronized externally.
|
||||
* This is typically accomplished by synchronizing on some object that
|
||||
* naturally encapsulates the set.
|
||||
*
|
||||
* If no such object exists, the set should be "wrapped" using the
|
||||
* {@link Collections#synchronizedSet Collections.synchronizedSet}
|
||||
* method. This is best done at creation time, to prevent accidental
|
||||
* unsynchronized access to the set:<pre>
|
||||
* Set s = Collections.synchronizedSet(new HashSet(...));</pre>
|
||||
*
|
||||
* <p>The iterators returned by this class's <tt>iterator</tt> method are
|
||||
* <i>fail-fast</i>: if the set is modified at any time after the iterator is
|
||||
* created, in any way except through the iterator's own <tt>remove</tt>
|
||||
* method, the Iterator throws a {@link ConcurrentModificationException}.
|
||||
* Thus, in the face of concurrent modification, the iterator fails quickly
|
||||
* and cleanly, rather than risking arbitrary, non-deterministic behavior at
|
||||
* an undetermined time in the future.
|
||||
*
|
||||
* <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
|
||||
* as it is, generally speaking, impossible to make any hard guarantees in the
|
||||
* presence of unsynchronized concurrent modification. Fail-fast iterators
|
||||
* throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
|
||||
* Therefore, it would be wrong to write a program that depended on this
|
||||
* exception for its correctness: <i>the fail-fast behavior of iterators
|
||||
* should be used only to detect bugs.</i>
|
||||
*
|
||||
* <p>This class is a member of the
|
||||
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
|
||||
* Java Collections Framework</a>.
|
||||
*
|
||||
* @param <E> the type of elements maintained by this set
|
||||
*
|
||||
* @author Josh Bloch
|
||||
* @author Neal Gafter
|
||||
* @see Collection
|
||||
* @see Set
|
||||
* @see TreeSet
|
||||
* @see HashMap
|
||||
* @since 1.2
|
||||
*/
|
||||
|
||||
public class HashSet<E>
|
||||
extends AbstractSet<E>
|
||||
implements Set<E>, Cloneable, java.io.Serializable
|
||||
{
|
||||
static final long serialVersionUID = -5024744406713321676L;
|
||||
|
||||
private transient HashMap<E,Object> map;
|
||||
|
||||
// Dummy value to associate with an Object in the backing Map
|
||||
private static final Object PRESENT = new Object();
|
||||
|
||||
/**
|
||||
* Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
|
||||
* default initial capacity (16) and load factor (0.75).
|
||||
*/
|
||||
public HashSet() {
|
||||
map = new HashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new set containing the elements in the specified
|
||||
* collection. The <tt>HashMap</tt> is created with default load factor
|
||||
* (0.75) and an initial capacity sufficient to contain the elements in
|
||||
* the specified collection.
|
||||
*
|
||||
* @param c the collection whose elements are to be placed into this set
|
||||
* @throws NullPointerException if the specified collection is null
|
||||
*/
|
||||
public HashSet(Collection<? extends E> c) {
|
||||
map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
|
||||
addAll(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
|
||||
* the specified initial capacity and the specified load factor.
|
||||
*
|
||||
* @param initialCapacity the initial capacity of the hash map
|
||||
* @param loadFactor the load factor of the hash map
|
||||
* @throws IllegalArgumentException if the initial capacity is less
|
||||
* than zero, or if the load factor is nonpositive
|
||||
*/
|
||||
public HashSet(int initialCapacity, float loadFactor) {
|
||||
map = new HashMap<>(initialCapacity, loadFactor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
|
||||
* the specified initial capacity and default load factor (0.75).
|
||||
*
|
||||
* @param initialCapacity the initial capacity of the hash table
|
||||
* @throws IllegalArgumentException if the initial capacity is less
|
||||
* than zero
|
||||
*/
|
||||
public HashSet(int initialCapacity) {
|
||||
map = new HashMap<>(initialCapacity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new, empty linked hash set. (This package private
|
||||
* constructor is only used by LinkedHashSet.) The backing
|
||||
* HashMap instance is a LinkedHashMap with the specified initial
|
||||
* capacity and the specified load factor.
|
||||
*
|
||||
* @param initialCapacity the initial capacity of the hash map
|
||||
* @param loadFactor the load factor of the hash map
|
||||
* @param dummy ignored (distinguishes this
|
||||
* constructor from other int, float constructor.)
|
||||
* @throws IllegalArgumentException if the initial capacity is less
|
||||
* than zero, or if the load factor is nonpositive
|
||||
*/
|
||||
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
|
||||
map = new LinkedHashMap<>(initialCapacity, loadFactor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator over the elements in this set. The elements
|
||||
* are returned in no particular order.
|
||||
*
|
||||
* @return an Iterator over the elements in this set
|
||||
* @see ConcurrentModificationException
|
||||
*/
|
||||
public Iterator<E> iterator() {
|
||||
return map.keySet().iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of elements in this set (its cardinality).
|
||||
*
|
||||
* @return the number of elements in this set (its cardinality)
|
||||
*/
|
||||
public int size() {
|
||||
return map.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this set contains no elements.
|
||||
*
|
||||
* @return <tt>true</tt> if this set contains no elements
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return map.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this set contains the specified element.
|
||||
* More formally, returns <tt>true</tt> if and only if this set
|
||||
* contains an element <tt>e</tt> such that
|
||||
* <tt>(o==null ? e==null : o.equals(e))</tt>.
|
||||
*
|
||||
* @param o element whose presence in this set is to be tested
|
||||
* @return <tt>true</tt> if this set contains the specified element
|
||||
*/
|
||||
public boolean contains(Object o) {
|
||||
return map.containsKey(o);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified element to this set if it is not already present.
|
||||
* More formally, adds the specified element <tt>e</tt> to this set if
|
||||
* this set contains no element <tt>e2</tt> such that
|
||||
* <tt>(e==null ? e2==null : e.equals(e2))</tt>.
|
||||
* If this set already contains the element, the call leaves the set
|
||||
* unchanged and returns <tt>false</tt>.
|
||||
*
|
||||
* @param e element to be added to this set
|
||||
* @return <tt>true</tt> if this set did not already contain the specified
|
||||
* element
|
||||
*/
|
||||
public boolean add(E e) {
|
||||
return map.put(e, PRESENT)==null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified element from this set if it is present.
|
||||
* More formally, removes an element <tt>e</tt> such that
|
||||
* <tt>(o==null ? e==null : o.equals(e))</tt>,
|
||||
* if this set contains such an element. Returns <tt>true</tt> if
|
||||
* this set contained the element (or equivalently, if this set
|
||||
* changed as a result of the call). (This set will not contain the
|
||||
* element once the call returns.)
|
||||
*
|
||||
* @param o object to be removed from this set, if present
|
||||
* @return <tt>true</tt> if the set contained the specified element
|
||||
*/
|
||||
public boolean remove(Object o) {
|
||||
return map.remove(o)==PRESENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all of the elements from this set.
|
||||
* The set will be empty after this call returns.
|
||||
*/
|
||||
public void clear() {
|
||||
map.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a shallow copy of this <tt>HashSet</tt> instance: the elements
|
||||
* themselves are not cloned.
|
||||
*
|
||||
* @return a shallow copy of this set
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object clone() {
|
||||
try {
|
||||
HashSet<E> newSet = (HashSet<E>) super.clone();
|
||||
newSet.map = (HashMap<E, Object>) map.clone();
|
||||
return newSet;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new InternalError(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the state of this <tt>HashSet</tt> instance to a stream (that is,
|
||||
* serialize it).
|
||||
*
|
||||
* @serialData The capacity of the backing <tt>HashMap</tt> instance
|
||||
* (int), and its load factor (float) are emitted, followed by
|
||||
* the size of the set (the number of elements it contains)
|
||||
* (int), followed by all of its elements (each an Object) in
|
||||
* no particular order.
|
||||
*/
|
||||
private void writeObject(java.io.ObjectOutputStream s)
|
||||
throws java.io.IOException {
|
||||
// Write out any hidden serialization magic
|
||||
s.defaultWriteObject();
|
||||
|
||||
// Write out HashMap capacity and load factor
|
||||
s.writeInt(map.capacity());
|
||||
s.writeFloat(map.loadFactor());
|
||||
|
||||
// Write out size
|
||||
s.writeInt(map.size());
|
||||
|
||||
// Write out all elements in the proper order.
|
||||
for (E e : map.keySet())
|
||||
s.writeObject(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconstitute the <tt>HashSet</tt> instance from a stream (that is,
|
||||
* deserialize it).
|
||||
*/
|
||||
private void readObject(java.io.ObjectInputStream s)
|
||||
throws java.io.IOException, ClassNotFoundException {
|
||||
// Consume and ignore stream fields (currently zero).
|
||||
s.readFields();
|
||||
|
||||
// Read capacity and verify non-negative.
|
||||
int capacity = s.readInt();
|
||||
if (capacity < 0) {
|
||||
throw new InvalidObjectException("Illegal capacity: " +
|
||||
capacity);
|
||||
}
|
||||
|
||||
// Read load factor and verify positive and non NaN.
|
||||
float loadFactor = s.readFloat();
|
||||
if (loadFactor <= 0 || Float.isNaN(loadFactor)) {
|
||||
throw new InvalidObjectException("Illegal load factor: " +
|
||||
loadFactor);
|
||||
}
|
||||
// Clamp load factor to range of 0.25...4.0.
|
||||
loadFactor = Math.min(Math.max(0.25f, loadFactor), 4.0f);
|
||||
|
||||
// Read size and verify non-negative.
|
||||
int size = s.readInt();
|
||||
if (size < 0) {
|
||||
throw new InvalidObjectException("Illegal size: " + size);
|
||||
}
|
||||
// Set the capacity according to the size and load factor ensuring that
|
||||
// the HashMap is at least 25% full but clamping to maximum capacity.
|
||||
capacity = (int) Math.min(size * Math.min(1 / loadFactor, 4.0f),
|
||||
HashMap.MAXIMUM_CAPACITY);
|
||||
|
||||
// Constructing the backing map will lazily create an array when the first element is
|
||||
// added, so check it before construction. Call HashMap.tableSizeFor to compute the
|
||||
// actual allocation size. Check Map.Entry[].class since it's the nearest public type to
|
||||
// what is actually created.
|
||||
|
||||
SharedSecrets.getJavaOISAccess()
|
||||
.checkArray(s, Map.Entry[].class, HashMap.tableSizeFor(capacity));
|
||||
|
||||
// Create backing HashMap
|
||||
map = (((HashSet<?>)this) instanceof LinkedHashSet ?
|
||||
new LinkedHashMap<E,Object>(capacity, loadFactor) :
|
||||
new HashMap<E,Object>(capacity, loadFactor));
|
||||
|
||||
// Read in all elements in the proper order.
|
||||
for (int i=0; i<size; i++) {
|
||||
@SuppressWarnings("unchecked")
|
||||
E e = (E) s.readObject();
|
||||
map.put(e, PRESENT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
|
||||
* and <em>fail-fast</em> {@link Spliterator} over the elements in this
|
||||
* set.
|
||||
*
|
||||
* <p>The {@code Spliterator} reports {@link Spliterator#SIZED} and
|
||||
* {@link Spliterator#DISTINCT}. Overriding implementations should document
|
||||
* the reporting of additional characteristic values.
|
||||
*
|
||||
* @return a {@code Spliterator} over the elements in this set
|
||||
* @since 1.8
|
||||
*/
|
||||
public Spliterator<E> spliterator() {
|
||||
return new HashMap.KeySpliterator<E,Object>(map, 0, -1, 0, 0);
|
||||
}
|
||||
}
|
||||
1443
jdkSrc/jdk8/java/util/Hashtable.java
Normal file
1443
jdkSrc/jdk8/java/util/Hashtable.java
Normal file
File diff suppressed because it is too large
Load Diff
1604
jdkSrc/jdk8/java/util/IdentityHashMap.java
Normal file
1604
jdkSrc/jdk8/java/util/IdentityHashMap.java
Normal file
File diff suppressed because it is too large
Load Diff
69
jdkSrc/jdk8/java/util/IllegalFormatCodePointException.java
Normal file
69
jdkSrc/jdk8/java/util/IllegalFormatCodePointException.java
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* Unchecked exception thrown when a character with an invalid Unicode code
|
||||
* point as defined by {@link Character#isValidCodePoint} is passed to the
|
||||
* {@link Formatter}.
|
||||
*
|
||||
* <p> Unless otherwise specified, passing a <tt>null</tt> argument to any
|
||||
* method or constructor in this class will cause a {@link
|
||||
* NullPointerException} to be thrown.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class IllegalFormatCodePointException extends IllegalFormatException {
|
||||
|
||||
private static final long serialVersionUID = 19080630L;
|
||||
|
||||
private int c;
|
||||
|
||||
/**
|
||||
* Constructs an instance of this class with the specified illegal code
|
||||
* point as defined by {@link Character#isValidCodePoint}.
|
||||
*
|
||||
* @param c
|
||||
* The illegal Unicode code point
|
||||
*/
|
||||
public IllegalFormatCodePointException(int c) {
|
||||
this.c = c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the illegal code point as defined by {@link
|
||||
* Character#isValidCodePoint}.
|
||||
*
|
||||
* @return The illegal Unicode code point
|
||||
*/
|
||||
public int getCodePoint() {
|
||||
return c;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return String.format("Code point = %#x", c);
|
||||
}
|
||||
}
|
||||
84
jdkSrc/jdk8/java/util/IllegalFormatConversionException.java
Normal file
84
jdkSrc/jdk8/java/util/IllegalFormatConversionException.java
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* Unchecked exception thrown when the argument corresponding to the format
|
||||
* specifier is of an incompatible type.
|
||||
*
|
||||
* <p> Unless otherwise specified, passing a <tt>null</tt> argument to any
|
||||
* method or constructor in this class will cause a {@link
|
||||
* NullPointerException} to be thrown.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class IllegalFormatConversionException extends IllegalFormatException {
|
||||
|
||||
private static final long serialVersionUID = 17000126L;
|
||||
|
||||
private char c;
|
||||
private Class<?> arg;
|
||||
|
||||
/**
|
||||
* Constructs an instance of this class with the mismatched conversion and
|
||||
* the corresponding argument class.
|
||||
*
|
||||
* @param c
|
||||
* Inapplicable conversion
|
||||
*
|
||||
* @param arg
|
||||
* Class of the mismatched argument
|
||||
*/
|
||||
public IllegalFormatConversionException(char c, Class<?> arg) {
|
||||
if (arg == null)
|
||||
throw new NullPointerException();
|
||||
this.c = c;
|
||||
this.arg = arg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the inapplicable conversion.
|
||||
*
|
||||
* @return The inapplicable conversion
|
||||
*/
|
||||
public char getConversion() {
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the class of the mismatched argument.
|
||||
*
|
||||
* @return The class of the mismatched argument
|
||||
*/
|
||||
public Class<?> getArgumentClass() {
|
||||
return arg;
|
||||
}
|
||||
|
||||
// javadoc inherited from Throwable.java
|
||||
public String getMessage() {
|
||||
return String.format("%c != %s", c, arg.getName());
|
||||
}
|
||||
}
|
||||
42
jdkSrc/jdk8/java/util/IllegalFormatException.java
Normal file
42
jdkSrc/jdk8/java/util/IllegalFormatException.java
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* Unchecked exception thrown when a format string contains an illegal syntax
|
||||
* or a format specifier that is incompatible with the given arguments. Only
|
||||
* explicit subtypes of this exception which correspond to specific errors
|
||||
* should be instantiated.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class IllegalFormatException extends IllegalArgumentException {
|
||||
|
||||
private static final long serialVersionUID = 18830826L;
|
||||
|
||||
// package-private to prevent explicit instantiation
|
||||
IllegalFormatException() { }
|
||||
}
|
||||
67
jdkSrc/jdk8/java/util/IllegalFormatFlagsException.java
Normal file
67
jdkSrc/jdk8/java/util/IllegalFormatFlagsException.java
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* Unchecked exception thrown when an illegal combination flags is given.
|
||||
*
|
||||
* <p> Unless otherwise specified, passing a <tt>null</tt> argument to any
|
||||
* method or constructor in this class will cause a {@link
|
||||
* NullPointerException} to be thrown.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class IllegalFormatFlagsException extends IllegalFormatException {
|
||||
|
||||
private static final long serialVersionUID = 790824L;
|
||||
|
||||
private String flags;
|
||||
|
||||
/**
|
||||
* Constructs an instance of this class with the specified flags.
|
||||
*
|
||||
* @param f
|
||||
* The set of format flags which contain an illegal combination
|
||||
*/
|
||||
public IllegalFormatFlagsException(String f) {
|
||||
if (f == null)
|
||||
throw new NullPointerException();
|
||||
this.flags = f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of flags which contains an illegal combination.
|
||||
*
|
||||
* @return The flags
|
||||
*/
|
||||
public String getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return "Flags = '" + flags + "'";
|
||||
}
|
||||
}
|
||||
63
jdkSrc/jdk8/java/util/IllegalFormatPrecisionException.java
Normal file
63
jdkSrc/jdk8/java/util/IllegalFormatPrecisionException.java
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* Unchecked exception thrown when the precision is a negative value other than
|
||||
* <tt>-1</tt>, the conversion does not support a precision, or the value is
|
||||
* otherwise unsupported.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class IllegalFormatPrecisionException extends IllegalFormatException {
|
||||
|
||||
private static final long serialVersionUID = 18711008L;
|
||||
|
||||
private int p;
|
||||
|
||||
/**
|
||||
* Constructs an instance of this class with the specified precision.
|
||||
*
|
||||
* @param p
|
||||
* The precision
|
||||
*/
|
||||
public IllegalFormatPrecisionException(int p) {
|
||||
this.p = p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the precision
|
||||
*
|
||||
* @return The precision
|
||||
*/
|
||||
public int getPrecision() {
|
||||
return p;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return Integer.toString(p);
|
||||
}
|
||||
}
|
||||
62
jdkSrc/jdk8/java/util/IllegalFormatWidthException.java
Normal file
62
jdkSrc/jdk8/java/util/IllegalFormatWidthException.java
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* Unchecked exception thrown when the format width is a negative value other
|
||||
* than <tt>-1</tt> or is otherwise unsupported.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class IllegalFormatWidthException extends IllegalFormatException {
|
||||
|
||||
private static final long serialVersionUID = 16660902L;
|
||||
|
||||
private int w;
|
||||
|
||||
/**
|
||||
* Constructs an instance of this class with the specified width.
|
||||
*
|
||||
* @param w
|
||||
* The width
|
||||
*/
|
||||
public IllegalFormatWidthException(int w) {
|
||||
this.w = w;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the width
|
||||
*
|
||||
* @return The width
|
||||
*/
|
||||
public int getWidth() {
|
||||
return w;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return Integer.toString(w);
|
||||
}
|
||||
}
|
||||
90
jdkSrc/jdk8/java/util/IllformedLocaleException.java
Normal file
90
jdkSrc/jdk8/java/util/IllformedLocaleException.java
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2009-2010, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* Thrown by methods in {@link Locale} and {@link Locale.Builder} to
|
||||
* indicate that an argument is not a well-formed BCP 47 tag.
|
||||
*
|
||||
* @see Locale
|
||||
* @since 1.7
|
||||
*/
|
||||
public class IllformedLocaleException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = -5245986824925681401L;
|
||||
|
||||
private int _errIdx = -1;
|
||||
|
||||
/**
|
||||
* Constructs a new <code>IllformedLocaleException</code> with no
|
||||
* detail message and -1 as the error index.
|
||||
*/
|
||||
public IllformedLocaleException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>IllformedLocaleException</code> with the
|
||||
* given message and -1 as the error index.
|
||||
*
|
||||
* @param message the message
|
||||
*/
|
||||
public IllformedLocaleException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>IllformedLocaleException</code> with the
|
||||
* given message and the error index. The error index is the approximate
|
||||
* offset from the start of the ill-formed value to the point where the
|
||||
* parse first detected an error. A negative error index value indicates
|
||||
* either the error index is not applicable or unknown.
|
||||
*
|
||||
* @param message the message
|
||||
* @param errorIndex the index
|
||||
*/
|
||||
public IllformedLocaleException(String message, int errorIndex) {
|
||||
super(message + ((errorIndex < 0) ? "" : " [at index " + errorIndex + "]"));
|
||||
_errIdx = errorIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index where the error was found. A negative value indicates
|
||||
* either the error index is not applicable or unknown.
|
||||
*
|
||||
* @return the error index
|
||||
*/
|
||||
public int getErrorIndex() {
|
||||
return _errIdx;
|
||||
}
|
||||
}
|
||||
59
jdkSrc/jdk8/java/util/InputMismatchException.java
Normal file
59
jdkSrc/jdk8/java/util/InputMismatchException.java
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* Thrown by a <code>Scanner</code> to indicate that the token
|
||||
* retrieved does not match the pattern for the expected type, or
|
||||
* that the token is out of range for the expected type.
|
||||
*
|
||||
* @author unascribed
|
||||
* @see java.util.Scanner
|
||||
* @since 1.5
|
||||
*/
|
||||
public
|
||||
class InputMismatchException extends NoSuchElementException {
|
||||
private static final long serialVersionUID = 8811230760997066428L;
|
||||
|
||||
/**
|
||||
* Constructs an <code>InputMismatchException</code> with <tt>null</tt>
|
||||
* as its error message string.
|
||||
*/
|
||||
public InputMismatchException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an <code>InputMismatchException</code>, saving a reference
|
||||
* to the error message string <tt>s</tt> for later retrieval by the
|
||||
* <tt>getMessage</tt> method.
|
||||
*
|
||||
* @param s the detail message.
|
||||
*/
|
||||
public InputMismatchException(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
171
jdkSrc/jdk8/java/util/IntSummaryStatistics.java
Normal file
171
jdkSrc/jdk8/java/util/IntSummaryStatistics.java
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.util;
|
||||
|
||||
import java.util.function.IntConsumer;
|
||||
import java.util.stream.Collector;
|
||||
|
||||
/**
|
||||
* A state object for collecting statistics such as count, min, max, sum, and
|
||||
* average.
|
||||
*
|
||||
* <p>This class is designed to work with (though does not require)
|
||||
* {@linkplain java.util.stream streams}. For example, you can compute
|
||||
* summary statistics on a stream of ints with:
|
||||
* <pre> {@code
|
||||
* IntSummaryStatistics stats = intStream.collect(IntSummaryStatistics::new,
|
||||
* IntSummaryStatistics::accept,
|
||||
* IntSummaryStatistics::combine);
|
||||
* }</pre>
|
||||
*
|
||||
* <p>{@code IntSummaryStatistics} can be used as a
|
||||
* {@linkplain java.util.stream.Stream#collect(Collector) reduction}
|
||||
* target for a {@linkplain java.util.stream.Stream stream}. For example:
|
||||
*
|
||||
* <pre> {@code
|
||||
* IntSummaryStatistics stats = people.stream()
|
||||
* .collect(Collectors.summarizingInt(Person::getDependents));
|
||||
*}</pre>
|
||||
*
|
||||
* This computes, in a single pass, the count of people, as well as the minimum,
|
||||
* maximum, sum, and average of their number of dependents.
|
||||
*
|
||||
* @implNote This implementation is not thread safe. However, it is safe to use
|
||||
* {@link java.util.stream.Collectors#summarizingInt(java.util.function.ToIntFunction)
|
||||
* Collectors.toIntStatistics()} on a parallel stream, because the parallel
|
||||
* implementation of {@link java.util.stream.Stream#collect Stream.collect()}
|
||||
* provides the necessary partitioning, isolation, and merging of results for
|
||||
* safe and efficient parallel execution.
|
||||
*
|
||||
* <p>This implementation does not check for overflow of the sum.
|
||||
* @since 1.8
|
||||
*/
|
||||
public class IntSummaryStatistics implements IntConsumer {
|
||||
private long count;
|
||||
private long sum;
|
||||
private int min = Integer.MAX_VALUE;
|
||||
private int max = Integer.MIN_VALUE;
|
||||
|
||||
/**
|
||||
* Construct an empty instance with zero count, zero sum,
|
||||
* {@code Integer.MAX_VALUE} min, {@code Integer.MIN_VALUE} max and zero
|
||||
* average.
|
||||
*/
|
||||
public IntSummaryStatistics() { }
|
||||
|
||||
/**
|
||||
* Records a new value into the summary information
|
||||
*
|
||||
* @param value the input value
|
||||
*/
|
||||
@Override
|
||||
public void accept(int value) {
|
||||
++count;
|
||||
sum += value;
|
||||
min = Math.min(min, value);
|
||||
max = Math.max(max, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines the state of another {@code IntSummaryStatistics} into this one.
|
||||
*
|
||||
* @param other another {@code IntSummaryStatistics}
|
||||
* @throws NullPointerException if {@code other} is null
|
||||
*/
|
||||
public void combine(IntSummaryStatistics other) {
|
||||
count += other.count;
|
||||
sum += other.sum;
|
||||
min = Math.min(min, other.min);
|
||||
max = Math.max(max, other.max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the count of values recorded.
|
||||
*
|
||||
* @return the count of values
|
||||
*/
|
||||
public final long getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of values recorded, or zero if no values have been
|
||||
* recorded.
|
||||
*
|
||||
* @return the sum of values, or zero if none
|
||||
*/
|
||||
public final long getSum() {
|
||||
return sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum value recorded, or {@code Integer.MAX_VALUE} if no
|
||||
* values have been recorded.
|
||||
*
|
||||
* @return the minimum value, or {@code Integer.MAX_VALUE} if none
|
||||
*/
|
||||
public final int getMin() {
|
||||
return min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum value recorded, or {@code Integer.MIN_VALUE} if no
|
||||
* values have been recorded.
|
||||
*
|
||||
* @return the maximum value, or {@code Integer.MIN_VALUE} if none
|
||||
*/
|
||||
public final int getMax() {
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the arithmetic mean of values recorded, or zero if no values have been
|
||||
* recorded.
|
||||
*
|
||||
* @return the arithmetic mean of values, or zero if none
|
||||
*/
|
||||
public final double getAverage() {
|
||||
return getCount() > 0 ? (double) getSum() / getCount() : 0.0d;
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* Returns a non-empty string representation of this object suitable for
|
||||
* debugging. The exact presentation format is unspecified and may vary
|
||||
* between implementations and versions.
|
||||
*/
|
||||
public String toString() {
|
||||
return String.format(
|
||||
"%s{count=%d, sum=%d, min=%d, average=%f, max=%d}",
|
||||
this.getClass().getSimpleName(),
|
||||
getCount(),
|
||||
getSum(),
|
||||
getMin(),
|
||||
getAverage(),
|
||||
getMax());
|
||||
}
|
||||
}
|
||||
93
jdkSrc/jdk8/java/util/InvalidPropertiesFormatException.java
Normal file
93
jdkSrc/jdk8/java/util/InvalidPropertiesFormatException.java
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
import java.io.NotSerializableException;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Thrown to indicate that an operation could not complete because
|
||||
* the input did not conform to the appropriate XML document type
|
||||
* for a collection of properties, as per the {@link Properties}
|
||||
* specification.<p>
|
||||
*
|
||||
* Note, that although InvalidPropertiesFormatException inherits Serializable
|
||||
* interface from Exception, it is not intended to be Serializable. Appropriate
|
||||
* serialization methods are implemented to throw NotSerializableException.
|
||||
*
|
||||
* @see Properties
|
||||
* @since 1.5
|
||||
* @serial exclude
|
||||
*/
|
||||
|
||||
public class InvalidPropertiesFormatException extends IOException {
|
||||
|
||||
private static final long serialVersionUID = 7763056076009360219L;
|
||||
|
||||
/**
|
||||
* Constructs an InvalidPropertiesFormatException with the specified
|
||||
* cause.
|
||||
*
|
||||
* @param cause the cause (which is saved for later retrieval by the
|
||||
* {@link Throwable#getCause()} method).
|
||||
*/
|
||||
public InvalidPropertiesFormatException(Throwable cause) {
|
||||
super(cause==null ? null : cause.toString());
|
||||
this.initCause(cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an InvalidPropertiesFormatException with the specified
|
||||
* detail message.
|
||||
*
|
||||
* @param message the detail message. The detail message is saved for
|
||||
* later retrieval by the {@link Throwable#getMessage()} method.
|
||||
*/
|
||||
public InvalidPropertiesFormatException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws NotSerializableException, since InvalidPropertiesFormatException
|
||||
* objects are not intended to be serializable.
|
||||
*/
|
||||
private void writeObject(java.io.ObjectOutputStream out)
|
||||
throws NotSerializableException
|
||||
{
|
||||
throw new NotSerializableException("Not serializable.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws NotSerializableException, since InvalidPropertiesFormatException
|
||||
* objects are not intended to be serializable.
|
||||
*/
|
||||
private void readObject(java.io.ObjectInputStream in)
|
||||
throws NotSerializableException
|
||||
{
|
||||
throw new NotSerializableException("Not serializable.");
|
||||
}
|
||||
|
||||
}
|
||||
118
jdkSrc/jdk8/java/util/Iterator.java
Normal file
118
jdkSrc/jdk8/java/util/Iterator.java
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* An iterator over a collection. {@code Iterator} takes the place of
|
||||
* {@link Enumeration} in the Java Collections Framework. Iterators
|
||||
* differ from enumerations in two ways:
|
||||
*
|
||||
* <ul>
|
||||
* <li> Iterators allow the caller to remove elements from the
|
||||
* underlying collection during the iteration with well-defined
|
||||
* semantics.
|
||||
* <li> Method names have been improved.
|
||||
* </ul>
|
||||
*
|
||||
* <p>This interface is a member of the
|
||||
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
|
||||
* Java Collections Framework</a>.
|
||||
*
|
||||
* @param <E> the type of elements returned by this iterator
|
||||
*
|
||||
* @author Josh Bloch
|
||||
* @see Collection
|
||||
* @see ListIterator
|
||||
* @see Iterable
|
||||
* @since 1.2
|
||||
*/
|
||||
public interface Iterator<E> {
|
||||
/**
|
||||
* Returns {@code true} if the iteration has more elements.
|
||||
* (In other words, returns {@code true} if {@link #next} would
|
||||
* return an element rather than throwing an exception.)
|
||||
*
|
||||
* @return {@code true} if the iteration has more elements
|
||||
*/
|
||||
boolean hasNext();
|
||||
|
||||
/**
|
||||
* Returns the next element in the iteration.
|
||||
*
|
||||
* @return the next element in the iteration
|
||||
* @throws NoSuchElementException if the iteration has no more elements
|
||||
*/
|
||||
E next();
|
||||
|
||||
/**
|
||||
* Removes from the underlying collection the last element returned
|
||||
* by this iterator (optional operation). This method can be called
|
||||
* only once per call to {@link #next}. The behavior of an iterator
|
||||
* is unspecified if the underlying collection is modified while the
|
||||
* iteration is in progress in any way other than by calling this
|
||||
* method.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation throws an instance of
|
||||
* {@link UnsupportedOperationException} and performs no other action.
|
||||
*
|
||||
* @throws UnsupportedOperationException if the {@code remove}
|
||||
* operation is not supported by this iterator
|
||||
*
|
||||
* @throws IllegalStateException if the {@code next} method has not
|
||||
* yet been called, or the {@code remove} method has already
|
||||
* been called after the last call to the {@code next}
|
||||
* method
|
||||
*/
|
||||
default void remove() {
|
||||
throw new UnsupportedOperationException("remove");
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the given action for each remaining element until all elements
|
||||
* have been processed or the action throws an exception. Actions are
|
||||
* performed in the order of iteration, if that order is specified.
|
||||
* Exceptions thrown by the action are relayed to the caller.
|
||||
*
|
||||
* @implSpec
|
||||
* <p>The default implementation behaves as if:
|
||||
* <pre>{@code
|
||||
* while (hasNext())
|
||||
* action.accept(next());
|
||||
* }</pre>
|
||||
*
|
||||
* @param action The action to be performed for each element
|
||||
* @throws NullPointerException if the specified action is null
|
||||
* @since 1.8
|
||||
*/
|
||||
default void forEachRemaining(Consumer<? super E> action) {
|
||||
Objects.requireNonNull(action);
|
||||
while (hasNext())
|
||||
action.accept(next());
|
||||
}
|
||||
}
|
||||
2374
jdkSrc/jdk8/java/util/JapaneseImperialCalendar.java
Normal file
2374
jdkSrc/jdk8/java/util/JapaneseImperialCalendar.java
Normal file
File diff suppressed because it is too large
Load Diff
379
jdkSrc/jdk8/java/util/JumboEnumSet.java
Normal file
379
jdkSrc/jdk8/java/util/JumboEnumSet.java
Normal file
@@ -0,0 +1,379 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* Private implementation class for EnumSet, for "jumbo" enum types
|
||||
* (i.e., those with more than 64 elements).
|
||||
*
|
||||
* @author Josh Bloch
|
||||
* @since 1.5
|
||||
* @serial exclude
|
||||
*/
|
||||
class JumboEnumSet<E extends Enum<E>> extends EnumSet<E> {
|
||||
private static final long serialVersionUID = 334349849919042784L;
|
||||
|
||||
/**
|
||||
* Bit vector representation of this set. The ith bit of the jth
|
||||
* element of this array represents the presence of universe[64*j +i]
|
||||
* in this set.
|
||||
*/
|
||||
private long elements[];
|
||||
|
||||
// Redundant - maintained for performance
|
||||
private int size = 0;
|
||||
|
||||
JumboEnumSet(Class<E>elementType, Enum<?>[] universe) {
|
||||
super(elementType, universe);
|
||||
elements = new long[(universe.length + 63) >>> 6];
|
||||
}
|
||||
|
||||
void addRange(E from, E to) {
|
||||
int fromIndex = from.ordinal() >>> 6;
|
||||
int toIndex = to.ordinal() >>> 6;
|
||||
|
||||
if (fromIndex == toIndex) {
|
||||
elements[fromIndex] = (-1L >>> (from.ordinal() - to.ordinal() - 1))
|
||||
<< from.ordinal();
|
||||
} else {
|
||||
elements[fromIndex] = (-1L << from.ordinal());
|
||||
for (int i = fromIndex + 1; i < toIndex; i++)
|
||||
elements[i] = -1;
|
||||
elements[toIndex] = -1L >>> (63 - to.ordinal());
|
||||
}
|
||||
size = to.ordinal() - from.ordinal() + 1;
|
||||
}
|
||||
|
||||
void addAll() {
|
||||
for (int i = 0; i < elements.length; i++)
|
||||
elements[i] = -1;
|
||||
elements[elements.length - 1] >>>= -universe.length;
|
||||
size = universe.length;
|
||||
}
|
||||
|
||||
void complement() {
|
||||
for (int i = 0; i < elements.length; i++)
|
||||
elements[i] = ~elements[i];
|
||||
elements[elements.length - 1] &= (-1L >>> -universe.length);
|
||||
size = universe.length - size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator over the elements contained in this set. The
|
||||
* iterator traverses the elements in their <i>natural order</i> (which is
|
||||
* the order in which the enum constants are declared). The returned
|
||||
* Iterator is a "weakly consistent" iterator that will never throw {@link
|
||||
* ConcurrentModificationException}.
|
||||
*
|
||||
* @return an iterator over the elements contained in this set
|
||||
*/
|
||||
public Iterator<E> iterator() {
|
||||
return new EnumSetIterator<>();
|
||||
}
|
||||
|
||||
private class EnumSetIterator<E extends Enum<E>> implements Iterator<E> {
|
||||
/**
|
||||
* A bit vector representing the elements in the current "word"
|
||||
* of the set not yet returned by this iterator.
|
||||
*/
|
||||
long unseen;
|
||||
|
||||
/**
|
||||
* The index corresponding to unseen in the elements array.
|
||||
*/
|
||||
int unseenIndex = 0;
|
||||
|
||||
/**
|
||||
* The bit representing the last element returned by this iterator
|
||||
* but not removed, or zero if no such element exists.
|
||||
*/
|
||||
long lastReturned = 0;
|
||||
|
||||
/**
|
||||
* The index corresponding to lastReturned in the elements array.
|
||||
*/
|
||||
int lastReturnedIndex = 0;
|
||||
|
||||
EnumSetIterator() {
|
||||
unseen = elements[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
while (unseen == 0 && unseenIndex < elements.length - 1)
|
||||
unseen = elements[++unseenIndex];
|
||||
return unseen != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public E next() {
|
||||
if (!hasNext())
|
||||
throw new NoSuchElementException();
|
||||
lastReturned = unseen & -unseen;
|
||||
lastReturnedIndex = unseenIndex;
|
||||
unseen -= lastReturned;
|
||||
return (E) universe[(lastReturnedIndex << 6)
|
||||
+ Long.numberOfTrailingZeros(lastReturned)];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
if (lastReturned == 0)
|
||||
throw new IllegalStateException();
|
||||
final long oldElements = elements[lastReturnedIndex];
|
||||
elements[lastReturnedIndex] &= ~lastReturned;
|
||||
if (oldElements != elements[lastReturnedIndex]) {
|
||||
size--;
|
||||
}
|
||||
lastReturned = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of elements in this set.
|
||||
*
|
||||
* @return the number of elements in this set
|
||||
*/
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this set contains no elements.
|
||||
*
|
||||
* @return <tt>true</tt> if this set contains no elements
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return size == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this set contains the specified element.
|
||||
*
|
||||
* @param e element to be checked for containment in this collection
|
||||
* @return <tt>true</tt> if this set contains the specified element
|
||||
*/
|
||||
public boolean contains(Object e) {
|
||||
if (e == null)
|
||||
return false;
|
||||
Class<?> eClass = e.getClass();
|
||||
if (eClass != elementType && eClass.getSuperclass() != elementType)
|
||||
return false;
|
||||
|
||||
int eOrdinal = ((Enum<?>)e).ordinal();
|
||||
return (elements[eOrdinal >>> 6] & (1L << eOrdinal)) != 0;
|
||||
}
|
||||
|
||||
// Modification Operations
|
||||
|
||||
/**
|
||||
* Adds the specified element to this set if it is not already present.
|
||||
*
|
||||
* @param e element to be added to this set
|
||||
* @return <tt>true</tt> if the set changed as a result of the call
|
||||
*
|
||||
* @throws NullPointerException if <tt>e</tt> is null
|
||||
*/
|
||||
public boolean add(E e) {
|
||||
typeCheck(e);
|
||||
|
||||
int eOrdinal = e.ordinal();
|
||||
int eWordNum = eOrdinal >>> 6;
|
||||
|
||||
long oldElements = elements[eWordNum];
|
||||
elements[eWordNum] |= (1L << eOrdinal);
|
||||
boolean result = (elements[eWordNum] != oldElements);
|
||||
if (result)
|
||||
size++;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified element from this set if it is present.
|
||||
*
|
||||
* @param e element to be removed from this set, if present
|
||||
* @return <tt>true</tt> if the set contained the specified element
|
||||
*/
|
||||
public boolean remove(Object e) {
|
||||
if (e == null)
|
||||
return false;
|
||||
Class<?> eClass = e.getClass();
|
||||
if (eClass != elementType && eClass.getSuperclass() != elementType)
|
||||
return false;
|
||||
int eOrdinal = ((Enum<?>)e).ordinal();
|
||||
int eWordNum = eOrdinal >>> 6;
|
||||
|
||||
long oldElements = elements[eWordNum];
|
||||
elements[eWordNum] &= ~(1L << eOrdinal);
|
||||
boolean result = (elements[eWordNum] != oldElements);
|
||||
if (result)
|
||||
size--;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Bulk Operations
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this set contains all of the elements
|
||||
* in the specified collection.
|
||||
*
|
||||
* @param c collection to be checked for containment in this set
|
||||
* @return <tt>true</tt> if this set contains all of the elements
|
||||
* in the specified collection
|
||||
* @throws NullPointerException if the specified collection is null
|
||||
*/
|
||||
public boolean containsAll(Collection<?> c) {
|
||||
if (!(c instanceof JumboEnumSet))
|
||||
return super.containsAll(c);
|
||||
|
||||
JumboEnumSet<?> es = (JumboEnumSet<?>)c;
|
||||
if (es.elementType != elementType)
|
||||
return es.isEmpty();
|
||||
|
||||
for (int i = 0; i < elements.length; i++)
|
||||
if ((es.elements[i] & ~elements[i]) != 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all of the elements in the specified collection to this set.
|
||||
*
|
||||
* @param c collection whose elements are to be added to this set
|
||||
* @return <tt>true</tt> if this set changed as a result of the call
|
||||
* @throws NullPointerException if the specified collection or any of
|
||||
* its elements are null
|
||||
*/
|
||||
public boolean addAll(Collection<? extends E> c) {
|
||||
if (!(c instanceof JumboEnumSet))
|
||||
return super.addAll(c);
|
||||
|
||||
JumboEnumSet<?> es = (JumboEnumSet<?>)c;
|
||||
if (es.elementType != elementType) {
|
||||
if (es.isEmpty())
|
||||
return false;
|
||||
else
|
||||
throw new ClassCastException(
|
||||
es.elementType + " != " + elementType);
|
||||
}
|
||||
|
||||
for (int i = 0; i < elements.length; i++)
|
||||
elements[i] |= es.elements[i];
|
||||
return recalculateSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes from this set all of its elements that are contained in
|
||||
* the specified collection.
|
||||
*
|
||||
* @param c elements to be removed from this set
|
||||
* @return <tt>true</tt> if this set changed as a result of the call
|
||||
* @throws NullPointerException if the specified collection is null
|
||||
*/
|
||||
public boolean removeAll(Collection<?> c) {
|
||||
if (!(c instanceof JumboEnumSet))
|
||||
return super.removeAll(c);
|
||||
|
||||
JumboEnumSet<?> es = (JumboEnumSet<?>)c;
|
||||
if (es.elementType != elementType)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < elements.length; i++)
|
||||
elements[i] &= ~es.elements[i];
|
||||
return recalculateSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retains only the elements in this set that are contained in the
|
||||
* specified collection.
|
||||
*
|
||||
* @param c elements to be retained in this set
|
||||
* @return <tt>true</tt> if this set changed as a result of the call
|
||||
* @throws NullPointerException if the specified collection is null
|
||||
*/
|
||||
public boolean retainAll(Collection<?> c) {
|
||||
if (!(c instanceof JumboEnumSet))
|
||||
return super.retainAll(c);
|
||||
|
||||
JumboEnumSet<?> es = (JumboEnumSet<?>)c;
|
||||
if (es.elementType != elementType) {
|
||||
boolean changed = (size != 0);
|
||||
clear();
|
||||
return changed;
|
||||
}
|
||||
|
||||
for (int i = 0; i < elements.length; i++)
|
||||
elements[i] &= es.elements[i];
|
||||
return recalculateSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all of the elements from this set.
|
||||
*/
|
||||
public void clear() {
|
||||
Arrays.fill(elements, 0);
|
||||
size = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the specified object with this set for equality. Returns
|
||||
* <tt>true</tt> if the given object is also a set, the two sets have
|
||||
* the same size, and every member of the given set is contained in
|
||||
* this set.
|
||||
*
|
||||
* @param o object to be compared for equality with this set
|
||||
* @return <tt>true</tt> if the specified object is equal to this set
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof JumboEnumSet))
|
||||
return super.equals(o);
|
||||
|
||||
JumboEnumSet<?> es = (JumboEnumSet<?>)o;
|
||||
if (es.elementType != elementType)
|
||||
return size == 0 && es.size == 0;
|
||||
|
||||
return Arrays.equals(es.elements, elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recalculates the size of the set. Returns true if it's changed.
|
||||
*/
|
||||
private boolean recalculateSize() {
|
||||
int oldSize = size;
|
||||
size = 0;
|
||||
for (long elt : elements)
|
||||
size += Long.bitCount(elt);
|
||||
|
||||
return size != oldSize;
|
||||
}
|
||||
|
||||
public EnumSet<E> clone() {
|
||||
JumboEnumSet<E> result = (JumboEnumSet<E>) super.clone();
|
||||
result.elements = result.elements.clone();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
756
jdkSrc/jdk8/java/util/LinkedHashMap.java
Normal file
756
jdkSrc/jdk8/java/util/LinkedHashMap.java
Normal file
@@ -0,0 +1,756 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* <p>Hash table and linked list implementation of the <tt>Map</tt> interface,
|
||||
* with predictable iteration order. This implementation differs from
|
||||
* <tt>HashMap</tt> in that it maintains a doubly-linked list running through
|
||||
* all of its entries. This linked list defines the iteration ordering,
|
||||
* which is normally the order in which keys were inserted into the map
|
||||
* (<i>insertion-order</i>). Note that insertion order is not affected
|
||||
* if a key is <i>re-inserted</i> into the map. (A key <tt>k</tt> is
|
||||
* reinserted into a map <tt>m</tt> if <tt>m.put(k, v)</tt> is invoked when
|
||||
* <tt>m.containsKey(k)</tt> would return <tt>true</tt> immediately prior to
|
||||
* the invocation.)
|
||||
*
|
||||
* <p>This implementation spares its clients from the unspecified, generally
|
||||
* chaotic ordering provided by {@link HashMap} (and {@link Hashtable}),
|
||||
* without incurring the increased cost associated with {@link TreeMap}. It
|
||||
* can be used to produce a copy of a map that has the same order as the
|
||||
* original, regardless of the original map's implementation:
|
||||
* <pre>
|
||||
* void foo(Map m) {
|
||||
* Map copy = new LinkedHashMap(m);
|
||||
* ...
|
||||
* }
|
||||
* </pre>
|
||||
* This technique is particularly useful if a module takes a map on input,
|
||||
* copies it, and later returns results whose order is determined by that of
|
||||
* the copy. (Clients generally appreciate having things returned in the same
|
||||
* order they were presented.)
|
||||
*
|
||||
* <p>A special {@link #LinkedHashMap(int,float,boolean) constructor} is
|
||||
* provided to create a linked hash map whose order of iteration is the order
|
||||
* in which its entries were last accessed, from least-recently accessed to
|
||||
* most-recently (<i>access-order</i>). This kind of map is well-suited to
|
||||
* building LRU caches. Invoking the {@code put}, {@code putIfAbsent},
|
||||
* {@code get}, {@code getOrDefault}, {@code compute}, {@code computeIfAbsent},
|
||||
* {@code computeIfPresent}, or {@code merge} methods results
|
||||
* in an access to the corresponding entry (assuming it exists after the
|
||||
* invocation completes). The {@code replace} methods only result in an access
|
||||
* of the entry if the value is replaced. The {@code putAll} method generates one
|
||||
* entry access for each mapping in the specified map, in the order that
|
||||
* key-value mappings are provided by the specified map's entry set iterator.
|
||||
* <i>No other methods generate entry accesses.</i> In particular, operations
|
||||
* on collection-views do <i>not</i> affect the order of iteration of the
|
||||
* backing map.
|
||||
*
|
||||
* <p>The {@link #removeEldestEntry(Map.Entry)} method may be overridden to
|
||||
* impose a policy for removing stale mappings automatically when new mappings
|
||||
* are added to the map.
|
||||
*
|
||||
* <p>This class provides all of the optional <tt>Map</tt> operations, and
|
||||
* permits null elements. Like <tt>HashMap</tt>, it provides constant-time
|
||||
* performance for the basic operations (<tt>add</tt>, <tt>contains</tt> and
|
||||
* <tt>remove</tt>), assuming the hash function disperses elements
|
||||
* properly among the buckets. Performance is likely to be just slightly
|
||||
* below that of <tt>HashMap</tt>, due to the added expense of maintaining the
|
||||
* linked list, with one exception: Iteration over the collection-views
|
||||
* of a <tt>LinkedHashMap</tt> requires time proportional to the <i>size</i>
|
||||
* of the map, regardless of its capacity. Iteration over a <tt>HashMap</tt>
|
||||
* is likely to be more expensive, requiring time proportional to its
|
||||
* <i>capacity</i>.
|
||||
*
|
||||
* <p>A linked hash map has two parameters that affect its performance:
|
||||
* <i>initial capacity</i> and <i>load factor</i>. They are defined precisely
|
||||
* as for <tt>HashMap</tt>. Note, however, that the penalty for choosing an
|
||||
* excessively high value for initial capacity is less severe for this class
|
||||
* than for <tt>HashMap</tt>, as iteration times for this class are unaffected
|
||||
* by capacity.
|
||||
*
|
||||
* <p><strong>Note that this implementation is not synchronized.</strong>
|
||||
* If multiple threads access a linked hash map concurrently, and at least
|
||||
* one of the threads modifies the map structurally, it <em>must</em> be
|
||||
* synchronized externally. This is typically accomplished by
|
||||
* synchronizing on some object that naturally encapsulates the map.
|
||||
*
|
||||
* If no such object exists, the map should be "wrapped" using the
|
||||
* {@link Collections#synchronizedMap Collections.synchronizedMap}
|
||||
* method. This is best done at creation time, to prevent accidental
|
||||
* unsynchronized access to the map:<pre>
|
||||
* Map m = Collections.synchronizedMap(new LinkedHashMap(...));</pre>
|
||||
*
|
||||
* A structural modification is any operation that adds or deletes one or more
|
||||
* mappings or, in the case of access-ordered linked hash maps, affects
|
||||
* iteration order. In insertion-ordered linked hash maps, merely changing
|
||||
* the value associated with a key that is already contained in the map is not
|
||||
* a structural modification. <strong>In access-ordered linked hash maps,
|
||||
* merely querying the map with <tt>get</tt> is a structural modification.
|
||||
* </strong>)
|
||||
*
|
||||
* <p>The iterators returned by the <tt>iterator</tt> method of the collections
|
||||
* returned by all of this class's collection view methods are
|
||||
* <em>fail-fast</em>: if the map is structurally modified at any time after
|
||||
* the iterator is created, in any way except through the iterator's own
|
||||
* <tt>remove</tt> method, the iterator will throw a {@link
|
||||
* ConcurrentModificationException}. Thus, in the face of concurrent
|
||||
* modification, the iterator fails quickly and cleanly, rather than risking
|
||||
* arbitrary, non-deterministic behavior at an undetermined time in the future.
|
||||
*
|
||||
* <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
|
||||
* as it is, generally speaking, impossible to make any hard guarantees in the
|
||||
* presence of unsynchronized concurrent modification. Fail-fast iterators
|
||||
* throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
|
||||
* Therefore, it would be wrong to write a program that depended on this
|
||||
* exception for its correctness: <i>the fail-fast behavior of iterators
|
||||
* should be used only to detect bugs.</i>
|
||||
*
|
||||
* <p>The spliterators returned by the spliterator method of the collections
|
||||
* returned by all of this class's collection view methods are
|
||||
* <em><a href="Spliterator.html#binding">late-binding</a></em>,
|
||||
* <em>fail-fast</em>, and additionally report {@link Spliterator#ORDERED}.
|
||||
*
|
||||
* <p>This class is a member of the
|
||||
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
|
||||
* Java Collections Framework</a>.
|
||||
*
|
||||
* @implNote
|
||||
* The spliterators returned by the spliterator method of the collections
|
||||
* returned by all of this class's collection view methods are created from
|
||||
* the iterators of the corresponding collections.
|
||||
*
|
||||
* @param <K> the type of keys maintained by this map
|
||||
* @param <V> the type of mapped values
|
||||
*
|
||||
* @author Josh Bloch
|
||||
* @see Object#hashCode()
|
||||
* @see Collection
|
||||
* @see Map
|
||||
* @see HashMap
|
||||
* @see TreeMap
|
||||
* @see Hashtable
|
||||
* @since 1.4
|
||||
*/
|
||||
public class LinkedHashMap<K,V>
|
||||
extends HashMap<K,V>
|
||||
implements Map<K,V>
|
||||
{
|
||||
|
||||
/*
|
||||
* Implementation note. A previous version of this class was
|
||||
* internally structured a little differently. Because superclass
|
||||
* HashMap now uses trees for some of its nodes, class
|
||||
* LinkedHashMap.Entry is now treated as intermediary node class
|
||||
* that can also be converted to tree form. The name of this
|
||||
* class, LinkedHashMap.Entry, is confusing in several ways in its
|
||||
* current context, but cannot be changed. Otherwise, even though
|
||||
* it is not exported outside this package, some existing source
|
||||
* code is known to have relied on a symbol resolution corner case
|
||||
* rule in calls to removeEldestEntry that suppressed compilation
|
||||
* errors due to ambiguous usages. So, we keep the name to
|
||||
* preserve unmodified compilability.
|
||||
*
|
||||
* The changes in node classes also require using two fields
|
||||
* (head, tail) rather than a pointer to a header node to maintain
|
||||
* the doubly-linked before/after list. This class also
|
||||
* previously used a different style of callback methods upon
|
||||
* access, insertion, and removal.
|
||||
*/
|
||||
|
||||
/**
|
||||
* HashMap.Node subclass for normal LinkedHashMap entries.
|
||||
*/
|
||||
static class Entry<K,V> extends HashMap.Node<K,V> {
|
||||
Entry<K,V> before, after;
|
||||
Entry(int hash, K key, V value, Node<K,V> next) {
|
||||
super(hash, key, value, next);
|
||||
}
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 3801124242820219131L;
|
||||
|
||||
/**
|
||||
* The head (eldest) of the doubly linked list.
|
||||
*/
|
||||
transient LinkedHashMap.Entry<K,V> head;
|
||||
|
||||
/**
|
||||
* The tail (youngest) of the doubly linked list.
|
||||
*/
|
||||
transient LinkedHashMap.Entry<K,V> tail;
|
||||
|
||||
/**
|
||||
* The iteration ordering method for this linked hash map: <tt>true</tt>
|
||||
* for access-order, <tt>false</tt> for insertion-order.
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
final boolean accessOrder;
|
||||
|
||||
// internal utilities
|
||||
|
||||
// link at the end of list
|
||||
private void linkNodeLast(LinkedHashMap.Entry<K,V> p) {
|
||||
LinkedHashMap.Entry<K,V> last = tail;
|
||||
tail = p;
|
||||
if (last == null)
|
||||
head = p;
|
||||
else {
|
||||
p.before = last;
|
||||
last.after = p;
|
||||
}
|
||||
}
|
||||
|
||||
// apply src's links to dst
|
||||
private void transferLinks(LinkedHashMap.Entry<K,V> src,
|
||||
LinkedHashMap.Entry<K,V> dst) {
|
||||
LinkedHashMap.Entry<K,V> b = dst.before = src.before;
|
||||
LinkedHashMap.Entry<K,V> a = dst.after = src.after;
|
||||
if (b == null)
|
||||
head = dst;
|
||||
else
|
||||
b.after = dst;
|
||||
if (a == null)
|
||||
tail = dst;
|
||||
else
|
||||
a.before = dst;
|
||||
}
|
||||
|
||||
// overrides of HashMap hook methods
|
||||
|
||||
void reinitialize() {
|
||||
super.reinitialize();
|
||||
head = tail = null;
|
||||
}
|
||||
|
||||
Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) {
|
||||
LinkedHashMap.Entry<K,V> p =
|
||||
new LinkedHashMap.Entry<K,V>(hash, key, value, e);
|
||||
linkNodeLast(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
Node<K,V> replacementNode(Node<K,V> p, Node<K,V> next) {
|
||||
LinkedHashMap.Entry<K,V> q = (LinkedHashMap.Entry<K,V>)p;
|
||||
LinkedHashMap.Entry<K,V> t =
|
||||
new LinkedHashMap.Entry<K,V>(q.hash, q.key, q.value, next);
|
||||
transferLinks(q, t);
|
||||
return t;
|
||||
}
|
||||
|
||||
TreeNode<K,V> newTreeNode(int hash, K key, V value, Node<K,V> next) {
|
||||
TreeNode<K,V> p = new TreeNode<K,V>(hash, key, value, next);
|
||||
linkNodeLast(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
TreeNode<K,V> replacementTreeNode(Node<K,V> p, Node<K,V> next) {
|
||||
LinkedHashMap.Entry<K,V> q = (LinkedHashMap.Entry<K,V>)p;
|
||||
TreeNode<K,V> t = new TreeNode<K,V>(q.hash, q.key, q.value, next);
|
||||
transferLinks(q, t);
|
||||
return t;
|
||||
}
|
||||
|
||||
void afterNodeRemoval(Node<K,V> e) { // unlink
|
||||
LinkedHashMap.Entry<K,V> p =
|
||||
(LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;
|
||||
p.before = p.after = null;
|
||||
if (b == null)
|
||||
head = a;
|
||||
else
|
||||
b.after = a;
|
||||
if (a == null)
|
||||
tail = b;
|
||||
else
|
||||
a.before = b;
|
||||
}
|
||||
|
||||
void afterNodeInsertion(boolean evict) { // possibly remove eldest
|
||||
LinkedHashMap.Entry<K,V> first;
|
||||
if (evict && (first = head) != null && removeEldestEntry(first)) {
|
||||
K key = first.key;
|
||||
removeNode(hash(key), key, null, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
void afterNodeAccess(Node<K,V> e) { // move node to last
|
||||
LinkedHashMap.Entry<K,V> last;
|
||||
if (accessOrder && (last = tail) != e) {
|
||||
LinkedHashMap.Entry<K,V> p =
|
||||
(LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;
|
||||
p.after = null;
|
||||
if (b == null)
|
||||
head = a;
|
||||
else
|
||||
b.after = a;
|
||||
if (a != null)
|
||||
a.before = b;
|
||||
else
|
||||
last = b;
|
||||
if (last == null)
|
||||
head = p;
|
||||
else {
|
||||
p.before = last;
|
||||
last.after = p;
|
||||
}
|
||||
tail = p;
|
||||
++modCount;
|
||||
}
|
||||
}
|
||||
|
||||
void internalWriteEntries(java.io.ObjectOutputStream s) throws IOException {
|
||||
for (LinkedHashMap.Entry<K,V> e = head; e != null; e = e.after) {
|
||||
s.writeObject(e.key);
|
||||
s.writeObject(e.value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an empty insertion-ordered <tt>LinkedHashMap</tt> instance
|
||||
* with the specified initial capacity and load factor.
|
||||
*
|
||||
* @param initialCapacity the initial capacity
|
||||
* @param loadFactor the load factor
|
||||
* @throws IllegalArgumentException if the initial capacity is negative
|
||||
* or the load factor is nonpositive
|
||||
*/
|
||||
public LinkedHashMap(int initialCapacity, float loadFactor) {
|
||||
super(initialCapacity, loadFactor);
|
||||
accessOrder = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an empty insertion-ordered <tt>LinkedHashMap</tt> instance
|
||||
* with the specified initial capacity and a default load factor (0.75).
|
||||
*
|
||||
* @param initialCapacity the initial capacity
|
||||
* @throws IllegalArgumentException if the initial capacity is negative
|
||||
*/
|
||||
public LinkedHashMap(int initialCapacity) {
|
||||
super(initialCapacity);
|
||||
accessOrder = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an empty insertion-ordered <tt>LinkedHashMap</tt> instance
|
||||
* with the default initial capacity (16) and load factor (0.75).
|
||||
*/
|
||||
public LinkedHashMap() {
|
||||
super();
|
||||
accessOrder = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an insertion-ordered <tt>LinkedHashMap</tt> instance with
|
||||
* the same mappings as the specified map. The <tt>LinkedHashMap</tt>
|
||||
* instance is created with a default load factor (0.75) and an initial
|
||||
* capacity sufficient to hold the mappings in the specified map.
|
||||
*
|
||||
* @param m the map whose mappings are to be placed in this map
|
||||
* @throws NullPointerException if the specified map is null
|
||||
*/
|
||||
public LinkedHashMap(Map<? extends K, ? extends V> m) {
|
||||
super();
|
||||
accessOrder = false;
|
||||
putMapEntries(m, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an empty <tt>LinkedHashMap</tt> instance with the
|
||||
* specified initial capacity, load factor and ordering mode.
|
||||
*
|
||||
* @param initialCapacity the initial capacity
|
||||
* @param loadFactor the load factor
|
||||
* @param accessOrder the ordering mode - <tt>true</tt> for
|
||||
* access-order, <tt>false</tt> for insertion-order
|
||||
* @throws IllegalArgumentException if the initial capacity is negative
|
||||
* or the load factor is nonpositive
|
||||
*/
|
||||
public LinkedHashMap(int initialCapacity,
|
||||
float loadFactor,
|
||||
boolean accessOrder) {
|
||||
super(initialCapacity, loadFactor);
|
||||
this.accessOrder = accessOrder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this map maps one or more keys to the
|
||||
* specified value.
|
||||
*
|
||||
* @param value value whose presence in this map is to be tested
|
||||
* @return <tt>true</tt> if this map maps one or more keys to the
|
||||
* specified value
|
||||
*/
|
||||
public boolean containsValue(Object value) {
|
||||
for (LinkedHashMap.Entry<K,V> e = head; e != null; e = e.after) {
|
||||
V v = e.value;
|
||||
if (v == value || (value != null && value.equals(v)))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value to which the specified key is mapped,
|
||||
* or {@code null} if this map contains no mapping for the key.
|
||||
*
|
||||
* <p>More formally, if this map contains a mapping from a key
|
||||
* {@code k} to a value {@code v} such that {@code (key==null ? k==null :
|
||||
* key.equals(k))}, then this method returns {@code v}; otherwise
|
||||
* it returns {@code null}. (There can be at most one such mapping.)
|
||||
*
|
||||
* <p>A return value of {@code null} does not <i>necessarily</i>
|
||||
* indicate that the map contains no mapping for the key; it's also
|
||||
* possible that the map explicitly maps the key to {@code null}.
|
||||
* The {@link #containsKey containsKey} operation may be used to
|
||||
* distinguish these two cases.
|
||||
*/
|
||||
public V get(Object key) {
|
||||
Node<K,V> e;
|
||||
if ((e = getNode(hash(key), key)) == null)
|
||||
return null;
|
||||
if (accessOrder)
|
||||
afterNodeAccess(e);
|
||||
return e.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public V getOrDefault(Object key, V defaultValue) {
|
||||
Node<K,V> e;
|
||||
if ((e = getNode(hash(key), key)) == null)
|
||||
return defaultValue;
|
||||
if (accessOrder)
|
||||
afterNodeAccess(e);
|
||||
return e.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void clear() {
|
||||
super.clear();
|
||||
head = tail = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this map should remove its eldest entry.
|
||||
* This method is invoked by <tt>put</tt> and <tt>putAll</tt> after
|
||||
* inserting a new entry into the map. It provides the implementor
|
||||
* with the opportunity to remove the eldest entry each time a new one
|
||||
* is added. This is useful if the map represents a cache: it allows
|
||||
* the map to reduce memory consumption by deleting stale entries.
|
||||
*
|
||||
* <p>Sample use: this override will allow the map to grow up to 100
|
||||
* entries and then delete the eldest entry each time a new entry is
|
||||
* added, maintaining a steady state of 100 entries.
|
||||
* <pre>
|
||||
* private static final int MAX_ENTRIES = 100;
|
||||
*
|
||||
* protected boolean removeEldestEntry(Map.Entry eldest) {
|
||||
* return size() > MAX_ENTRIES;
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p>This method typically does not modify the map in any way,
|
||||
* instead allowing the map to modify itself as directed by its
|
||||
* return value. It <i>is</i> permitted for this method to modify
|
||||
* the map directly, but if it does so, it <i>must</i> return
|
||||
* <tt>false</tt> (indicating that the map should not attempt any
|
||||
* further modification). The effects of returning <tt>true</tt>
|
||||
* after modifying the map from within this method are unspecified.
|
||||
*
|
||||
* <p>This implementation merely returns <tt>false</tt> (so that this
|
||||
* map acts like a normal map - the eldest element is never removed).
|
||||
*
|
||||
* @param eldest The least recently inserted entry in the map, or if
|
||||
* this is an access-ordered map, the least recently accessed
|
||||
* entry. This is the entry that will be removed it this
|
||||
* method returns <tt>true</tt>. If the map was empty prior
|
||||
* to the <tt>put</tt> or <tt>putAll</tt> invocation resulting
|
||||
* in this invocation, this will be the entry that was just
|
||||
* inserted; in other words, if the map contains a single
|
||||
* entry, the eldest entry is also the newest.
|
||||
* @return <tt>true</tt> if the eldest entry should be removed
|
||||
* from the map; <tt>false</tt> if it should be retained.
|
||||
*/
|
||||
protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Set} view of the keys contained in this map.
|
||||
* The set is backed by the map, so changes to the map are
|
||||
* reflected in the set, and vice-versa. If the map is modified
|
||||
* while an iteration over the set is in progress (except through
|
||||
* the iterator's own <tt>remove</tt> operation), the results of
|
||||
* the iteration are undefined. The set supports element removal,
|
||||
* which removes the corresponding mapping from the map, via the
|
||||
* <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
|
||||
* <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt>
|
||||
* operations. It does not support the <tt>add</tt> or <tt>addAll</tt>
|
||||
* operations.
|
||||
* Its {@link Spliterator} typically provides faster sequential
|
||||
* performance but much poorer parallel performance than that of
|
||||
* {@code HashMap}.
|
||||
*
|
||||
* @return a set view of the keys contained in this map
|
||||
*/
|
||||
public Set<K> keySet() {
|
||||
Set<K> ks = keySet;
|
||||
if (ks == null) {
|
||||
ks = new LinkedKeySet();
|
||||
keySet = ks;
|
||||
}
|
||||
return ks;
|
||||
}
|
||||
|
||||
final class LinkedKeySet extends AbstractSet<K> {
|
||||
public final int size() { return size; }
|
||||
public final void clear() { LinkedHashMap.this.clear(); }
|
||||
public final Iterator<K> iterator() {
|
||||
return new LinkedKeyIterator();
|
||||
}
|
||||
public final boolean contains(Object o) { return containsKey(o); }
|
||||
public final boolean remove(Object key) {
|
||||
return removeNode(hash(key), key, null, false, true) != null;
|
||||
}
|
||||
public final Spliterator<K> spliterator() {
|
||||
return Spliterators.spliterator(this, Spliterator.SIZED |
|
||||
Spliterator.ORDERED |
|
||||
Spliterator.DISTINCT);
|
||||
}
|
||||
public final void forEach(Consumer<? super K> action) {
|
||||
if (action == null)
|
||||
throw new NullPointerException();
|
||||
int mc = modCount;
|
||||
for (LinkedHashMap.Entry<K,V> e = head; e != null; e = e.after)
|
||||
action.accept(e.key);
|
||||
if (modCount != mc)
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Collection} view of the values contained in this map.
|
||||
* The collection is backed by the map, so changes to the map are
|
||||
* reflected in the collection, and vice-versa. If the map is
|
||||
* modified while an iteration over the collection is in progress
|
||||
* (except through the iterator's own <tt>remove</tt> operation),
|
||||
* the results of the iteration are undefined. The collection
|
||||
* supports element removal, which removes the corresponding
|
||||
* mapping from the map, via the <tt>Iterator.remove</tt>,
|
||||
* <tt>Collection.remove</tt>, <tt>removeAll</tt>,
|
||||
* <tt>retainAll</tt> and <tt>clear</tt> operations. It does not
|
||||
* support the <tt>add</tt> or <tt>addAll</tt> operations.
|
||||
* Its {@link Spliterator} typically provides faster sequential
|
||||
* performance but much poorer parallel performance than that of
|
||||
* {@code HashMap}.
|
||||
*
|
||||
* @return a view of the values contained in this map
|
||||
*/
|
||||
public Collection<V> values() {
|
||||
Collection<V> vs = values;
|
||||
if (vs == null) {
|
||||
vs = new LinkedValues();
|
||||
values = vs;
|
||||
}
|
||||
return vs;
|
||||
}
|
||||
|
||||
final class LinkedValues extends AbstractCollection<V> {
|
||||
public final int size() { return size; }
|
||||
public final void clear() { LinkedHashMap.this.clear(); }
|
||||
public final Iterator<V> iterator() {
|
||||
return new LinkedValueIterator();
|
||||
}
|
||||
public final boolean contains(Object o) { return containsValue(o); }
|
||||
public final Spliterator<V> spliterator() {
|
||||
return Spliterators.spliterator(this, Spliterator.SIZED |
|
||||
Spliterator.ORDERED);
|
||||
}
|
||||
public final void forEach(Consumer<? super V> action) {
|
||||
if (action == null)
|
||||
throw new NullPointerException();
|
||||
int mc = modCount;
|
||||
for (LinkedHashMap.Entry<K,V> e = head; e != null; e = e.after)
|
||||
action.accept(e.value);
|
||||
if (modCount != mc)
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Set} view of the mappings contained in this map.
|
||||
* The set is backed by the map, so changes to the map are
|
||||
* reflected in the set, and vice-versa. If the map is modified
|
||||
* while an iteration over the set is in progress (except through
|
||||
* the iterator's own <tt>remove</tt> operation, or through the
|
||||
* <tt>setValue</tt> operation on a map entry returned by the
|
||||
* iterator) the results of the iteration are undefined. The set
|
||||
* supports element removal, which removes the corresponding
|
||||
* mapping from the map, via the <tt>Iterator.remove</tt>,
|
||||
* <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt> and
|
||||
* <tt>clear</tt> operations. It does not support the
|
||||
* <tt>add</tt> or <tt>addAll</tt> operations.
|
||||
* Its {@link Spliterator} typically provides faster sequential
|
||||
* performance but much poorer parallel performance than that of
|
||||
* {@code HashMap}.
|
||||
*
|
||||
* @return a set view of the mappings contained in this map
|
||||
*/
|
||||
public Set<Map.Entry<K,V>> entrySet() {
|
||||
Set<Map.Entry<K,V>> es;
|
||||
return (es = entrySet) == null ? (entrySet = new LinkedEntrySet()) : es;
|
||||
}
|
||||
|
||||
final class LinkedEntrySet extends AbstractSet<Map.Entry<K,V>> {
|
||||
public final int size() { return size; }
|
||||
public final void clear() { LinkedHashMap.this.clear(); }
|
||||
public final Iterator<Map.Entry<K,V>> iterator() {
|
||||
return new LinkedEntryIterator();
|
||||
}
|
||||
public final boolean contains(Object o) {
|
||||
if (!(o instanceof Map.Entry))
|
||||
return false;
|
||||
Map.Entry<?,?> e = (Map.Entry<?,?>) o;
|
||||
Object key = e.getKey();
|
||||
Node<K,V> candidate = getNode(hash(key), key);
|
||||
return candidate != null && candidate.equals(e);
|
||||
}
|
||||
public final boolean remove(Object o) {
|
||||
if (o instanceof Map.Entry) {
|
||||
Map.Entry<?,?> e = (Map.Entry<?,?>) o;
|
||||
Object key = e.getKey();
|
||||
Object value = e.getValue();
|
||||
return removeNode(hash(key), key, value, true, true) != null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public final Spliterator<Map.Entry<K,V>> spliterator() {
|
||||
return Spliterators.spliterator(this, Spliterator.SIZED |
|
||||
Spliterator.ORDERED |
|
||||
Spliterator.DISTINCT);
|
||||
}
|
||||
public final void forEach(Consumer<? super Map.Entry<K,V>> action) {
|
||||
if (action == null)
|
||||
throw new NullPointerException();
|
||||
int mc = modCount;
|
||||
for (LinkedHashMap.Entry<K,V> e = head; e != null; e = e.after)
|
||||
action.accept(e);
|
||||
if (modCount != mc)
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
}
|
||||
|
||||
// Map overrides
|
||||
|
||||
public void forEach(BiConsumer<? super K, ? super V> action) {
|
||||
if (action == null)
|
||||
throw new NullPointerException();
|
||||
int mc = modCount;
|
||||
for (LinkedHashMap.Entry<K,V> e = head; e != null; e = e.after)
|
||||
action.accept(e.key, e.value);
|
||||
if (modCount != mc)
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
|
||||
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
|
||||
if (function == null)
|
||||
throw new NullPointerException();
|
||||
int mc = modCount;
|
||||
for (LinkedHashMap.Entry<K,V> e = head; e != null; e = e.after)
|
||||
e.value = function.apply(e.key, e.value);
|
||||
if (modCount != mc)
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
|
||||
// Iterators
|
||||
|
||||
abstract class LinkedHashIterator {
|
||||
LinkedHashMap.Entry<K,V> next;
|
||||
LinkedHashMap.Entry<K,V> current;
|
||||
int expectedModCount;
|
||||
|
||||
LinkedHashIterator() {
|
||||
next = head;
|
||||
expectedModCount = modCount;
|
||||
current = null;
|
||||
}
|
||||
|
||||
public final boolean hasNext() {
|
||||
return next != null;
|
||||
}
|
||||
|
||||
final LinkedHashMap.Entry<K,V> nextNode() {
|
||||
LinkedHashMap.Entry<K,V> e = next;
|
||||
if (modCount != expectedModCount)
|
||||
throw new ConcurrentModificationException();
|
||||
if (e == null)
|
||||
throw new NoSuchElementException();
|
||||
current = e;
|
||||
next = e.after;
|
||||
return e;
|
||||
}
|
||||
|
||||
public final void remove() {
|
||||
Node<K,V> p = current;
|
||||
if (p == null)
|
||||
throw new IllegalStateException();
|
||||
if (modCount != expectedModCount)
|
||||
throw new ConcurrentModificationException();
|
||||
current = null;
|
||||
K key = p.key;
|
||||
removeNode(hash(key), key, null, false, false);
|
||||
expectedModCount = modCount;
|
||||
}
|
||||
}
|
||||
|
||||
final class LinkedKeyIterator extends LinkedHashIterator
|
||||
implements Iterator<K> {
|
||||
public final K next() { return nextNode().getKey(); }
|
||||
}
|
||||
|
||||
final class LinkedValueIterator extends LinkedHashIterator
|
||||
implements Iterator<V> {
|
||||
public final V next() { return nextNode().value; }
|
||||
}
|
||||
|
||||
final class LinkedEntryIterator extends LinkedHashIterator
|
||||
implements Iterator<Map.Entry<K,V>> {
|
||||
public final Map.Entry<K,V> next() { return nextNode(); }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
195
jdkSrc/jdk8/java/util/LinkedHashSet.java
Normal file
195
jdkSrc/jdk8/java/util/LinkedHashSet.java
Normal file
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* <p>Hash table and linked list implementation of the <tt>Set</tt> interface,
|
||||
* with predictable iteration order. This implementation differs from
|
||||
* <tt>HashSet</tt> in that it maintains a doubly-linked list running through
|
||||
* all of its entries. This linked list defines the iteration ordering,
|
||||
* which is the order in which elements were inserted into the set
|
||||
* (<i>insertion-order</i>). Note that insertion order is <i>not</i> affected
|
||||
* if an element is <i>re-inserted</i> into the set. (An element <tt>e</tt>
|
||||
* is reinserted into a set <tt>s</tt> if <tt>s.add(e)</tt> is invoked when
|
||||
* <tt>s.contains(e)</tt> would return <tt>true</tt> immediately prior to
|
||||
* the invocation.)
|
||||
*
|
||||
* <p>This implementation spares its clients from the unspecified, generally
|
||||
* chaotic ordering provided by {@link HashSet}, without incurring the
|
||||
* increased cost associated with {@link TreeSet}. It can be used to
|
||||
* produce a copy of a set that has the same order as the original, regardless
|
||||
* of the original set's implementation:
|
||||
* <pre>
|
||||
* void foo(Set s) {
|
||||
* Set copy = new LinkedHashSet(s);
|
||||
* ...
|
||||
* }
|
||||
* </pre>
|
||||
* This technique is particularly useful if a module takes a set on input,
|
||||
* copies it, and later returns results whose order is determined by that of
|
||||
* the copy. (Clients generally appreciate having things returned in the same
|
||||
* order they were presented.)
|
||||
*
|
||||
* <p>This class provides all of the optional <tt>Set</tt> operations, and
|
||||
* permits null elements. Like <tt>HashSet</tt>, it provides constant-time
|
||||
* performance for the basic operations (<tt>add</tt>, <tt>contains</tt> and
|
||||
* <tt>remove</tt>), assuming the hash function disperses elements
|
||||
* properly among the buckets. Performance is likely to be just slightly
|
||||
* below that of <tt>HashSet</tt>, due to the added expense of maintaining the
|
||||
* linked list, with one exception: Iteration over a <tt>LinkedHashSet</tt>
|
||||
* requires time proportional to the <i>size</i> of the set, regardless of
|
||||
* its capacity. Iteration over a <tt>HashSet</tt> is likely to be more
|
||||
* expensive, requiring time proportional to its <i>capacity</i>.
|
||||
*
|
||||
* <p>A linked hash set has two parameters that affect its performance:
|
||||
* <i>initial capacity</i> and <i>load factor</i>. They are defined precisely
|
||||
* as for <tt>HashSet</tt>. Note, however, that the penalty for choosing an
|
||||
* excessively high value for initial capacity is less severe for this class
|
||||
* than for <tt>HashSet</tt>, as iteration times for this class are unaffected
|
||||
* by capacity.
|
||||
*
|
||||
* <p><strong>Note that this implementation is not synchronized.</strong>
|
||||
* If multiple threads access a linked hash set concurrently, and at least
|
||||
* one of the threads modifies the set, it <em>must</em> be synchronized
|
||||
* externally. This is typically accomplished by synchronizing on some
|
||||
* object that naturally encapsulates the set.
|
||||
*
|
||||
* If no such object exists, the set should be "wrapped" using the
|
||||
* {@link Collections#synchronizedSet Collections.synchronizedSet}
|
||||
* method. This is best done at creation time, to prevent accidental
|
||||
* unsynchronized access to the set: <pre>
|
||||
* Set s = Collections.synchronizedSet(new LinkedHashSet(...));</pre>
|
||||
*
|
||||
* <p>The iterators returned by this class's <tt>iterator</tt> method are
|
||||
* <em>fail-fast</em>: if the set is modified at any time after the iterator
|
||||
* is created, in any way except through the iterator's own <tt>remove</tt>
|
||||
* method, the iterator will throw a {@link ConcurrentModificationException}.
|
||||
* Thus, in the face of concurrent modification, the iterator fails quickly
|
||||
* and cleanly, rather than risking arbitrary, non-deterministic behavior at
|
||||
* an undetermined time in the future.
|
||||
*
|
||||
* <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
|
||||
* as it is, generally speaking, impossible to make any hard guarantees in the
|
||||
* presence of unsynchronized concurrent modification. Fail-fast iterators
|
||||
* throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
|
||||
* Therefore, it would be wrong to write a program that depended on this
|
||||
* exception for its correctness: <i>the fail-fast behavior of iterators
|
||||
* should be used only to detect bugs.</i>
|
||||
*
|
||||
* <p>This class is a member of the
|
||||
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
|
||||
* Java Collections Framework</a>.
|
||||
*
|
||||
* @param <E> the type of elements maintained by this set
|
||||
*
|
||||
* @author Josh Bloch
|
||||
* @see Object#hashCode()
|
||||
* @see Collection
|
||||
* @see Set
|
||||
* @see HashSet
|
||||
* @see TreeSet
|
||||
* @see Hashtable
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
public class LinkedHashSet<E>
|
||||
extends HashSet<E>
|
||||
implements Set<E>, Cloneable, java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = -2851667679971038690L;
|
||||
|
||||
/**
|
||||
* Constructs a new, empty linked hash set with the specified initial
|
||||
* capacity and load factor.
|
||||
*
|
||||
* @param initialCapacity the initial capacity of the linked hash set
|
||||
* @param loadFactor the load factor of the linked hash set
|
||||
* @throws IllegalArgumentException if the initial capacity is less
|
||||
* than zero, or if the load factor is nonpositive
|
||||
*/
|
||||
public LinkedHashSet(int initialCapacity, float loadFactor) {
|
||||
super(initialCapacity, loadFactor, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new, empty linked hash set with the specified initial
|
||||
* capacity and the default load factor (0.75).
|
||||
*
|
||||
* @param initialCapacity the initial capacity of the LinkedHashSet
|
||||
* @throws IllegalArgumentException if the initial capacity is less
|
||||
* than zero
|
||||
*/
|
||||
public LinkedHashSet(int initialCapacity) {
|
||||
super(initialCapacity, .75f, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new, empty linked hash set with the default initial
|
||||
* capacity (16) and load factor (0.75).
|
||||
*/
|
||||
public LinkedHashSet() {
|
||||
super(16, .75f, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new linked hash set with the same elements as the
|
||||
* specified collection. The linked hash set is created with an initial
|
||||
* capacity sufficient to hold the elements in the specified collection
|
||||
* and the default load factor (0.75).
|
||||
*
|
||||
* @param c the collection whose elements are to be placed into
|
||||
* this set
|
||||
* @throws NullPointerException if the specified collection is null
|
||||
*/
|
||||
public LinkedHashSet(Collection<? extends E> c) {
|
||||
super(Math.max(2*c.size(), 11), .75f, true);
|
||||
addAll(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
|
||||
* and <em>fail-fast</em> {@code Spliterator} over the elements in this set.
|
||||
*
|
||||
* <p>The {@code Spliterator} reports {@link Spliterator#SIZED},
|
||||
* {@link Spliterator#DISTINCT}, and {@code ORDERED}. Implementations
|
||||
* should document the reporting of additional characteristic values.
|
||||
*
|
||||
* @implNote
|
||||
* The implementation creates a
|
||||
* <em><a href="Spliterator.html#binding">late-binding</a></em> spliterator
|
||||
* from the set's {@code Iterator}. The spliterator inherits the
|
||||
* <em>fail-fast</em> properties of the set's iterator.
|
||||
* The created {@code Spliterator} additionally reports
|
||||
* {@link Spliterator#SUBSIZED}.
|
||||
*
|
||||
* @return a {@code Spliterator} over the elements in this set
|
||||
* @since 1.8
|
||||
*/
|
||||
@Override
|
||||
public Spliterator<E> spliterator() {
|
||||
return Spliterators.spliterator(this, Spliterator.DISTINCT | Spliterator.ORDERED);
|
||||
}
|
||||
}
|
||||
1262
jdkSrc/jdk8/java/util/LinkedList.java
Normal file
1262
jdkSrc/jdk8/java/util/LinkedList.java
Normal file
File diff suppressed because it is too large
Load Diff
734
jdkSrc/jdk8/java/util/List.java
Normal file
734
jdkSrc/jdk8/java/util/List.java
Normal file
@@ -0,0 +1,734 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
/**
|
||||
* An ordered collection (also known as a <i>sequence</i>). The user of this
|
||||
* interface has precise control over where in the list each element is
|
||||
* inserted. The user can access elements by their integer index (position in
|
||||
* the list), and search for elements in the list.<p>
|
||||
*
|
||||
* Unlike sets, lists typically allow duplicate elements. More formally,
|
||||
* lists typically allow pairs of elements <tt>e1</tt> and <tt>e2</tt>
|
||||
* such that <tt>e1.equals(e2)</tt>, and they typically allow multiple
|
||||
* null elements if they allow null elements at all. It is not inconceivable
|
||||
* that someone might wish to implement a list that prohibits duplicates, by
|
||||
* throwing runtime exceptions when the user attempts to insert them, but we
|
||||
* expect this usage to be rare.<p>
|
||||
*
|
||||
* The <tt>List</tt> interface places additional stipulations, beyond those
|
||||
* specified in the <tt>Collection</tt> interface, on the contracts of the
|
||||
* <tt>iterator</tt>, <tt>add</tt>, <tt>remove</tt>, <tt>equals</tt>, and
|
||||
* <tt>hashCode</tt> methods. Declarations for other inherited methods are
|
||||
* also included here for convenience.<p>
|
||||
*
|
||||
* The <tt>List</tt> interface provides four methods for positional (indexed)
|
||||
* access to list elements. Lists (like Java arrays) are zero based. Note
|
||||
* that these operations may execute in time proportional to the index value
|
||||
* for some implementations (the <tt>LinkedList</tt> class, for
|
||||
* example). Thus, iterating over the elements in a list is typically
|
||||
* preferable to indexing through it if the caller does not know the
|
||||
* implementation.<p>
|
||||
*
|
||||
* The <tt>List</tt> interface provides a special iterator, called a
|
||||
* <tt>ListIterator</tt>, that allows element insertion and replacement, and
|
||||
* bidirectional access in addition to the normal operations that the
|
||||
* <tt>Iterator</tt> interface provides. A method is provided to obtain a
|
||||
* list iterator that starts at a specified position in the list.<p>
|
||||
*
|
||||
* The <tt>List</tt> interface provides two methods to search for a specified
|
||||
* object. From a performance standpoint, these methods should be used with
|
||||
* caution. In many implementations they will perform costly linear
|
||||
* searches.<p>
|
||||
*
|
||||
* The <tt>List</tt> interface provides two methods to efficiently insert and
|
||||
* remove multiple elements at an arbitrary point in the list.<p>
|
||||
*
|
||||
* Note: While it is permissible for lists to contain themselves as elements,
|
||||
* extreme caution is advised: the <tt>equals</tt> and <tt>hashCode</tt>
|
||||
* methods are no longer well defined on such a list.
|
||||
*
|
||||
* <p>Some list implementations have restrictions on the elements that
|
||||
* they may contain. For example, some implementations prohibit null elements,
|
||||
* and some have restrictions on the types of their elements. Attempting to
|
||||
* add an ineligible element throws an unchecked exception, typically
|
||||
* <tt>NullPointerException</tt> or <tt>ClassCastException</tt>. Attempting
|
||||
* to query the presence of an ineligible element may throw an exception,
|
||||
* or it may simply return false; some implementations will exhibit the former
|
||||
* behavior and some will exhibit the latter. More generally, attempting an
|
||||
* operation on an ineligible element whose completion would not result in
|
||||
* the insertion of an ineligible element into the list may throw an
|
||||
* exception or it may succeed, at the option of the implementation.
|
||||
* Such exceptions are marked as "optional" in the specification for this
|
||||
* interface.
|
||||
*
|
||||
* <p>This interface is a member of the
|
||||
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
|
||||
* Java Collections Framework</a>.
|
||||
*
|
||||
* @param <E> the type of elements in this list
|
||||
*
|
||||
* @author Josh Bloch
|
||||
* @author Neal Gafter
|
||||
* @see Collection
|
||||
* @see Set
|
||||
* @see ArrayList
|
||||
* @see LinkedList
|
||||
* @see Vector
|
||||
* @see Arrays#asList(Object[])
|
||||
* @see Collections#nCopies(int, Object)
|
||||
* @see Collections#EMPTY_LIST
|
||||
* @see AbstractList
|
||||
* @see AbstractSequentialList
|
||||
* @since 1.2
|
||||
*/
|
||||
|
||||
public interface List<E> extends Collection<E> {
|
||||
// Query Operations
|
||||
|
||||
/**
|
||||
* Returns the number of elements in this list. If this list contains
|
||||
* more than <tt>Integer.MAX_VALUE</tt> elements, returns
|
||||
* <tt>Integer.MAX_VALUE</tt>.
|
||||
*
|
||||
* @return the number of elements in this list
|
||||
*/
|
||||
int size();
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this list contains no elements.
|
||||
*
|
||||
* @return <tt>true</tt> if this list contains no elements
|
||||
*/
|
||||
boolean isEmpty();
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this list contains the specified element.
|
||||
* More formally, returns <tt>true</tt> if and only if this list contains
|
||||
* at least one element <tt>e</tt> such that
|
||||
* <tt>(o==null ? e==null : o.equals(e))</tt>.
|
||||
*
|
||||
* @param o element whose presence in this list is to be tested
|
||||
* @return <tt>true</tt> if this list contains the specified element
|
||||
* @throws ClassCastException if the type of the specified element
|
||||
* is incompatible with this list
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if the specified element is null and this
|
||||
* list does not permit null elements
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
*/
|
||||
boolean contains(Object o);
|
||||
|
||||
/**
|
||||
* Returns an iterator over the elements in this list in proper sequence.
|
||||
*
|
||||
* @return an iterator over the elements in this list in proper sequence
|
||||
*/
|
||||
Iterator<E> iterator();
|
||||
|
||||
/**
|
||||
* Returns an array containing all of the elements in this list in proper
|
||||
* sequence (from first to last element).
|
||||
*
|
||||
* <p>The returned array will be "safe" in that no references to it are
|
||||
* maintained by this list. (In other words, this method must
|
||||
* allocate a new array even if this list is backed by an array).
|
||||
* The caller is thus free to modify the returned array.
|
||||
*
|
||||
* <p>This method acts as bridge between array-based and collection-based
|
||||
* APIs.
|
||||
*
|
||||
* @return an array containing all of the elements in this list in proper
|
||||
* sequence
|
||||
* @see Arrays#asList(Object[])
|
||||
*/
|
||||
Object[] toArray();
|
||||
|
||||
/**
|
||||
* Returns an array containing all of the elements in this list in
|
||||
* proper sequence (from first to last element); the runtime type of
|
||||
* the returned array is that of the specified array. If the list fits
|
||||
* in the specified array, it is returned therein. Otherwise, a new
|
||||
* array is allocated with the runtime type of the specified array and
|
||||
* the size of this list.
|
||||
*
|
||||
* <p>If the list fits in the specified array with room to spare (i.e.,
|
||||
* the array has more elements than the list), the element in the array
|
||||
* immediately following the end of the list is set to <tt>null</tt>.
|
||||
* (This is useful in determining the length of the list <i>only</i> if
|
||||
* the caller knows that the list does not contain any null elements.)
|
||||
*
|
||||
* <p>Like the {@link #toArray()} method, this method acts as bridge between
|
||||
* array-based and collection-based APIs. Further, this method allows
|
||||
* precise control over the runtime type of the output array, and may,
|
||||
* under certain circumstances, be used to save allocation costs.
|
||||
*
|
||||
* <p>Suppose <tt>x</tt> is a list known to contain only strings.
|
||||
* The following code can be used to dump the list into a newly
|
||||
* allocated array of <tt>String</tt>:
|
||||
*
|
||||
* <pre>{@code
|
||||
* String[] y = x.toArray(new String[0]);
|
||||
* }</pre>
|
||||
*
|
||||
* Note that <tt>toArray(new Object[0])</tt> is identical in function to
|
||||
* <tt>toArray()</tt>.
|
||||
*
|
||||
* @param a the array into which the elements of this list are to
|
||||
* be stored, if it is big enough; otherwise, a new array of the
|
||||
* same runtime type is allocated for this purpose.
|
||||
* @return an array containing the elements of this list
|
||||
* @throws ArrayStoreException if the runtime type of the specified array
|
||||
* is not a supertype of the runtime type of every element in
|
||||
* this list
|
||||
* @throws NullPointerException if the specified array is null
|
||||
*/
|
||||
<T> T[] toArray(T[] a);
|
||||
|
||||
|
||||
// Modification Operations
|
||||
|
||||
/**
|
||||
* Appends the specified element to the end of this list (optional
|
||||
* operation).
|
||||
*
|
||||
* <p>Lists that support this operation may place limitations on what
|
||||
* elements may be added to this list. In particular, some
|
||||
* lists will refuse to add null elements, and others will impose
|
||||
* restrictions on the type of elements that may be added. List
|
||||
* classes should clearly specify in their documentation any restrictions
|
||||
* on what elements may be added.
|
||||
*
|
||||
* @param e element to be appended to this list
|
||||
* @return <tt>true</tt> (as specified by {@link Collection#add})
|
||||
* @throws UnsupportedOperationException if the <tt>add</tt> operation
|
||||
* is not supported by this list
|
||||
* @throws ClassCastException if the class of the specified element
|
||||
* prevents it from being added to this list
|
||||
* @throws NullPointerException if the specified element is null and this
|
||||
* list does not permit null elements
|
||||
* @throws IllegalArgumentException if some property of this element
|
||||
* prevents it from being added to this list
|
||||
*/
|
||||
boolean add(E e);
|
||||
|
||||
/**
|
||||
* Removes the first occurrence of the specified element from this list,
|
||||
* if it is present (optional operation). If this list does not contain
|
||||
* the element, it is unchanged. More formally, removes the element with
|
||||
* the lowest index <tt>i</tt> such that
|
||||
* <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>
|
||||
* (if such an element exists). Returns <tt>true</tt> if this list
|
||||
* contained the specified element (or equivalently, if this list changed
|
||||
* as a result of the call).
|
||||
*
|
||||
* @param o element to be removed from this list, if present
|
||||
* @return <tt>true</tt> if this list contained the specified element
|
||||
* @throws ClassCastException if the type of the specified element
|
||||
* is incompatible with this list
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if the specified element is null and this
|
||||
* list does not permit null elements
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws UnsupportedOperationException if the <tt>remove</tt> operation
|
||||
* is not supported by this list
|
||||
*/
|
||||
boolean remove(Object o);
|
||||
|
||||
|
||||
// Bulk Modification Operations
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this list contains all of the elements of the
|
||||
* specified collection.
|
||||
*
|
||||
* @param c collection to be checked for containment in this list
|
||||
* @return <tt>true</tt> if this list contains all of the elements of the
|
||||
* specified collection
|
||||
* @throws ClassCastException if the types of one or more elements
|
||||
* in the specified collection are incompatible with this
|
||||
* list
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if the specified collection contains one
|
||||
* or more null elements and this list does not permit null
|
||||
* elements
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>),
|
||||
* or if the specified collection is null
|
||||
* @see #contains(Object)
|
||||
*/
|
||||
boolean containsAll(Collection<?> c);
|
||||
|
||||
/**
|
||||
* Appends all of the elements in the specified collection to the end of
|
||||
* this list, in the order that they are returned by the specified
|
||||
* collection's iterator (optional operation). The behavior of this
|
||||
* operation is undefined if the specified collection is modified while
|
||||
* the operation is in progress. (Note that this will occur if the
|
||||
* specified collection is this list, and it's nonempty.)
|
||||
*
|
||||
* @param c collection containing elements to be added to this list
|
||||
* @return <tt>true</tt> if this list changed as a result of the call
|
||||
* @throws UnsupportedOperationException if the <tt>addAll</tt> operation
|
||||
* is not supported by this list
|
||||
* @throws ClassCastException if the class of an element of the specified
|
||||
* collection prevents it from being added to this list
|
||||
* @throws NullPointerException if the specified collection contains one
|
||||
* or more null elements and this list does not permit null
|
||||
* elements, or if the specified collection is null
|
||||
* @throws IllegalArgumentException if some property of an element of the
|
||||
* specified collection prevents it from being added to this list
|
||||
* @see #add(Object)
|
||||
*/
|
||||
boolean addAll(Collection<? extends E> c);
|
||||
|
||||
/**
|
||||
* Inserts all of the elements in the specified collection into this
|
||||
* list at the specified position (optional operation). Shifts the
|
||||
* element currently at that position (if any) and any subsequent
|
||||
* elements to the right (increases their indices). The new elements
|
||||
* will appear in this list in the order that they are returned by the
|
||||
* specified collection's iterator. The behavior of this operation is
|
||||
* undefined if the specified collection is modified while the
|
||||
* operation is in progress. (Note that this will occur if the specified
|
||||
* collection is this list, and it's nonempty.)
|
||||
*
|
||||
* @param index index at which to insert the first element from the
|
||||
* specified collection
|
||||
* @param c collection containing elements to be added to this list
|
||||
* @return <tt>true</tt> if this list changed as a result of the call
|
||||
* @throws UnsupportedOperationException if the <tt>addAll</tt> operation
|
||||
* is not supported by this list
|
||||
* @throws ClassCastException if the class of an element of the specified
|
||||
* collection prevents it from being added to this list
|
||||
* @throws NullPointerException if the specified collection contains one
|
||||
* or more null elements and this list does not permit null
|
||||
* elements, or if the specified collection is null
|
||||
* @throws IllegalArgumentException if some property of an element of the
|
||||
* specified collection prevents it from being added to this list
|
||||
* @throws IndexOutOfBoundsException if the index is out of range
|
||||
* (<tt>index < 0 || index > size()</tt>)
|
||||
*/
|
||||
boolean addAll(int index, Collection<? extends E> c);
|
||||
|
||||
/**
|
||||
* Removes from this list all of its elements that are contained in the
|
||||
* specified collection (optional operation).
|
||||
*
|
||||
* @param c collection containing elements to be removed from this list
|
||||
* @return <tt>true</tt> if this list changed as a result of the call
|
||||
* @throws UnsupportedOperationException if the <tt>removeAll</tt> operation
|
||||
* is not supported by this list
|
||||
* @throws ClassCastException if the class of an element of this list
|
||||
* is incompatible with the specified collection
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if this list contains a null element and the
|
||||
* specified collection does not permit null elements
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>),
|
||||
* or if the specified collection is null
|
||||
* @see #remove(Object)
|
||||
* @see #contains(Object)
|
||||
*/
|
||||
boolean removeAll(Collection<?> c);
|
||||
|
||||
/**
|
||||
* Retains only the elements in this list that are contained in the
|
||||
* specified collection (optional operation). In other words, removes
|
||||
* from this list all of its elements that are not contained in the
|
||||
* specified collection.
|
||||
*
|
||||
* @param c collection containing elements to be retained in this list
|
||||
* @return <tt>true</tt> if this list changed as a result of the call
|
||||
* @throws UnsupportedOperationException if the <tt>retainAll</tt> operation
|
||||
* is not supported by this list
|
||||
* @throws ClassCastException if the class of an element of this list
|
||||
* is incompatible with the specified collection
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if this list contains a null element and the
|
||||
* specified collection does not permit null elements
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>),
|
||||
* or if the specified collection is null
|
||||
* @see #remove(Object)
|
||||
* @see #contains(Object)
|
||||
*/
|
||||
boolean retainAll(Collection<?> c);
|
||||
|
||||
/**
|
||||
* Replaces each element of this list with the result of applying the
|
||||
* operator to that element. Errors or runtime exceptions thrown by
|
||||
* the operator are relayed to the caller.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation is equivalent to, for this {@code list}:
|
||||
* <pre>{@code
|
||||
* final ListIterator<E> li = list.listIterator();
|
||||
* while (li.hasNext()) {
|
||||
* li.set(operator.apply(li.next()));
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* If the list's list-iterator does not support the {@code set} operation
|
||||
* then an {@code UnsupportedOperationException} will be thrown when
|
||||
* replacing the first element.
|
||||
*
|
||||
* @param operator the operator to apply to each element
|
||||
* @throws UnsupportedOperationException if this list is unmodifiable.
|
||||
* Implementations may throw this exception if an element
|
||||
* cannot be replaced or if, in general, modification is not
|
||||
* supported
|
||||
* @throws NullPointerException if the specified operator is null or
|
||||
* if the operator result is a null value and this list does
|
||||
* not permit null elements
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @since 1.8
|
||||
*/
|
||||
default void replaceAll(UnaryOperator<E> operator) {
|
||||
Objects.requireNonNull(operator);
|
||||
final ListIterator<E> li = this.listIterator();
|
||||
while (li.hasNext()) {
|
||||
li.set(operator.apply(li.next()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts this list according to the order induced by the specified
|
||||
* {@link Comparator}.
|
||||
*
|
||||
* <p>All elements in this list must be <i>mutually comparable</i> using the
|
||||
* specified comparator (that is, {@code c.compare(e1, e2)} must not throw
|
||||
* a {@code ClassCastException} for any elements {@code e1} and {@code e2}
|
||||
* in the list).
|
||||
*
|
||||
* <p>If the specified comparator is {@code null} then all elements in this
|
||||
* list must implement the {@link Comparable} interface and the elements'
|
||||
* {@linkplain Comparable natural ordering} should be used.
|
||||
*
|
||||
* <p>This list must be modifiable, but need not be resizable.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation obtains an array containing all elements in
|
||||
* this list, sorts the array, and iterates over this list resetting each
|
||||
* element from the corresponding position in the array. (This avoids the
|
||||
* n<sup>2</sup> log(n) performance that would result from attempting
|
||||
* to sort a linked list in place.)
|
||||
*
|
||||
* @implNote
|
||||
* This implementation is a stable, adaptive, iterative mergesort that
|
||||
* requires far fewer than n lg(n) comparisons when the input array is
|
||||
* partially sorted, while offering the performance of a traditional
|
||||
* mergesort when the input array is randomly ordered. If the input array
|
||||
* is nearly sorted, the implementation requires approximately n
|
||||
* comparisons. Temporary storage requirements vary from a small constant
|
||||
* for nearly sorted input arrays to n/2 object references for randomly
|
||||
* ordered input arrays.
|
||||
*
|
||||
* <p>The implementation takes equal advantage of ascending and
|
||||
* descending order in its input array, and can take advantage of
|
||||
* ascending and descending order in different parts of the same
|
||||
* input array. It is well-suited to merging two or more sorted arrays:
|
||||
* simply concatenate the arrays and sort the resulting array.
|
||||
*
|
||||
* <p>The implementation was adapted from Tim Peters's list sort for Python
|
||||
* (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt">
|
||||
* TimSort</a>). It uses techniques from Peter McIlroy's "Optimistic
|
||||
* Sorting and Information Theoretic Complexity", in Proceedings of the
|
||||
* Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474,
|
||||
* January 1993.
|
||||
*
|
||||
* @param c the {@code Comparator} used to compare list elements.
|
||||
* A {@code null} value indicates that the elements'
|
||||
* {@linkplain Comparable natural ordering} should be used
|
||||
* @throws ClassCastException if the list contains elements that are not
|
||||
* <i>mutually comparable</i> using the specified comparator
|
||||
* @throws UnsupportedOperationException if the list's list-iterator does
|
||||
* not support the {@code set} operation
|
||||
* @throws IllegalArgumentException
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* if the comparator is found to violate the {@link Comparator}
|
||||
* contract
|
||||
* @since 1.8
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
default void sort(Comparator<? super E> c) {
|
||||
Object[] a = this.toArray();
|
||||
Arrays.sort(a, (Comparator) c);
|
||||
ListIterator<E> i = this.listIterator();
|
||||
for (Object e : a) {
|
||||
i.next();
|
||||
i.set((E) e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all of the elements from this list (optional operation).
|
||||
* The list will be empty after this call returns.
|
||||
*
|
||||
* @throws UnsupportedOperationException if the <tt>clear</tt> operation
|
||||
* is not supported by this list
|
||||
*/
|
||||
void clear();
|
||||
|
||||
|
||||
// Comparison and hashing
|
||||
|
||||
/**
|
||||
* Compares the specified object with this list for equality. Returns
|
||||
* <tt>true</tt> if and only if the specified object is also a list, both
|
||||
* lists have the same size, and all corresponding pairs of elements in
|
||||
* the two lists are <i>equal</i>. (Two elements <tt>e1</tt> and
|
||||
* <tt>e2</tt> are <i>equal</i> if <tt>(e1==null ? e2==null :
|
||||
* e1.equals(e2))</tt>.) In other words, two lists are defined to be
|
||||
* equal if they contain the same elements in the same order. This
|
||||
* definition ensures that the equals method works properly across
|
||||
* different implementations of the <tt>List</tt> interface.
|
||||
*
|
||||
* @param o the object to be compared for equality with this list
|
||||
* @return <tt>true</tt> if the specified object is equal to this list
|
||||
*/
|
||||
boolean equals(Object o);
|
||||
|
||||
/**
|
||||
* Returns the hash code value for this list. The hash code of a list
|
||||
* is defined to be the result of the following calculation:
|
||||
* <pre>{@code
|
||||
* int hashCode = 1;
|
||||
* for (E e : list)
|
||||
* hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
|
||||
* }</pre>
|
||||
* This ensures that <tt>list1.equals(list2)</tt> implies that
|
||||
* <tt>list1.hashCode()==list2.hashCode()</tt> for any two lists,
|
||||
* <tt>list1</tt> and <tt>list2</tt>, as required by the general
|
||||
* contract of {@link Object#hashCode}.
|
||||
*
|
||||
* @return the hash code value for this list
|
||||
* @see Object#equals(Object)
|
||||
* @see #equals(Object)
|
||||
*/
|
||||
int hashCode();
|
||||
|
||||
|
||||
// Positional Access Operations
|
||||
|
||||
/**
|
||||
* Returns the element at the specified position in this list.
|
||||
*
|
||||
* @param index index of the element to return
|
||||
* @return the element at the specified position in this list
|
||||
* @throws IndexOutOfBoundsException if the index is out of range
|
||||
* (<tt>index < 0 || index >= size()</tt>)
|
||||
*/
|
||||
E get(int index);
|
||||
|
||||
/**
|
||||
* Replaces the element at the specified position in this list with the
|
||||
* specified element (optional operation).
|
||||
*
|
||||
* @param index index of the element to replace
|
||||
* @param element element to be stored at the specified position
|
||||
* @return the element previously at the specified position
|
||||
* @throws UnsupportedOperationException if the <tt>set</tt> operation
|
||||
* is not supported by this list
|
||||
* @throws ClassCastException if the class of the specified element
|
||||
* prevents it from being added to this list
|
||||
* @throws NullPointerException if the specified element is null and
|
||||
* this list does not permit null elements
|
||||
* @throws IllegalArgumentException if some property of the specified
|
||||
* element prevents it from being added to this list
|
||||
* @throws IndexOutOfBoundsException if the index is out of range
|
||||
* (<tt>index < 0 || index >= size()</tt>)
|
||||
*/
|
||||
E set(int index, E element);
|
||||
|
||||
/**
|
||||
* Inserts the specified element at the specified position in this list
|
||||
* (optional operation). Shifts the element currently at that position
|
||||
* (if any) and any subsequent elements to the right (adds one to their
|
||||
* indices).
|
||||
*
|
||||
* @param index index at which the specified element is to be inserted
|
||||
* @param element element to be inserted
|
||||
* @throws UnsupportedOperationException if the <tt>add</tt> operation
|
||||
* is not supported by this list
|
||||
* @throws ClassCastException if the class of the specified element
|
||||
* prevents it from being added to this list
|
||||
* @throws NullPointerException if the specified element is null and
|
||||
* this list does not permit null elements
|
||||
* @throws IllegalArgumentException if some property of the specified
|
||||
* element prevents it from being added to this list
|
||||
* @throws IndexOutOfBoundsException if the index is out of range
|
||||
* (<tt>index < 0 || index > size()</tt>)
|
||||
*/
|
||||
void add(int index, E element);
|
||||
|
||||
/**
|
||||
* Removes the element at the specified position in this list (optional
|
||||
* operation). Shifts any subsequent elements to the left (subtracts one
|
||||
* from their indices). Returns the element that was removed from the
|
||||
* list.
|
||||
*
|
||||
* @param index the index of the element to be removed
|
||||
* @return the element previously at the specified position
|
||||
* @throws UnsupportedOperationException if the <tt>remove</tt> operation
|
||||
* is not supported by this list
|
||||
* @throws IndexOutOfBoundsException if the index is out of range
|
||||
* (<tt>index < 0 || index >= size()</tt>)
|
||||
*/
|
||||
E remove(int index);
|
||||
|
||||
|
||||
// Search Operations
|
||||
|
||||
/**
|
||||
* Returns the index of the first occurrence of the specified element
|
||||
* in this list, or -1 if this list does not contain the element.
|
||||
* More formally, returns the lowest index <tt>i</tt> such that
|
||||
* <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
|
||||
* or -1 if there is no such index.
|
||||
*
|
||||
* @param o element to search for
|
||||
* @return the index of the first occurrence of the specified element in
|
||||
* this list, or -1 if this list does not contain the element
|
||||
* @throws ClassCastException if the type of the specified element
|
||||
* is incompatible with this list
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if the specified element is null and this
|
||||
* list does not permit null elements
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
*/
|
||||
int indexOf(Object o);
|
||||
|
||||
/**
|
||||
* Returns the index of the last occurrence of the specified element
|
||||
* in this list, or -1 if this list does not contain the element.
|
||||
* More formally, returns the highest index <tt>i</tt> such that
|
||||
* <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
|
||||
* or -1 if there is no such index.
|
||||
*
|
||||
* @param o element to search for
|
||||
* @return the index of the last occurrence of the specified element in
|
||||
* this list, or -1 if this list does not contain the element
|
||||
* @throws ClassCastException if the type of the specified element
|
||||
* is incompatible with this list
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if the specified element is null and this
|
||||
* list does not permit null elements
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
*/
|
||||
int lastIndexOf(Object o);
|
||||
|
||||
|
||||
// List Iterators
|
||||
|
||||
/**
|
||||
* Returns a list iterator over the elements in this list (in proper
|
||||
* sequence).
|
||||
*
|
||||
* @return a list iterator over the elements in this list (in proper
|
||||
* sequence)
|
||||
*/
|
||||
ListIterator<E> listIterator();
|
||||
|
||||
/**
|
||||
* Returns a list iterator over the elements in this list (in proper
|
||||
* sequence), starting at the specified position in the list.
|
||||
* The specified index indicates the first element that would be
|
||||
* returned by an initial call to {@link ListIterator#next next}.
|
||||
* An initial call to {@link ListIterator#previous previous} would
|
||||
* return the element with the specified index minus one.
|
||||
*
|
||||
* @param index index of the first element to be returned from the
|
||||
* list iterator (by a call to {@link ListIterator#next next})
|
||||
* @return a list iterator over the elements in this list (in proper
|
||||
* sequence), starting at the specified position in the list
|
||||
* @throws IndexOutOfBoundsException if the index is out of range
|
||||
* ({@code index < 0 || index > size()})
|
||||
*/
|
||||
ListIterator<E> listIterator(int index);
|
||||
|
||||
// View
|
||||
|
||||
/**
|
||||
* Returns a view of the portion of this list between the specified
|
||||
* <tt>fromIndex</tt>, inclusive, and <tt>toIndex</tt>, exclusive. (If
|
||||
* <tt>fromIndex</tt> and <tt>toIndex</tt> are equal, the returned list is
|
||||
* empty.) The returned list is backed by this list, so non-structural
|
||||
* changes in the returned list are reflected in this list, and vice-versa.
|
||||
* The returned list supports all of the optional list operations supported
|
||||
* by this list.<p>
|
||||
*
|
||||
* This method eliminates the need for explicit range operations (of
|
||||
* the sort that commonly exist for arrays). Any operation that expects
|
||||
* a list can be used as a range operation by passing a subList view
|
||||
* instead of a whole list. For example, the following idiom
|
||||
* removes a range of elements from a list:
|
||||
* <pre>{@code
|
||||
* list.subList(from, to).clear();
|
||||
* }</pre>
|
||||
* Similar idioms may be constructed for <tt>indexOf</tt> and
|
||||
* <tt>lastIndexOf</tt>, and all of the algorithms in the
|
||||
* <tt>Collections</tt> class can be applied to a subList.<p>
|
||||
*
|
||||
* The semantics of the list returned by this method become undefined if
|
||||
* the backing list (i.e., this list) is <i>structurally modified</i> in
|
||||
* any way other than via the returned list. (Structural modifications are
|
||||
* those that change the size of this list, or otherwise perturb it in such
|
||||
* a fashion that iterations in progress may yield incorrect results.)
|
||||
*
|
||||
* @param fromIndex low endpoint (inclusive) of the subList
|
||||
* @param toIndex high endpoint (exclusive) of the subList
|
||||
* @return a view of the specified range within this list
|
||||
* @throws IndexOutOfBoundsException for an illegal endpoint index value
|
||||
* (<tt>fromIndex < 0 || toIndex > size ||
|
||||
* fromIndex > toIndex</tt>)
|
||||
*/
|
||||
List<E> subList(int fromIndex, int toIndex);
|
||||
|
||||
/**
|
||||
* Creates a {@link Spliterator} over the elements in this list.
|
||||
*
|
||||
* <p>The {@code Spliterator} reports {@link Spliterator#SIZED} and
|
||||
* {@link Spliterator#ORDERED}. Implementations should document the
|
||||
* reporting of additional characteristic values.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation creates a
|
||||
* <em><a href="Spliterator.html#binding">late-binding</a></em> spliterator
|
||||
* from the list's {@code Iterator}. The spliterator inherits the
|
||||
* <em>fail-fast</em> properties of the list's iterator.
|
||||
*
|
||||
* @implNote
|
||||
* The created {@code Spliterator} additionally reports
|
||||
* {@link Spliterator#SUBSIZED}.
|
||||
*
|
||||
* @return a {@code Spliterator} over the elements in this list
|
||||
* @since 1.8
|
||||
*/
|
||||
@Override
|
||||
default Spliterator<E> spliterator() {
|
||||
return Spliterators.spliterator(this, Spliterator.ORDERED);
|
||||
}
|
||||
}
|
||||
195
jdkSrc/jdk8/java/util/ListIterator.java
Normal file
195
jdkSrc/jdk8/java/util/ListIterator.java
Normal file
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* An iterator for lists that allows the programmer
|
||||
* to traverse the list in either direction, modify
|
||||
* the list during iteration, and obtain the iterator's
|
||||
* current position in the list. A {@code ListIterator}
|
||||
* has no current element; its <I>cursor position</I> always
|
||||
* lies between the element that would be returned by a call
|
||||
* to {@code previous()} and the element that would be
|
||||
* returned by a call to {@code next()}.
|
||||
* An iterator for a list of length {@code n} has {@code n+1} possible
|
||||
* cursor positions, as illustrated by the carets ({@code ^}) below:
|
||||
* <PRE>
|
||||
* Element(0) Element(1) Element(2) ... Element(n-1)
|
||||
* cursor positions: ^ ^ ^ ^ ^
|
||||
* </PRE>
|
||||
* Note that the {@link #remove} and {@link #set(Object)} methods are
|
||||
* <i>not</i> defined in terms of the cursor position; they are defined to
|
||||
* operate on the last element returned by a call to {@link #next} or
|
||||
* {@link #previous()}.
|
||||
*
|
||||
* <p>This interface is a member of the
|
||||
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
|
||||
* Java Collections Framework</a>.
|
||||
*
|
||||
* @author Josh Bloch
|
||||
* @see Collection
|
||||
* @see List
|
||||
* @see Iterator
|
||||
* @see Enumeration
|
||||
* @see List#listIterator()
|
||||
* @since 1.2
|
||||
*/
|
||||
public interface ListIterator<E> extends Iterator<E> {
|
||||
// Query Operations
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this list iterator has more elements when
|
||||
* traversing the list in the forward direction. (In other words,
|
||||
* returns {@code true} if {@link #next} would return an element rather
|
||||
* than throwing an exception.)
|
||||
*
|
||||
* @return {@code true} if the list iterator has more elements when
|
||||
* traversing the list in the forward direction
|
||||
*/
|
||||
boolean hasNext();
|
||||
|
||||
/**
|
||||
* Returns the next element in the list and advances the cursor position.
|
||||
* This method may be called repeatedly to iterate through the list,
|
||||
* or intermixed with calls to {@link #previous} to go back and forth.
|
||||
* (Note that alternating calls to {@code next} and {@code previous}
|
||||
* will return the same element repeatedly.)
|
||||
*
|
||||
* @return the next element in the list
|
||||
* @throws NoSuchElementException if the iteration has no next element
|
||||
*/
|
||||
E next();
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this list iterator has more elements when
|
||||
* traversing the list in the reverse direction. (In other words,
|
||||
* returns {@code true} if {@link #previous} would return an element
|
||||
* rather than throwing an exception.)
|
||||
*
|
||||
* @return {@code true} if the list iterator has more elements when
|
||||
* traversing the list in the reverse direction
|
||||
*/
|
||||
boolean hasPrevious();
|
||||
|
||||
/**
|
||||
* Returns the previous element in the list and moves the cursor
|
||||
* position backwards. This method may be called repeatedly to
|
||||
* iterate through the list backwards, or intermixed with calls to
|
||||
* {@link #next} to go back and forth. (Note that alternating calls
|
||||
* to {@code next} and {@code previous} will return the same
|
||||
* element repeatedly.)
|
||||
*
|
||||
* @return the previous element in the list
|
||||
* @throws NoSuchElementException if the iteration has no previous
|
||||
* element
|
||||
*/
|
||||
E previous();
|
||||
|
||||
/**
|
||||
* Returns the index of the element that would be returned by a
|
||||
* subsequent call to {@link #next}. (Returns list size if the list
|
||||
* iterator is at the end of the list.)
|
||||
*
|
||||
* @return the index of the element that would be returned by a
|
||||
* subsequent call to {@code next}, or list size if the list
|
||||
* iterator is at the end of the list
|
||||
*/
|
||||
int nextIndex();
|
||||
|
||||
/**
|
||||
* Returns the index of the element that would be returned by a
|
||||
* subsequent call to {@link #previous}. (Returns -1 if the list
|
||||
* iterator is at the beginning of the list.)
|
||||
*
|
||||
* @return the index of the element that would be returned by a
|
||||
* subsequent call to {@code previous}, or -1 if the list
|
||||
* iterator is at the beginning of the list
|
||||
*/
|
||||
int previousIndex();
|
||||
|
||||
|
||||
// Modification Operations
|
||||
|
||||
/**
|
||||
* Removes from the list the last element that was returned by {@link
|
||||
* #next} or {@link #previous} (optional operation). This call can
|
||||
* only be made once per call to {@code next} or {@code previous}.
|
||||
* It can be made only if {@link #add} has not been
|
||||
* called after the last call to {@code next} or {@code previous}.
|
||||
*
|
||||
* @throws UnsupportedOperationException if the {@code remove}
|
||||
* operation is not supported by this list iterator
|
||||
* @throws IllegalStateException if neither {@code next} nor
|
||||
* {@code previous} have been called, or {@code remove} or
|
||||
* {@code add} have been called after the last call to
|
||||
* {@code next} or {@code previous}
|
||||
*/
|
||||
void remove();
|
||||
|
||||
/**
|
||||
* Replaces the last element returned by {@link #next} or
|
||||
* {@link #previous} with the specified element (optional operation).
|
||||
* This call can be made only if neither {@link #remove} nor {@link
|
||||
* #add} have been called after the last call to {@code next} or
|
||||
* {@code previous}.
|
||||
*
|
||||
* @param e the element with which to replace the last element returned by
|
||||
* {@code next} or {@code previous}
|
||||
* @throws UnsupportedOperationException if the {@code set} operation
|
||||
* is not supported by this list iterator
|
||||
* @throws ClassCastException if the class of the specified element
|
||||
* prevents it from being added to this list
|
||||
* @throws IllegalArgumentException if some aspect of the specified
|
||||
* element prevents it from being added to this list
|
||||
* @throws IllegalStateException if neither {@code next} nor
|
||||
* {@code previous} have been called, or {@code remove} or
|
||||
* {@code add} have been called after the last call to
|
||||
* {@code next} or {@code previous}
|
||||
*/
|
||||
void set(E e);
|
||||
|
||||
/**
|
||||
* Inserts the specified element into the list (optional operation).
|
||||
* The element is inserted immediately before the element that
|
||||
* would be returned by {@link #next}, if any, and after the element
|
||||
* that would be returned by {@link #previous}, if any. (If the
|
||||
* list contains no elements, the new element becomes the sole element
|
||||
* on the list.) The new element is inserted before the implicit
|
||||
* cursor: a subsequent call to {@code next} would be unaffected, and a
|
||||
* subsequent call to {@code previous} would return the new element.
|
||||
* (This call increases by one the value that would be returned by a
|
||||
* call to {@code nextIndex} or {@code previousIndex}.)
|
||||
*
|
||||
* @param e the element to insert
|
||||
* @throws UnsupportedOperationException if the {@code add} method is
|
||||
* not supported by this list iterator
|
||||
* @throws ClassCastException if the class of the specified element
|
||||
* prevents it from being added to this list
|
||||
* @throws IllegalArgumentException if some aspect of this element
|
||||
* prevents it from being added to this list
|
||||
*/
|
||||
void add(E e);
|
||||
}
|
||||
210
jdkSrc/jdk8/java/util/ListResourceBundle.java
Normal file
210
jdkSrc/jdk8/java/util/ListResourceBundle.java
Normal file
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
|
||||
*
|
||||
* The original version of this source code and documentation
|
||||
* is copyrighted and owned by Taligent, Inc., a wholly-owned
|
||||
* subsidiary of IBM. These materials are provided under terms
|
||||
* of a License Agreement between Taligent and Sun. This technology
|
||||
* is protected by multiple US and International patents.
|
||||
*
|
||||
* This notice and attribution to Taligent may not be removed.
|
||||
* Taligent is a registered trademark of Taligent, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
import sun.util.ResourceBundleEnumeration;
|
||||
|
||||
/**
|
||||
* <code>ListResourceBundle</code> is an abstract subclass of
|
||||
* <code>ResourceBundle</code> that manages resources for a locale
|
||||
* in a convenient and easy to use list. See <code>ResourceBundle</code> for
|
||||
* more information about resource bundles in general.
|
||||
*
|
||||
* <P>
|
||||
* Subclasses must override <code>getContents</code> and provide an array,
|
||||
* where each item in the array is a pair of objects.
|
||||
* The first element of each pair is the key, which must be a
|
||||
* <code>String</code>, and the second element is the value associated with
|
||||
* that key.
|
||||
*
|
||||
* <p>
|
||||
* The following <a name="sample">example</a> shows two members of a resource
|
||||
* bundle family with the base name "MyResources".
|
||||
* "MyResources" is the default member of the bundle family, and
|
||||
* "MyResources_fr" is the French member.
|
||||
* These members are based on <code>ListResourceBundle</code>
|
||||
* (a related <a href="PropertyResourceBundle.html#sample">example</a> shows
|
||||
* how you can add a bundle to this family that's based on a properties file).
|
||||
* The keys in this example are of the form "s1" etc. The actual
|
||||
* keys are entirely up to your choice, so long as they are the same as
|
||||
* the keys you use in your program to retrieve the objects from the bundle.
|
||||
* Keys are case-sensitive.
|
||||
* <blockquote>
|
||||
* <pre>
|
||||
*
|
||||
* public class MyResources extends ListResourceBundle {
|
||||
* protected Object[][] getContents() {
|
||||
* return new Object[][] {
|
||||
* // LOCALIZE THIS
|
||||
* {"s1", "The disk \"{1}\" contains {0}."}, // MessageFormat pattern
|
||||
* {"s2", "1"}, // location of {0} in pattern
|
||||
* {"s3", "My Disk"}, // sample disk name
|
||||
* {"s4", "no files"}, // first ChoiceFormat choice
|
||||
* {"s5", "one file"}, // second ChoiceFormat choice
|
||||
* {"s6", "{0,number} files"}, // third ChoiceFormat choice
|
||||
* {"s7", "3 Mar 96"}, // sample date
|
||||
* {"s8", new Dimension(1,5)} // real object, not just string
|
||||
* // END OF MATERIAL TO LOCALIZE
|
||||
* };
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* public class MyResources_fr extends ListResourceBundle {
|
||||
* protected Object[][] getContents() {
|
||||
* return new Object[][] {
|
||||
* // LOCALIZE THIS
|
||||
* {"s1", "Le disque \"{1}\" {0}."}, // MessageFormat pattern
|
||||
* {"s2", "1"}, // location of {0} in pattern
|
||||
* {"s3", "Mon disque"}, // sample disk name
|
||||
* {"s4", "ne contient pas de fichiers"}, // first ChoiceFormat choice
|
||||
* {"s5", "contient un fichier"}, // second ChoiceFormat choice
|
||||
* {"s6", "contient {0,number} fichiers"}, // third ChoiceFormat choice
|
||||
* {"s7", "3 mars 1996"}, // sample date
|
||||
* {"s8", new Dimension(1,3)} // real object, not just string
|
||||
* // END OF MATERIAL TO LOCALIZE
|
||||
* };
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* </blockquote>
|
||||
*
|
||||
* <p>
|
||||
* The implementation of a {@code ListResourceBundle} subclass must be thread-safe
|
||||
* if it's simultaneously used by multiple threads. The default implementations
|
||||
* of the methods in this class are thread-safe.
|
||||
*
|
||||
* @see ResourceBundle
|
||||
* @see PropertyResourceBundle
|
||||
* @since JDK1.1
|
||||
*/
|
||||
public abstract class ListResourceBundle extends ResourceBundle {
|
||||
/**
|
||||
* Sole constructor. (For invocation by subclass constructors, typically
|
||||
* implicit.)
|
||||
*/
|
||||
public ListResourceBundle() {
|
||||
}
|
||||
|
||||
// Implements java.util.ResourceBundle.handleGetObject; inherits javadoc specification.
|
||||
public final Object handleGetObject(String key) {
|
||||
// lazily load the lookup hashtable.
|
||||
if (lookup == null) {
|
||||
loadLookup();
|
||||
}
|
||||
if (key == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
return lookup.get(key); // this class ignores locales
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an <code>Enumeration</code> of the keys contained in
|
||||
* this <code>ResourceBundle</code> and its parent bundles.
|
||||
*
|
||||
* @return an <code>Enumeration</code> of the keys contained in
|
||||
* this <code>ResourceBundle</code> and its parent bundles.
|
||||
* @see #keySet()
|
||||
*/
|
||||
public Enumeration<String> getKeys() {
|
||||
// lazily load the lookup hashtable.
|
||||
if (lookup == null) {
|
||||
loadLookup();
|
||||
}
|
||||
|
||||
ResourceBundle parent = this.parent;
|
||||
return new ResourceBundleEnumeration(lookup.keySet(),
|
||||
(parent != null) ? parent.getKeys() : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a <code>Set</code> of the keys contained
|
||||
* <em>only</em> in this <code>ResourceBundle</code>.
|
||||
*
|
||||
* @return a <code>Set</code> of the keys contained only in this
|
||||
* <code>ResourceBundle</code>
|
||||
* @since 1.6
|
||||
* @see #keySet()
|
||||
*/
|
||||
protected Set<String> handleKeySet() {
|
||||
if (lookup == null) {
|
||||
loadLookup();
|
||||
}
|
||||
return lookup.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array in which each item is a pair of objects in an
|
||||
* <code>Object</code> array. The first element of each pair is
|
||||
* the key, which must be a <code>String</code>, and the second
|
||||
* element is the value associated with that key. See the class
|
||||
* description for details.
|
||||
*
|
||||
* @return an array of an <code>Object</code> array representing a
|
||||
* key-value pair.
|
||||
*/
|
||||
abstract protected Object[][] getContents();
|
||||
|
||||
// ==================privates====================
|
||||
|
||||
/**
|
||||
* We lazily load the lookup hashtable. This function does the
|
||||
* loading.
|
||||
*/
|
||||
private synchronized void loadLookup() {
|
||||
if (lookup != null)
|
||||
return;
|
||||
|
||||
Object[][] contents = getContents();
|
||||
HashMap<String,Object> temp = new HashMap<>(contents.length);
|
||||
for (int i = 0; i < contents.length; ++i) {
|
||||
// key must be non-null String, value must be non-null
|
||||
String key = (String) contents[i][0];
|
||||
Object value = contents[i][1];
|
||||
if (key == null || value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
temp.put(key, value);
|
||||
}
|
||||
lookup = temp;
|
||||
}
|
||||
|
||||
private Map<String,Object> lookup = null;
|
||||
}
|
||||
3283
jdkSrc/jdk8/java/util/Locale.java
Normal file
3283
jdkSrc/jdk8/java/util/Locale.java
Normal file
File diff suppressed because it is too large
Load Diff
482
jdkSrc/jdk8/java/util/LocaleISOData.java
Normal file
482
jdkSrc/jdk8/java/util/LocaleISOData.java
Normal file
@@ -0,0 +1,482 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
class LocaleISOData {
|
||||
/**
|
||||
* The 2- and 3-letter ISO 639 language codes.
|
||||
*/
|
||||
static final String isoLanguageTable =
|
||||
"aa" + "aar" // Afar
|
||||
+ "ab" + "abk" // Abkhazian
|
||||
+ "ae" + "ave" // Avestan
|
||||
+ "af" + "afr" // Afrikaans
|
||||
+ "ak" + "aka" // Akan
|
||||
+ "am" + "amh" // Amharic
|
||||
+ "an" + "arg" // Aragonese
|
||||
+ "ar" + "ara" // Arabic
|
||||
+ "as" + "asm" // Assamese
|
||||
+ "av" + "ava" // Avaric
|
||||
+ "ay" + "aym" // Aymara
|
||||
+ "az" + "aze" // Azerbaijani
|
||||
+ "ba" + "bak" // Bashkir
|
||||
+ "be" + "bel" // Belarusian
|
||||
+ "bg" + "bul" // Bulgarian
|
||||
+ "bh" + "bih" // Bihari
|
||||
+ "bi" + "bis" // Bislama
|
||||
+ "bm" + "bam" // Bambara
|
||||
+ "bn" + "ben" // Bengali
|
||||
+ "bo" + "bod" // Tibetan
|
||||
+ "br" + "bre" // Breton
|
||||
+ "bs" + "bos" // Bosnian
|
||||
+ "ca" + "cat" // Catalan
|
||||
+ "ce" + "che" // Chechen
|
||||
+ "ch" + "cha" // Chamorro
|
||||
+ "co" + "cos" // Corsican
|
||||
+ "cr" + "cre" // Cree
|
||||
+ "cs" + "ces" // Czech
|
||||
+ "cu" + "chu" // Church Slavic
|
||||
+ "cv" + "chv" // Chuvash
|
||||
+ "cy" + "cym" // Welsh
|
||||
+ "da" + "dan" // Danish
|
||||
+ "de" + "deu" // German
|
||||
+ "dv" + "div" // Divehi
|
||||
+ "dz" + "dzo" // Dzongkha
|
||||
+ "ee" + "ewe" // Ewe
|
||||
+ "el" + "ell" // Greek
|
||||
+ "en" + "eng" // English
|
||||
+ "eo" + "epo" // Esperanto
|
||||
+ "es" + "spa" // Spanish
|
||||
+ "et" + "est" // Estonian
|
||||
+ "eu" + "eus" // Basque
|
||||
+ "fa" + "fas" // Persian
|
||||
+ "ff" + "ful" // Fulah
|
||||
+ "fi" + "fin" // Finnish
|
||||
+ "fj" + "fij" // Fijian
|
||||
+ "fo" + "fao" // Faroese
|
||||
+ "fr" + "fra" // French
|
||||
+ "fy" + "fry" // Frisian
|
||||
+ "ga" + "gle" // Irish
|
||||
+ "gd" + "gla" // Scottish Gaelic
|
||||
+ "gl" + "glg" // Gallegan
|
||||
+ "gn" + "grn" // Guarani
|
||||
+ "gu" + "guj" // Gujarati
|
||||
+ "gv" + "glv" // Manx
|
||||
+ "ha" + "hau" // Hausa
|
||||
+ "he" + "heb" // Hebrew
|
||||
+ "hi" + "hin" // Hindi
|
||||
+ "ho" + "hmo" // Hiri Motu
|
||||
+ "hr" + "hrv" // Croatian
|
||||
+ "ht" + "hat" // Haitian
|
||||
+ "hu" + "hun" // Hungarian
|
||||
+ "hy" + "hye" // Armenian
|
||||
+ "hz" + "her" // Herero
|
||||
+ "ia" + "ina" // Interlingua
|
||||
+ "id" + "ind" // Indonesian
|
||||
+ "ie" + "ile" // Interlingue
|
||||
+ "ig" + "ibo" // Igbo
|
||||
+ "ii" + "iii" // Sichuan Yi
|
||||
+ "ik" + "ipk" // Inupiaq
|
||||
+ "in" + "ind" // Indonesian (old)
|
||||
+ "io" + "ido" // Ido
|
||||
+ "is" + "isl" // Icelandic
|
||||
+ "it" + "ita" // Italian
|
||||
+ "iu" + "iku" // Inuktitut
|
||||
+ "iw" + "heb" // Hebrew (old)
|
||||
+ "ja" + "jpn" // Japanese
|
||||
+ "ji" + "yid" // Yiddish (old)
|
||||
+ "jv" + "jav" // Javanese
|
||||
+ "ka" + "kat" // Georgian
|
||||
+ "kg" + "kon" // Kongo
|
||||
+ "ki" + "kik" // Kikuyu
|
||||
+ "kj" + "kua" // Kwanyama
|
||||
+ "kk" + "kaz" // Kazakh
|
||||
+ "kl" + "kal" // Greenlandic
|
||||
+ "km" + "khm" // Khmer
|
||||
+ "kn" + "kan" // Kannada
|
||||
+ "ko" + "kor" // Korean
|
||||
+ "kr" + "kau" // Kanuri
|
||||
+ "ks" + "kas" // Kashmiri
|
||||
+ "ku" + "kur" // Kurdish
|
||||
+ "kv" + "kom" // Komi
|
||||
+ "kw" + "cor" // Cornish
|
||||
+ "ky" + "kir" // Kirghiz
|
||||
+ "la" + "lat" // Latin
|
||||
+ "lb" + "ltz" // Luxembourgish
|
||||
+ "lg" + "lug" // Ganda
|
||||
+ "li" + "lim" // Limburgish
|
||||
+ "ln" + "lin" // Lingala
|
||||
+ "lo" + "lao" // Lao
|
||||
+ "lt" + "lit" // Lithuanian
|
||||
+ "lu" + "lub" // Luba-Katanga
|
||||
+ "lv" + "lav" // Latvian
|
||||
+ "mg" + "mlg" // Malagasy
|
||||
+ "mh" + "mah" // Marshallese
|
||||
+ "mi" + "mri" // Maori
|
||||
+ "mk" + "mkd" // Macedonian
|
||||
+ "ml" + "mal" // Malayalam
|
||||
+ "mn" + "mon" // Mongolian
|
||||
+ "mo" + "mol" // Moldavian
|
||||
+ "mr" + "mar" // Marathi
|
||||
+ "ms" + "msa" // Malay
|
||||
+ "mt" + "mlt" // Maltese
|
||||
+ "my" + "mya" // Burmese
|
||||
+ "na" + "nau" // Nauru
|
||||
+ "nb" + "nob" // Norwegian Bokm?l
|
||||
+ "nd" + "nde" // North Ndebele
|
||||
+ "ne" + "nep" // Nepali
|
||||
+ "ng" + "ndo" // Ndonga
|
||||
+ "nl" + "nld" // Dutch
|
||||
+ "nn" + "nno" // Norwegian Nynorsk
|
||||
+ "no" + "nor" // Norwegian
|
||||
+ "nr" + "nbl" // South Ndebele
|
||||
+ "nv" + "nav" // Navajo
|
||||
+ "ny" + "nya" // Nyanja
|
||||
+ "oc" + "oci" // Occitan
|
||||
+ "oj" + "oji" // Ojibwa
|
||||
+ "om" + "orm" // Oromo
|
||||
+ "or" + "ori" // Oriya
|
||||
+ "os" + "oss" // Ossetian
|
||||
+ "pa" + "pan" // Panjabi
|
||||
+ "pi" + "pli" // Pali
|
||||
+ "pl" + "pol" // Polish
|
||||
+ "ps" + "pus" // Pushto
|
||||
+ "pt" + "por" // Portuguese
|
||||
+ "qu" + "que" // Quechua
|
||||
+ "rm" + "roh" // Raeto-Romance
|
||||
+ "rn" + "run" // Rundi
|
||||
+ "ro" + "ron" // Romanian
|
||||
+ "ru" + "rus" // Russian
|
||||
+ "rw" + "kin" // Kinyarwanda
|
||||
+ "sa" + "san" // Sanskrit
|
||||
+ "sc" + "srd" // Sardinian
|
||||
+ "sd" + "snd" // Sindhi
|
||||
+ "se" + "sme" // Northern Sami
|
||||
+ "sg" + "sag" // Sango
|
||||
+ "si" + "sin" // Sinhalese
|
||||
+ "sk" + "slk" // Slovak
|
||||
+ "sl" + "slv" // Slovenian
|
||||
+ "sm" + "smo" // Samoan
|
||||
+ "sn" + "sna" // Shona
|
||||
+ "so" + "som" // Somali
|
||||
+ "sq" + "sqi" // Albanian
|
||||
+ "sr" + "srp" // Serbian
|
||||
+ "ss" + "ssw" // Swati
|
||||
+ "st" + "sot" // Southern Sotho
|
||||
+ "su" + "sun" // Sundanese
|
||||
+ "sv" + "swe" // Swedish
|
||||
+ "sw" + "swa" // Swahili
|
||||
+ "ta" + "tam" // Tamil
|
||||
+ "te" + "tel" // Telugu
|
||||
+ "tg" + "tgk" // Tajik
|
||||
+ "th" + "tha" // Thai
|
||||
+ "ti" + "tir" // Tigrinya
|
||||
+ "tk" + "tuk" // Turkmen
|
||||
+ "tl" + "tgl" // Tagalog
|
||||
+ "tn" + "tsn" // Tswana
|
||||
+ "to" + "ton" // Tonga
|
||||
+ "tr" + "tur" // Turkish
|
||||
+ "ts" + "tso" // Tsonga
|
||||
+ "tt" + "tat" // Tatar
|
||||
+ "tw" + "twi" // Twi
|
||||
+ "ty" + "tah" // Tahitian
|
||||
+ "ug" + "uig" // Uighur
|
||||
+ "uk" + "ukr" // Ukrainian
|
||||
+ "ur" + "urd" // Urdu
|
||||
+ "uz" + "uzb" // Uzbek
|
||||
+ "ve" + "ven" // Venda
|
||||
+ "vi" + "vie" // Vietnamese
|
||||
+ "vo" + "vol" // Volap?k
|
||||
+ "wa" + "wln" // Walloon
|
||||
+ "wo" + "wol" // Wolof
|
||||
+ "xh" + "xho" // Xhosa
|
||||
+ "yi" + "yid" // Yiddish
|
||||
+ "yo" + "yor" // Yoruba
|
||||
+ "za" + "zha" // Zhuang
|
||||
+ "zh" + "zho" // Chinese
|
||||
+ "zu" + "zul" // Zulu
|
||||
;
|
||||
|
||||
/**
|
||||
* The 2- and 3-letter ISO 3166 country codes.
|
||||
*/
|
||||
static final String isoCountryTable =
|
||||
"AD" + "AND" // Andorra, Principality of
|
||||
+ "AE" + "ARE" // United Arab Emirates
|
||||
+ "AF" + "AFG" // Afghanistan
|
||||
+ "AG" + "ATG" // Antigua and Barbuda
|
||||
+ "AI" + "AIA" // Anguilla
|
||||
+ "AL" + "ALB" // Albania, People's Socialist Republic of
|
||||
+ "AM" + "ARM" // Armenia
|
||||
+ "AN" + "ANT" // Netherlands Antilles
|
||||
+ "AO" + "AGO" // Angola, Republic of
|
||||
+ "AQ" + "ATA" // Antarctica (the territory South of 60 deg S)
|
||||
+ "AR" + "ARG" // Argentina, Argentine Republic
|
||||
+ "AS" + "ASM" // American Samoa
|
||||
+ "AT" + "AUT" // Austria, Republic of
|
||||
+ "AU" + "AUS" // Australia, Commonwealth of
|
||||
+ "AW" + "ABW" // Aruba
|
||||
+ "AX" + "ALA" // \u00c5land Islands
|
||||
+ "AZ" + "AZE" // Azerbaijan, Republic of
|
||||
+ "BA" + "BIH" // Bosnia and Herzegovina
|
||||
+ "BB" + "BRB" // Barbados
|
||||
+ "BD" + "BGD" // Bangladesh, People's Republic of
|
||||
+ "BE" + "BEL" // Belgium, Kingdom of
|
||||
+ "BF" + "BFA" // Burkina Faso
|
||||
+ "BG" + "BGR" // Bulgaria, People's Republic of
|
||||
+ "BH" + "BHR" // Bahrain, Kingdom of
|
||||
+ "BI" + "BDI" // Burundi, Republic of
|
||||
+ "BJ" + "BEN" // Benin, People's Republic of
|
||||
+ "BL" + "BLM" // Saint Barth\u00e9lemy
|
||||
+ "BM" + "BMU" // Bermuda
|
||||
+ "BN" + "BRN" // Brunei Darussalam
|
||||
+ "BO" + "BOL" // Bolivia, Republic of
|
||||
+ "BQ" + "BES" // Bonaire, Sint Eustatius and Saba
|
||||
+ "BR" + "BRA" // Brazil, Federative Republic of
|
||||
+ "BS" + "BHS" // Bahamas, Commonwealth of the
|
||||
+ "BT" + "BTN" // Bhutan, Kingdom of
|
||||
+ "BV" + "BVT" // Bouvet Island (Bouvetoya)
|
||||
+ "BW" + "BWA" // Botswana, Republic of
|
||||
+ "BY" + "BLR" // Belarus
|
||||
+ "BZ" + "BLZ" // Belize
|
||||
+ "CA" + "CAN" // Canada
|
||||
+ "CC" + "CCK" // Cocos (Keeling) Islands
|
||||
+ "CD" + "COD" // Congo, Democratic Republic of
|
||||
+ "CF" + "CAF" // Central African Republic
|
||||
+ "CG" + "COG" // Congo, People's Republic of
|
||||
+ "CH" + "CHE" // Switzerland, Swiss Confederation
|
||||
+ "CI" + "CIV" // Cote D'Ivoire, Ivory Coast, Republic of the
|
||||
+ "CK" + "COK" // Cook Islands
|
||||
+ "CL" + "CHL" // Chile, Republic of
|
||||
+ "CM" + "CMR" // Cameroon, United Republic of
|
||||
+ "CN" + "CHN" // China, People's Republic of
|
||||
+ "CO" + "COL" // Colombia, Republic of
|
||||
+ "CR" + "CRI" // Costa Rica, Republic of
|
||||
// + "CS" + "SCG" // Serbia and Montenegro
|
||||
+ "CU" + "CUB" // Cuba, Republic of
|
||||
+ "CV" + "CPV" // Cape Verde, Republic of
|
||||
+ "CW" + "CUW" // Cura\u00e7ao
|
||||
+ "CX" + "CXR" // Christmas Island
|
||||
+ "CY" + "CYP" // Cyprus, Republic of
|
||||
+ "CZ" + "CZE" // Czech Republic
|
||||
+ "DE" + "DEU" // Germany
|
||||
+ "DJ" + "DJI" // Djibouti, Republic of
|
||||
+ "DK" + "DNK" // Denmark, Kingdom of
|
||||
+ "DM" + "DMA" // Dominica, Commonwealth of
|
||||
+ "DO" + "DOM" // Dominican Republic
|
||||
+ "DZ" + "DZA" // Algeria, People's Democratic Republic of
|
||||
+ "EC" + "ECU" // Ecuador, Republic of
|
||||
+ "EE" + "EST" // Estonia
|
||||
+ "EG" + "EGY" // Egypt, Arab Republic of
|
||||
+ "EH" + "ESH" // Western Sahara
|
||||
+ "ER" + "ERI" // Eritrea
|
||||
+ "ES" + "ESP" // Spain, Spanish State
|
||||
+ "ET" + "ETH" // Ethiopia
|
||||
+ "FI" + "FIN" // Finland, Republic of
|
||||
+ "FJ" + "FJI" // Fiji, Republic of the Fiji Islands
|
||||
+ "FK" + "FLK" // Falkland Islands (Malvinas)
|
||||
+ "FM" + "FSM" // Micronesia, Federated States of
|
||||
+ "FO" + "FRO" // Faeroe Islands
|
||||
+ "FR" + "FRA" // France, French Republic
|
||||
+ "GA" + "GAB" // Gabon, Gabonese Republic
|
||||
+ "GB" + "GBR" // United Kingdom of Great Britain & N. Ireland
|
||||
+ "GD" + "GRD" // Grenada
|
||||
+ "GE" + "GEO" // Georgia
|
||||
+ "GF" + "GUF" // French Guiana
|
||||
+ "GG" + "GGY" // Guernsey
|
||||
+ "GH" + "GHA" // Ghana, Republic of
|
||||
+ "GI" + "GIB" // Gibraltar
|
||||
+ "GL" + "GRL" // Greenland
|
||||
+ "GM" + "GMB" // Gambia, Republic of the
|
||||
+ "GN" + "GIN" // Guinea, Revolutionary People's Rep'c of
|
||||
+ "GP" + "GLP" // Guadaloupe
|
||||
+ "GQ" + "GNQ" // Equatorial Guinea, Republic of
|
||||
+ "GR" + "GRC" // Greece, Hellenic Republic
|
||||
+ "GS" + "SGS" // South Georgia and the South Sandwich Islands
|
||||
+ "GT" + "GTM" // Guatemala, Republic of
|
||||
+ "GU" + "GUM" // Guam
|
||||
+ "GW" + "GNB" // Guinea-Bissau, Republic of
|
||||
+ "GY" + "GUY" // Guyana, Republic of
|
||||
+ "HK" + "HKG" // Hong Kong, Special Administrative Region of China
|
||||
+ "HM" + "HMD" // Heard and McDonald Islands
|
||||
+ "HN" + "HND" // Honduras, Republic of
|
||||
+ "HR" + "HRV" // Hrvatska (Croatia)
|
||||
+ "HT" + "HTI" // Haiti, Republic of
|
||||
+ "HU" + "HUN" // Hungary, Hungarian People's Republic
|
||||
+ "ID" + "IDN" // Indonesia, Republic of
|
||||
+ "IE" + "IRL" // Ireland
|
||||
+ "IL" + "ISR" // Israel, State of
|
||||
+ "IM" + "IMN" // Isle of Man
|
||||
+ "IN" + "IND" // India, Republic of
|
||||
+ "IO" + "IOT" // British Indian Ocean Territory (Chagos Archipelago)
|
||||
+ "IQ" + "IRQ" // Iraq, Republic of
|
||||
+ "IR" + "IRN" // Iran, Islamic Republic of
|
||||
+ "IS" + "ISL" // Iceland, Republic of
|
||||
+ "IT" + "ITA" // Italy, Italian Republic
|
||||
+ "JE" + "JEY" // Jersey
|
||||
+ "JM" + "JAM" // Jamaica
|
||||
+ "JO" + "JOR" // Jordan, Hashemite Kingdom of
|
||||
+ "JP" + "JPN" // Japan
|
||||
+ "KE" + "KEN" // Kenya, Republic of
|
||||
+ "KG" + "KGZ" // Kyrgyz Republic
|
||||
+ "KH" + "KHM" // Cambodia, Kingdom of
|
||||
+ "KI" + "KIR" // Kiribati, Republic of
|
||||
+ "KM" + "COM" // Comoros, Union of the
|
||||
+ "KN" + "KNA" // St. Kitts and Nevis
|
||||
+ "KP" + "PRK" // Korea, Democratic People's Republic of
|
||||
+ "KR" + "KOR" // Korea, Republic of
|
||||
+ "KW" + "KWT" // Kuwait, State of
|
||||
+ "KY" + "CYM" // Cayman Islands
|
||||
+ "KZ" + "KAZ" // Kazakhstan, Republic of
|
||||
+ "LA" + "LAO" // Lao People's Democratic Republic
|
||||
+ "LB" + "LBN" // Lebanon, Lebanese Republic
|
||||
+ "LC" + "LCA" // St. Lucia
|
||||
+ "LI" + "LIE" // Liechtenstein, Principality of
|
||||
+ "LK" + "LKA" // Sri Lanka, Democratic Socialist Republic of
|
||||
+ "LR" + "LBR" // Liberia, Republic of
|
||||
+ "LS" + "LSO" // Lesotho, Kingdom of
|
||||
+ "LT" + "LTU" // Lithuania
|
||||
+ "LU" + "LUX" // Luxembourg, Grand Duchy of
|
||||
+ "LV" + "LVA" // Latvia
|
||||
+ "LY" + "LBY" // Libyan Arab Jamahiriya
|
||||
+ "MA" + "MAR" // Morocco, Kingdom of
|
||||
+ "MC" + "MCO" // Monaco, Principality of
|
||||
+ "MD" + "MDA" // Moldova, Republic of
|
||||
+ "ME" + "MNE" // Montenegro, Republic of
|
||||
+ "MF" + "MAF" // Saint Martin
|
||||
+ "MG" + "MDG" // Madagascar, Republic of
|
||||
+ "MH" + "MHL" // Marshall Islands
|
||||
+ "MK" + "MKD" // Macedonia, the former Yugoslav Republic of
|
||||
+ "ML" + "MLI" // Mali, Republic of
|
||||
+ "MM" + "MMR" // Myanmar
|
||||
+ "MN" + "MNG" // Mongolia, Mongolian People's Republic
|
||||
+ "MO" + "MAC" // Macao, Special Administrative Region of China
|
||||
+ "MP" + "MNP" // Northern Mariana Islands
|
||||
+ "MQ" + "MTQ" // Martinique
|
||||
+ "MR" + "MRT" // Mauritania, Islamic Republic of
|
||||
+ "MS" + "MSR" // Montserrat
|
||||
+ "MT" + "MLT" // Malta, Republic of
|
||||
+ "MU" + "MUS" // Mauritius
|
||||
+ "MV" + "MDV" // Maldives, Republic of
|
||||
+ "MW" + "MWI" // Malawi, Republic of
|
||||
+ "MX" + "MEX" // Mexico, United Mexican States
|
||||
+ "MY" + "MYS" // Malaysia
|
||||
+ "MZ" + "MOZ" // Mozambique, People's Republic of
|
||||
+ "NA" + "NAM" // Namibia
|
||||
+ "NC" + "NCL" // New Caledonia
|
||||
+ "NE" + "NER" // Niger, Republic of the
|
||||
+ "NF" + "NFK" // Norfolk Island
|
||||
+ "NG" + "NGA" // Nigeria, Federal Republic of
|
||||
+ "NI" + "NIC" // Nicaragua, Republic of
|
||||
+ "NL" + "NLD" // Netherlands, Kingdom of the
|
||||
+ "NO" + "NOR" // Norway, Kingdom of
|
||||
+ "NP" + "NPL" // Nepal, Kingdom of
|
||||
+ "NR" + "NRU" // Nauru, Republic of
|
||||
+ "NU" + "NIU" // Niue, Republic of
|
||||
+ "NZ" + "NZL" // New Zealand
|
||||
+ "OM" + "OMN" // Oman, Sultanate of
|
||||
+ "PA" + "PAN" // Panama, Republic of
|
||||
+ "PE" + "PER" // Peru, Republic of
|
||||
+ "PF" + "PYF" // French Polynesia
|
||||
+ "PG" + "PNG" // Papua New Guinea
|
||||
+ "PH" + "PHL" // Philippines, Republic of the
|
||||
+ "PK" + "PAK" // Pakistan, Islamic Republic of
|
||||
+ "PL" + "POL" // Poland, Republic of Poland
|
||||
+ "PM" + "SPM" // St. Pierre and Miquelon
|
||||
+ "PN" + "PCN" // Pitcairn Island
|
||||
+ "PR" + "PRI" // Puerto Rico
|
||||
+ "PS" + "PSE" // Palestinian Territory, Occupied
|
||||
+ "PT" + "PRT" // Portugal, Portuguese Republic
|
||||
+ "PW" + "PLW" // Palau
|
||||
+ "PY" + "PRY" // Paraguay, Republic of
|
||||
+ "QA" + "QAT" // Qatar, State of
|
||||
+ "RE" + "REU" // Reunion
|
||||
+ "RO" + "ROU" // Romania, Socialist Republic of
|
||||
+ "RS" + "SRB" // Serbia, Republic of
|
||||
+ "RU" + "RUS" // Russian Federation
|
||||
+ "RW" + "RWA" // Rwanda, Rwandese Republic
|
||||
+ "SA" + "SAU" // Saudi Arabia, Kingdom of
|
||||
+ "SB" + "SLB" // Solomon Islands
|
||||
+ "SC" + "SYC" // Seychelles, Republic of
|
||||
+ "SD" + "SDN" // Sudan, Democratic Republic of the
|
||||
+ "SE" + "SWE" // Sweden, Kingdom of
|
||||
+ "SG" + "SGP" // Singapore, Republic of
|
||||
+ "SH" + "SHN" // St. Helena
|
||||
+ "SI" + "SVN" // Slovenia
|
||||
+ "SJ" + "SJM" // Svalbard & Jan Mayen Islands
|
||||
+ "SK" + "SVK" // Slovakia (Slovak Republic)
|
||||
+ "SL" + "SLE" // Sierra Leone, Republic of
|
||||
+ "SM" + "SMR" // San Marino, Republic of
|
||||
+ "SN" + "SEN" // Senegal, Republic of
|
||||
+ "SO" + "SOM" // Somalia, Somali Republic
|
||||
+ "SR" + "SUR" // Suriname, Republic of
|
||||
+ "SS" + "SSD" // South Sudan
|
||||
+ "ST" + "STP" // Sao Tome and Principe, Democratic Republic of
|
||||
+ "SV" + "SLV" // El Salvador, Republic of
|
||||
+ "SX" + "SXM" // Sint Maarten (Dutch part)
|
||||
+ "SY" + "SYR" // Syrian Arab Republic
|
||||
+ "SZ" + "SWZ" // Swaziland, Kingdom of
|
||||
+ "TC" + "TCA" // Turks and Caicos Islands
|
||||
+ "TD" + "TCD" // Chad, Republic of
|
||||
+ "TF" + "ATF" // French Southern Territories
|
||||
+ "TG" + "TGO" // Togo, Togolese Republic
|
||||
+ "TH" + "THA" // Thailand, Kingdom of
|
||||
+ "TJ" + "TJK" // Tajikistan
|
||||
+ "TK" + "TKL" // Tokelau (Tokelau Islands)
|
||||
+ "TL" + "TLS" // Timor-Leste, Democratic Republic of
|
||||
+ "TM" + "TKM" // Turkmenistan
|
||||
+ "TN" + "TUN" // Tunisia, Republic of
|
||||
+ "TO" + "TON" // Tonga, Kingdom of
|
||||
+ "TR" + "TUR" // Turkey, Republic of
|
||||
+ "TT" + "TTO" // Trinidad and Tobago, Republic of
|
||||
+ "TV" + "TUV" // Tuvalu
|
||||
+ "TW" + "TWN" // Taiwan, Province of China
|
||||
+ "TZ" + "TZA" // Tanzania, United Republic of
|
||||
+ "UA" + "UKR" // Ukraine
|
||||
+ "UG" + "UGA" // Uganda, Republic of
|
||||
+ "UM" + "UMI" // United States Minor Outlying Islands
|
||||
+ "US" + "USA" // United States of America
|
||||
+ "UY" + "URY" // Uruguay, Eastern Republic of
|
||||
+ "UZ" + "UZB" // Uzbekistan
|
||||
+ "VA" + "VAT" // Holy See (Vatican City State)
|
||||
+ "VC" + "VCT" // St. Vincent and the Grenadines
|
||||
+ "VE" + "VEN" // Venezuela, Bolivarian Republic of
|
||||
+ "VG" + "VGB" // British Virgin Islands
|
||||
+ "VI" + "VIR" // US Virgin Islands
|
||||
+ "VN" + "VNM" // Viet Nam, Socialist Republic of
|
||||
+ "VU" + "VUT" // Vanuatu
|
||||
+ "WF" + "WLF" // Wallis and Futuna Islands
|
||||
+ "WS" + "WSM" // Samoa, Independent State of
|
||||
+ "YE" + "YEM" // Yemen
|
||||
+ "YT" + "MYT" // Mayotte
|
||||
+ "ZA" + "ZAF" // South Africa, Republic of
|
||||
+ "ZM" + "ZMB" // Zambia, Republic of
|
||||
+ "ZW" + "ZWE" // Zimbabwe
|
||||
;
|
||||
|
||||
private LocaleISOData() {
|
||||
}
|
||||
}
|
||||
183
jdkSrc/jdk8/java/util/LongSummaryStatistics.java
Normal file
183
jdkSrc/jdk8/java/util/LongSummaryStatistics.java
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.util;
|
||||
|
||||
import java.util.function.IntConsumer;
|
||||
import java.util.function.LongConsumer;
|
||||
import java.util.stream.Collector;
|
||||
|
||||
/**
|
||||
* A state object for collecting statistics such as count, min, max, sum, and
|
||||
* average.
|
||||
*
|
||||
* <p>This class is designed to work with (though does not require)
|
||||
* {@linkplain java.util.stream streams}. For example, you can compute
|
||||
* summary statistics on a stream of longs with:
|
||||
* <pre> {@code
|
||||
* LongSummaryStatistics stats = longStream.collect(LongSummaryStatistics::new,
|
||||
* LongSummaryStatistics::accept,
|
||||
* LongSummaryStatistics::combine);
|
||||
* }</pre>
|
||||
*
|
||||
* <p>{@code LongSummaryStatistics} can be used as a
|
||||
* {@linkplain java.util.stream.Stream#collect(Collector)} reduction}
|
||||
* target for a {@linkplain java.util.stream.Stream stream}. For example:
|
||||
*
|
||||
* <pre> {@code
|
||||
* LongSummaryStatistics stats = people.stream()
|
||||
* .collect(Collectors.summarizingLong(Person::getAge));
|
||||
*}</pre>
|
||||
*
|
||||
* This computes, in a single pass, the count of people, as well as the minimum,
|
||||
* maximum, sum, and average of their ages.
|
||||
*
|
||||
* @implNote This implementation is not thread safe. However, it is safe to use
|
||||
* {@link java.util.stream.Collectors#summarizingLong(java.util.function.ToLongFunction)
|
||||
* Collectors.toLongStatistics()} on a parallel stream, because the parallel
|
||||
* implementation of {@link java.util.stream.Stream#collect Stream.collect()}
|
||||
* provides the necessary partitioning, isolation, and merging of results for
|
||||
* safe and efficient parallel execution.
|
||||
*
|
||||
* <p>This implementation does not check for overflow of the sum.
|
||||
* @since 1.8
|
||||
*/
|
||||
public class LongSummaryStatistics implements LongConsumer, IntConsumer {
|
||||
private long count;
|
||||
private long sum;
|
||||
private long min = Long.MAX_VALUE;
|
||||
private long max = Long.MIN_VALUE;
|
||||
|
||||
/**
|
||||
* Construct an empty instance with zero count, zero sum,
|
||||
* {@code Long.MAX_VALUE} min, {@code Long.MIN_VALUE} max and zero
|
||||
* average.
|
||||
*/
|
||||
public LongSummaryStatistics() { }
|
||||
|
||||
/**
|
||||
* Records a new {@code int} value into the summary information.
|
||||
*
|
||||
* @param value the input value
|
||||
*/
|
||||
@Override
|
||||
public void accept(int value) {
|
||||
accept((long) value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Records a new {@code long} value into the summary information.
|
||||
*
|
||||
* @param value the input value
|
||||
*/
|
||||
@Override
|
||||
public void accept(long value) {
|
||||
++count;
|
||||
sum += value;
|
||||
min = Math.min(min, value);
|
||||
max = Math.max(max, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines the state of another {@code LongSummaryStatistics} into this
|
||||
* one.
|
||||
*
|
||||
* @param other another {@code LongSummaryStatistics}
|
||||
* @throws NullPointerException if {@code other} is null
|
||||
*/
|
||||
public void combine(LongSummaryStatistics other) {
|
||||
count += other.count;
|
||||
sum += other.sum;
|
||||
min = Math.min(min, other.min);
|
||||
max = Math.max(max, other.max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the count of values recorded.
|
||||
*
|
||||
* @return the count of values
|
||||
*/
|
||||
public final long getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of values recorded, or zero if no values have been
|
||||
* recorded.
|
||||
*
|
||||
* @return the sum of values, or zero if none
|
||||
*/
|
||||
public final long getSum() {
|
||||
return sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum value recorded, or {@code Long.MAX_VALUE} if no
|
||||
* values have been recorded.
|
||||
*
|
||||
* @return the minimum value, or {@code Long.MAX_VALUE} if none
|
||||
*/
|
||||
public final long getMin() {
|
||||
return min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum value recorded, or {@code Long.MIN_VALUE} if no
|
||||
* values have been recorded
|
||||
*
|
||||
* @return the maximum value, or {@code Long.MIN_VALUE} if none
|
||||
*/
|
||||
public final long getMax() {
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the arithmetic mean of values recorded, or zero if no values have been
|
||||
* recorded.
|
||||
*
|
||||
* @return The arithmetic mean of values, or zero if none
|
||||
*/
|
||||
public final double getAverage() {
|
||||
return getCount() > 0 ? (double) getSum() / getCount() : 0.0d;
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* Returns a non-empty string representation of this object suitable for
|
||||
* debugging. The exact presentation format is unspecified and may vary
|
||||
* between implementations and versions.
|
||||
*/
|
||||
public String toString() {
|
||||
return String.format(
|
||||
"%s{count=%d, sum=%d, min=%d, average=%f, max=%d}",
|
||||
this.getClass().getSimpleName(),
|
||||
getCount(),
|
||||
getSum(),
|
||||
getMin(),
|
||||
getAverage(),
|
||||
getMax());
|
||||
}
|
||||
}
|
||||
1183
jdkSrc/jdk8/java/util/Map.java
Normal file
1183
jdkSrc/jdk8/java/util/Map.java
Normal file
File diff suppressed because it is too large
Load Diff
70
jdkSrc/jdk8/java/util/MissingFormatArgumentException.java
Normal file
70
jdkSrc/jdk8/java/util/MissingFormatArgumentException.java
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* Unchecked exception thrown when there is a format specifier which does not
|
||||
* have a corresponding argument or if an argument index refers to an argument
|
||||
* that does not exist.
|
||||
*
|
||||
* <p> Unless otherwise specified, passing a <tt>null</tt> argument to any
|
||||
* method or constructor in this class will cause a {@link
|
||||
* NullPointerException} to be thrown.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class MissingFormatArgumentException extends IllegalFormatException {
|
||||
|
||||
private static final long serialVersionUID = 19190115L;
|
||||
|
||||
private String s;
|
||||
|
||||
/**
|
||||
* Constructs an instance of this class with the unmatched format
|
||||
* specifier.
|
||||
*
|
||||
* @param s
|
||||
* Format specifier which does not have a corresponding argument
|
||||
*/
|
||||
public MissingFormatArgumentException(String s) {
|
||||
if (s == null)
|
||||
throw new NullPointerException();
|
||||
this.s = s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unmatched format specifier.
|
||||
*
|
||||
* @return The unmatched format specifier
|
||||
*/
|
||||
public String getFormatSpecifier() {
|
||||
return s;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return "Format specifier '" + s + "'";
|
||||
}
|
||||
}
|
||||
68
jdkSrc/jdk8/java/util/MissingFormatWidthException.java
Normal file
68
jdkSrc/jdk8/java/util/MissingFormatWidthException.java
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* Unchecked exception thrown when the format width is required.
|
||||
*
|
||||
* <p> Unless otherwise specified, passing a <tt>null</tt> argument to any
|
||||
* method or constructor in this class will cause a {@link
|
||||
* NullPointerException} to be thrown.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class MissingFormatWidthException extends IllegalFormatException {
|
||||
|
||||
private static final long serialVersionUID = 15560123L;
|
||||
|
||||
private String s;
|
||||
|
||||
/**
|
||||
* Constructs an instance of this class with the specified format
|
||||
* specifier.
|
||||
*
|
||||
* @param s
|
||||
* The format specifier which does not have a width
|
||||
*/
|
||||
public MissingFormatWidthException(String s) {
|
||||
if (s == null)
|
||||
throw new NullPointerException();
|
||||
this.s = s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the format specifier which does not have a width.
|
||||
*
|
||||
* @return The format specifier which does not have a width
|
||||
*/
|
||||
public String getFormatSpecifier() {
|
||||
return s;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
124
jdkSrc/jdk8/java/util/MissingResourceException.java
Normal file
124
jdkSrc/jdk8/java/util/MissingResourceException.java
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
|
||||
*
|
||||
* The original version of this source code and documentation
|
||||
* is copyrighted and owned by Taligent, Inc., a wholly-owned
|
||||
* subsidiary of IBM. These materials are provided under terms
|
||||
* of a License Agreement between Taligent and Sun. This technology
|
||||
* is protected by multiple US and International patents.
|
||||
*
|
||||
* This notice and attribution to Taligent may not be removed.
|
||||
* Taligent is a registered trademark of Taligent, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* Signals that a resource is missing.
|
||||
* @see java.lang.Exception
|
||||
* @see ResourceBundle
|
||||
* @author Mark Davis
|
||||
* @since JDK1.1
|
||||
*/
|
||||
public
|
||||
class MissingResourceException extends RuntimeException {
|
||||
|
||||
/**
|
||||
* Constructs a MissingResourceException with the specified information.
|
||||
* A detail message is a String that describes this particular exception.
|
||||
* @param s the detail message
|
||||
* @param className the name of the resource class
|
||||
* @param key the key for the missing resource.
|
||||
*/
|
||||
public MissingResourceException(String s, String className, String key) {
|
||||
super(s);
|
||||
this.className = className;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>MissingResourceException</code> with
|
||||
* <code>message</code>, <code>className</code>, <code>key</code>,
|
||||
* and <code>cause</code>. This constructor is package private for
|
||||
* use by <code>ResourceBundle.getBundle</code>.
|
||||
*
|
||||
* @param message
|
||||
* the detail message
|
||||
* @param className
|
||||
* the name of the resource class
|
||||
* @param key
|
||||
* the key for the missing resource.
|
||||
* @param cause
|
||||
* the cause (which is saved for later retrieval by the
|
||||
* {@link Throwable.getCause()} method). (A null value is
|
||||
* permitted, and indicates that the cause is nonexistent
|
||||
* or unknown.)
|
||||
*/
|
||||
MissingResourceException(String message, String className, String key, Throwable cause) {
|
||||
super(message, cause);
|
||||
this.className = className;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets parameter passed by constructor.
|
||||
*
|
||||
* @return the name of the resource class
|
||||
*/
|
||||
public String getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets parameter passed by constructor.
|
||||
*
|
||||
* @return the key for the missing resource
|
||||
*/
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
//============ privates ============
|
||||
|
||||
// serialization compatibility with JDK1.1
|
||||
private static final long serialVersionUID = -4876345176062000401L;
|
||||
|
||||
/**
|
||||
* The class name of the resource bundle requested by the user.
|
||||
* @serial
|
||||
*/
|
||||
private String className;
|
||||
|
||||
/**
|
||||
* The name of the specific resource requested by the user.
|
||||
* @serial
|
||||
*/
|
||||
private String key;
|
||||
}
|
||||
424
jdkSrc/jdk8/java/util/NavigableMap.java
Normal file
424
jdkSrc/jdk8/java/util/NavigableMap.java
Normal file
@@ -0,0 +1,424 @@
|
||||
/*
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is available under and governed by the GNU General Public
|
||||
* License version 2 only, as published by the Free Software Foundation.
|
||||
* However, the following notice accompanied the original version of this
|
||||
* file:
|
||||
*
|
||||
* Written by Doug Lea and Josh Bloch with assistance from members of JCP
|
||||
* JSR-166 Expert Group and released to the public domain, as explained at
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* A {@link SortedMap} extended with navigation methods returning the
|
||||
* closest matches for given search targets. Methods
|
||||
* {@code lowerEntry}, {@code floorEntry}, {@code ceilingEntry},
|
||||
* and {@code higherEntry} return {@code Map.Entry} objects
|
||||
* associated with keys respectively less than, less than or equal,
|
||||
* greater than or equal, and greater than a given key, returning
|
||||
* {@code null} if there is no such key. Similarly, methods
|
||||
* {@code lowerKey}, {@code floorKey}, {@code ceilingKey}, and
|
||||
* {@code higherKey} return only the associated keys. All of these
|
||||
* methods are designed for locating, not traversing entries.
|
||||
*
|
||||
* <p>A {@code NavigableMap} may be accessed and traversed in either
|
||||
* ascending or descending key order. The {@code descendingMap}
|
||||
* method returns a view of the map with the senses of all relational
|
||||
* and directional methods inverted. The performance of ascending
|
||||
* operations and views is likely to be faster than that of descending
|
||||
* ones. Methods {@code subMap}, {@code headMap},
|
||||
* and {@code tailMap} differ from the like-named {@code
|
||||
* SortedMap} methods in accepting additional arguments describing
|
||||
* whether lower and upper bounds are inclusive versus exclusive.
|
||||
* Submaps of any {@code NavigableMap} must implement the {@code
|
||||
* NavigableMap} interface.
|
||||
*
|
||||
* <p>This interface additionally defines methods {@code firstEntry},
|
||||
* {@code pollFirstEntry}, {@code lastEntry}, and
|
||||
* {@code pollLastEntry} that return and/or remove the least and
|
||||
* greatest mappings, if any exist, else returning {@code null}.
|
||||
*
|
||||
* <p>Implementations of entry-returning methods are expected to
|
||||
* return {@code Map.Entry} pairs representing snapshots of mappings
|
||||
* at the time they were produced, and thus generally do <em>not</em>
|
||||
* support the optional {@code Entry.setValue} method. Note however
|
||||
* that it is possible to change mappings in the associated map using
|
||||
* method {@code put}.
|
||||
*
|
||||
* <p>Methods
|
||||
* {@link #subMap(Object, Object) subMap(K, K)},
|
||||
* {@link #headMap(Object) headMap(K)}, and
|
||||
* {@link #tailMap(Object) tailMap(K)}
|
||||
* are specified to return {@code SortedMap} to allow existing
|
||||
* implementations of {@code SortedMap} to be compatibly retrofitted to
|
||||
* implement {@code NavigableMap}, but extensions and implementations
|
||||
* of this interface are encouraged to override these methods to return
|
||||
* {@code NavigableMap}. Similarly,
|
||||
* {@link #keySet()} can be overriden to return {@code NavigableSet}.
|
||||
*
|
||||
* <p>This interface is a member of the
|
||||
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
|
||||
* Java Collections Framework</a>.
|
||||
*
|
||||
* @author Doug Lea
|
||||
* @author Josh Bloch
|
||||
* @param <K> the type of keys maintained by this map
|
||||
* @param <V> the type of mapped values
|
||||
* @since 1.6
|
||||
*/
|
||||
public interface NavigableMap<K,V> extends SortedMap<K,V> {
|
||||
/**
|
||||
* Returns a key-value mapping associated with the greatest key
|
||||
* strictly less than the given key, or {@code null} if there is
|
||||
* no such key.
|
||||
*
|
||||
* @param key the key
|
||||
* @return an entry with the greatest key less than {@code key},
|
||||
* or {@code null} if there is no such key
|
||||
* @throws ClassCastException if the specified key cannot be compared
|
||||
* with the keys currently in the map
|
||||
* @throws NullPointerException if the specified key is null
|
||||
* and this map does not permit null keys
|
||||
*/
|
||||
Map.Entry<K,V> lowerEntry(K key);
|
||||
|
||||
/**
|
||||
* Returns the greatest key strictly less than the given key, or
|
||||
* {@code null} if there is no such key.
|
||||
*
|
||||
* @param key the key
|
||||
* @return the greatest key less than {@code key},
|
||||
* or {@code null} if there is no such key
|
||||
* @throws ClassCastException if the specified key cannot be compared
|
||||
* with the keys currently in the map
|
||||
* @throws NullPointerException if the specified key is null
|
||||
* and this map does not permit null keys
|
||||
*/
|
||||
K lowerKey(K key);
|
||||
|
||||
/**
|
||||
* Returns a key-value mapping associated with the greatest key
|
||||
* less than or equal to the given key, or {@code null} if there
|
||||
* is no such key.
|
||||
*
|
||||
* @param key the key
|
||||
* @return an entry with the greatest key less than or equal to
|
||||
* {@code key}, or {@code null} if there is no such key
|
||||
* @throws ClassCastException if the specified key cannot be compared
|
||||
* with the keys currently in the map
|
||||
* @throws NullPointerException if the specified key is null
|
||||
* and this map does not permit null keys
|
||||
*/
|
||||
Map.Entry<K,V> floorEntry(K key);
|
||||
|
||||
/**
|
||||
* Returns the greatest key less than or equal to the given key,
|
||||
* or {@code null} if there is no such key.
|
||||
*
|
||||
* @param key the key
|
||||
* @return the greatest key less than or equal to {@code key},
|
||||
* or {@code null} if there is no such key
|
||||
* @throws ClassCastException if the specified key cannot be compared
|
||||
* with the keys currently in the map
|
||||
* @throws NullPointerException if the specified key is null
|
||||
* and this map does not permit null keys
|
||||
*/
|
||||
K floorKey(K key);
|
||||
|
||||
/**
|
||||
* Returns a key-value mapping associated with the least key
|
||||
* greater than or equal to the given key, or {@code null} if
|
||||
* there is no such key.
|
||||
*
|
||||
* @param key the key
|
||||
* @return an entry with the least key greater than or equal to
|
||||
* {@code key}, or {@code null} if there is no such key
|
||||
* @throws ClassCastException if the specified key cannot be compared
|
||||
* with the keys currently in the map
|
||||
* @throws NullPointerException if the specified key is null
|
||||
* and this map does not permit null keys
|
||||
*/
|
||||
Map.Entry<K,V> ceilingEntry(K key);
|
||||
|
||||
/**
|
||||
* Returns the least key greater than or equal to the given key,
|
||||
* or {@code null} if there is no such key.
|
||||
*
|
||||
* @param key the key
|
||||
* @return the least key greater than or equal to {@code key},
|
||||
* or {@code null} if there is no such key
|
||||
* @throws ClassCastException if the specified key cannot be compared
|
||||
* with the keys currently in the map
|
||||
* @throws NullPointerException if the specified key is null
|
||||
* and this map does not permit null keys
|
||||
*/
|
||||
K ceilingKey(K key);
|
||||
|
||||
/**
|
||||
* Returns a key-value mapping associated with the least key
|
||||
* strictly greater than the given key, or {@code null} if there
|
||||
* is no such key.
|
||||
*
|
||||
* @param key the key
|
||||
* @return an entry with the least key greater than {@code key},
|
||||
* or {@code null} if there is no such key
|
||||
* @throws ClassCastException if the specified key cannot be compared
|
||||
* with the keys currently in the map
|
||||
* @throws NullPointerException if the specified key is null
|
||||
* and this map does not permit null keys
|
||||
*/
|
||||
Map.Entry<K,V> higherEntry(K key);
|
||||
|
||||
/**
|
||||
* Returns the least key strictly greater than the given key, or
|
||||
* {@code null} if there is no such key.
|
||||
*
|
||||
* @param key the key
|
||||
* @return the least key greater than {@code key},
|
||||
* or {@code null} if there is no such key
|
||||
* @throws ClassCastException if the specified key cannot be compared
|
||||
* with the keys currently in the map
|
||||
* @throws NullPointerException if the specified key is null
|
||||
* and this map does not permit null keys
|
||||
*/
|
||||
K higherKey(K key);
|
||||
|
||||
/**
|
||||
* Returns a key-value mapping associated with the least
|
||||
* key in this map, or {@code null} if the map is empty.
|
||||
*
|
||||
* @return an entry with the least key,
|
||||
* or {@code null} if this map is empty
|
||||
*/
|
||||
Map.Entry<K,V> firstEntry();
|
||||
|
||||
/**
|
||||
* Returns a key-value mapping associated with the greatest
|
||||
* key in this map, or {@code null} if the map is empty.
|
||||
*
|
||||
* @return an entry with the greatest key,
|
||||
* or {@code null} if this map is empty
|
||||
*/
|
||||
Map.Entry<K,V> lastEntry();
|
||||
|
||||
/**
|
||||
* Removes and returns a key-value mapping associated with
|
||||
* the least key in this map, or {@code null} if the map is empty.
|
||||
*
|
||||
* @return the removed first entry of this map,
|
||||
* or {@code null} if this map is empty
|
||||
*/
|
||||
Map.Entry<K,V> pollFirstEntry();
|
||||
|
||||
/**
|
||||
* Removes and returns a key-value mapping associated with
|
||||
* the greatest key in this map, or {@code null} if the map is empty.
|
||||
*
|
||||
* @return the removed last entry of this map,
|
||||
* or {@code null} if this map is empty
|
||||
*/
|
||||
Map.Entry<K,V> pollLastEntry();
|
||||
|
||||
/**
|
||||
* Returns a reverse order view of the mappings contained in this map.
|
||||
* The descending map is backed by this map, so changes to the map are
|
||||
* reflected in the descending map, and vice-versa. If either map is
|
||||
* modified while an iteration over a collection view of either map
|
||||
* is in progress (except through the iterator's own {@code remove}
|
||||
* operation), the results of the iteration are undefined.
|
||||
*
|
||||
* <p>The returned map has an ordering equivalent to
|
||||
* <tt>{@link Collections#reverseOrder(Comparator) Collections.reverseOrder}(comparator())</tt>.
|
||||
* The expression {@code m.descendingMap().descendingMap()} returns a
|
||||
* view of {@code m} essentially equivalent to {@code m}.
|
||||
*
|
||||
* @return a reverse order view of this map
|
||||
*/
|
||||
NavigableMap<K,V> descendingMap();
|
||||
|
||||
/**
|
||||
* Returns a {@link NavigableSet} view of the keys contained in this map.
|
||||
* The set's iterator returns the keys in ascending order.
|
||||
* The set is backed by the map, so changes to the map are reflected in
|
||||
* the set, and vice-versa. If the map is modified while an iteration
|
||||
* over the set is in progress (except through the iterator's own {@code
|
||||
* remove} operation), the results of the iteration are undefined. The
|
||||
* set supports element removal, which removes the corresponding mapping
|
||||
* from the map, via the {@code Iterator.remove}, {@code Set.remove},
|
||||
* {@code removeAll}, {@code retainAll}, and {@code clear} operations.
|
||||
* It does not support the {@code add} or {@code addAll} operations.
|
||||
*
|
||||
* @return a navigable set view of the keys in this map
|
||||
*/
|
||||
NavigableSet<K> navigableKeySet();
|
||||
|
||||
/**
|
||||
* Returns a reverse order {@link NavigableSet} view of the keys contained in this map.
|
||||
* The set's iterator returns the keys in descending order.
|
||||
* The set is backed by the map, so changes to the map are reflected in
|
||||
* the set, and vice-versa. If the map is modified while an iteration
|
||||
* over the set is in progress (except through the iterator's own {@code
|
||||
* remove} operation), the results of the iteration are undefined. The
|
||||
* set supports element removal, which removes the corresponding mapping
|
||||
* from the map, via the {@code Iterator.remove}, {@code Set.remove},
|
||||
* {@code removeAll}, {@code retainAll}, and {@code clear} operations.
|
||||
* It does not support the {@code add} or {@code addAll} operations.
|
||||
*
|
||||
* @return a reverse order navigable set view of the keys in this map
|
||||
*/
|
||||
NavigableSet<K> descendingKeySet();
|
||||
|
||||
/**
|
||||
* Returns a view of the portion of this map whose keys range from
|
||||
* {@code fromKey} to {@code toKey}. If {@code fromKey} and
|
||||
* {@code toKey} are equal, the returned map is empty unless
|
||||
* {@code fromInclusive} and {@code toInclusive} are both true. The
|
||||
* returned map is backed by this map, so changes in the returned map are
|
||||
* reflected in this map, and vice-versa. The returned map supports all
|
||||
* optional map operations that this map supports.
|
||||
*
|
||||
* <p>The returned map will throw an {@code IllegalArgumentException}
|
||||
* on an attempt to insert a key outside of its range, or to construct a
|
||||
* submap either of whose endpoints lie outside its range.
|
||||
*
|
||||
* @param fromKey low endpoint of the keys in the returned map
|
||||
* @param fromInclusive {@code true} if the low endpoint
|
||||
* is to be included in the returned view
|
||||
* @param toKey high endpoint of the keys in the returned map
|
||||
* @param toInclusive {@code true} if the high endpoint
|
||||
* is to be included in the returned view
|
||||
* @return a view of the portion of this map whose keys range from
|
||||
* {@code fromKey} to {@code toKey}
|
||||
* @throws ClassCastException if {@code fromKey} and {@code toKey}
|
||||
* cannot be compared to one another using this map's comparator
|
||||
* (or, if the map has no comparator, using natural ordering).
|
||||
* Implementations may, but are not required to, throw this
|
||||
* exception if {@code fromKey} or {@code toKey}
|
||||
* cannot be compared to keys currently in the map.
|
||||
* @throws NullPointerException if {@code fromKey} or {@code toKey}
|
||||
* is null and this map does not permit null keys
|
||||
* @throws IllegalArgumentException if {@code fromKey} is greater than
|
||||
* {@code toKey}; or if this map itself has a restricted
|
||||
* range, and {@code fromKey} or {@code toKey} lies
|
||||
* outside the bounds of the range
|
||||
*/
|
||||
NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,
|
||||
K toKey, boolean toInclusive);
|
||||
|
||||
/**
|
||||
* Returns a view of the portion of this map whose keys are less than (or
|
||||
* equal to, if {@code inclusive} is true) {@code toKey}. The returned
|
||||
* map is backed by this map, so changes in the returned map are reflected
|
||||
* in this map, and vice-versa. The returned map supports all optional
|
||||
* map operations that this map supports.
|
||||
*
|
||||
* <p>The returned map will throw an {@code IllegalArgumentException}
|
||||
* on an attempt to insert a key outside its range.
|
||||
*
|
||||
* @param toKey high endpoint of the keys in the returned map
|
||||
* @param inclusive {@code true} if the high endpoint
|
||||
* is to be included in the returned view
|
||||
* @return a view of the portion of this map whose keys are less than
|
||||
* (or equal to, if {@code inclusive} is true) {@code toKey}
|
||||
* @throws ClassCastException if {@code toKey} is not compatible
|
||||
* with this map's comparator (or, if the map has no comparator,
|
||||
* if {@code toKey} does not implement {@link Comparable}).
|
||||
* Implementations may, but are not required to, throw this
|
||||
* exception if {@code toKey} cannot be compared to keys
|
||||
* currently in the map.
|
||||
* @throws NullPointerException if {@code toKey} is null
|
||||
* and this map does not permit null keys
|
||||
* @throws IllegalArgumentException if this map itself has a
|
||||
* restricted range, and {@code toKey} lies outside the
|
||||
* bounds of the range
|
||||
*/
|
||||
NavigableMap<K,V> headMap(K toKey, boolean inclusive);
|
||||
|
||||
/**
|
||||
* Returns a view of the portion of this map whose keys are greater than (or
|
||||
* equal to, if {@code inclusive} is true) {@code fromKey}. The returned
|
||||
* map is backed by this map, so changes in the returned map are reflected
|
||||
* in this map, and vice-versa. The returned map supports all optional
|
||||
* map operations that this map supports.
|
||||
*
|
||||
* <p>The returned map will throw an {@code IllegalArgumentException}
|
||||
* on an attempt to insert a key outside its range.
|
||||
*
|
||||
* @param fromKey low endpoint of the keys in the returned map
|
||||
* @param inclusive {@code true} if the low endpoint
|
||||
* is to be included in the returned view
|
||||
* @return a view of the portion of this map whose keys are greater than
|
||||
* (or equal to, if {@code inclusive} is true) {@code fromKey}
|
||||
* @throws ClassCastException if {@code fromKey} is not compatible
|
||||
* with this map's comparator (or, if the map has no comparator,
|
||||
* if {@code fromKey} does not implement {@link Comparable}).
|
||||
* Implementations may, but are not required to, throw this
|
||||
* exception if {@code fromKey} cannot be compared to keys
|
||||
* currently in the map.
|
||||
* @throws NullPointerException if {@code fromKey} is null
|
||||
* and this map does not permit null keys
|
||||
* @throws IllegalArgumentException if this map itself has a
|
||||
* restricted range, and {@code fromKey} lies outside the
|
||||
* bounds of the range
|
||||
*/
|
||||
NavigableMap<K,V> tailMap(K fromKey, boolean inclusive);
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>Equivalent to {@code subMap(fromKey, true, toKey, false)}.
|
||||
*
|
||||
* @throws ClassCastException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
* @throws IllegalArgumentException {@inheritDoc}
|
||||
*/
|
||||
SortedMap<K,V> subMap(K fromKey, K toKey);
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>Equivalent to {@code headMap(toKey, false)}.
|
||||
*
|
||||
* @throws ClassCastException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
* @throws IllegalArgumentException {@inheritDoc}
|
||||
*/
|
||||
SortedMap<K,V> headMap(K toKey);
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>Equivalent to {@code tailMap(fromKey, true)}.
|
||||
*
|
||||
* @throws ClassCastException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
* @throws IllegalArgumentException {@inheritDoc}
|
||||
*/
|
||||
SortedMap<K,V> tailMap(K fromKey);
|
||||
}
|
||||
319
jdkSrc/jdk8/java/util/NavigableSet.java
Normal file
319
jdkSrc/jdk8/java/util/NavigableSet.java
Normal file
@@ -0,0 +1,319 @@
|
||||
/*
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is available under and governed by the GNU General Public
|
||||
* License version 2 only, as published by the Free Software Foundation.
|
||||
* However, the following notice accompanied the original version of this
|
||||
* file:
|
||||
*
|
||||
* Written by Doug Lea and Josh Bloch with assistance from members of JCP
|
||||
* JSR-166 Expert Group and released to the public domain, as explained at
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* A {@link SortedSet} extended with navigation methods reporting
|
||||
* closest matches for given search targets. Methods {@code lower},
|
||||
* {@code floor}, {@code ceiling}, and {@code higher} return elements
|
||||
* respectively less than, less than or equal, greater than or equal,
|
||||
* and greater than a given element, returning {@code null} if there
|
||||
* is no such element. A {@code NavigableSet} may be accessed and
|
||||
* traversed in either ascending or descending order. The {@code
|
||||
* descendingSet} method returns a view of the set with the senses of
|
||||
* all relational and directional methods inverted. The performance of
|
||||
* ascending operations and views is likely to be faster than that of
|
||||
* descending ones. This interface additionally defines methods
|
||||
* {@code pollFirst} and {@code pollLast} that return and remove the
|
||||
* lowest and highest element, if one exists, else returning {@code
|
||||
* null}. Methods {@code subSet}, {@code headSet},
|
||||
* and {@code tailSet} differ from the like-named {@code
|
||||
* SortedSet} methods in accepting additional arguments describing
|
||||
* whether lower and upper bounds are inclusive versus exclusive.
|
||||
* Subsets of any {@code NavigableSet} must implement the {@code
|
||||
* NavigableSet} interface.
|
||||
*
|
||||
* <p> The return values of navigation methods may be ambiguous in
|
||||
* implementations that permit {@code null} elements. However, even
|
||||
* in this case the result can be disambiguated by checking
|
||||
* {@code contains(null)}. To avoid such issues, implementations of
|
||||
* this interface are encouraged to <em>not</em> permit insertion of
|
||||
* {@code null} elements. (Note that sorted sets of {@link
|
||||
* Comparable} elements intrinsically do not permit {@code null}.)
|
||||
*
|
||||
* <p>Methods
|
||||
* {@link #subSet(Object, Object) subSet(E, E)},
|
||||
* {@link #headSet(Object) headSet(E)}, and
|
||||
* {@link #tailSet(Object) tailSet(E)}
|
||||
* are specified to return {@code SortedSet} to allow existing
|
||||
* implementations of {@code SortedSet} to be compatibly retrofitted to
|
||||
* implement {@code NavigableSet}, but extensions and implementations
|
||||
* of this interface are encouraged to override these methods to return
|
||||
* {@code NavigableSet}.
|
||||
*
|
||||
* <p>This interface is a member of the
|
||||
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
|
||||
* Java Collections Framework</a>.
|
||||
*
|
||||
* @author Doug Lea
|
||||
* @author Josh Bloch
|
||||
* @param <E> the type of elements maintained by this set
|
||||
* @since 1.6
|
||||
*/
|
||||
public interface NavigableSet<E> extends SortedSet<E> {
|
||||
/**
|
||||
* Returns the greatest element in this set strictly less than the
|
||||
* given element, or {@code null} if there is no such element.
|
||||
*
|
||||
* @param e the value to match
|
||||
* @return the greatest element less than {@code e},
|
||||
* or {@code null} if there is no such element
|
||||
* @throws ClassCastException if the specified element cannot be
|
||||
* compared with the elements currently in the set
|
||||
* @throws NullPointerException if the specified element is null
|
||||
* and this set does not permit null elements
|
||||
*/
|
||||
E lower(E e);
|
||||
|
||||
/**
|
||||
* Returns the greatest element in this set less than or equal to
|
||||
* the given element, or {@code null} if there is no such element.
|
||||
*
|
||||
* @param e the value to match
|
||||
* @return the greatest element less than or equal to {@code e},
|
||||
* or {@code null} if there is no such element
|
||||
* @throws ClassCastException if the specified element cannot be
|
||||
* compared with the elements currently in the set
|
||||
* @throws NullPointerException if the specified element is null
|
||||
* and this set does not permit null elements
|
||||
*/
|
||||
E floor(E e);
|
||||
|
||||
/**
|
||||
* Returns the least element in this set greater than or equal to
|
||||
* the given element, or {@code null} if there is no such element.
|
||||
*
|
||||
* @param e the value to match
|
||||
* @return the least element greater than or equal to {@code e},
|
||||
* or {@code null} if there is no such element
|
||||
* @throws ClassCastException if the specified element cannot be
|
||||
* compared with the elements currently in the set
|
||||
* @throws NullPointerException if the specified element is null
|
||||
* and this set does not permit null elements
|
||||
*/
|
||||
E ceiling(E e);
|
||||
|
||||
/**
|
||||
* Returns the least element in this set strictly greater than the
|
||||
* given element, or {@code null} if there is no such element.
|
||||
*
|
||||
* @param e the value to match
|
||||
* @return the least element greater than {@code e},
|
||||
* or {@code null} if there is no such element
|
||||
* @throws ClassCastException if the specified element cannot be
|
||||
* compared with the elements currently in the set
|
||||
* @throws NullPointerException if the specified element is null
|
||||
* and this set does not permit null elements
|
||||
*/
|
||||
E higher(E e);
|
||||
|
||||
/**
|
||||
* Retrieves and removes the first (lowest) element,
|
||||
* or returns {@code null} if this set is empty.
|
||||
*
|
||||
* @return the first element, or {@code null} if this set is empty
|
||||
*/
|
||||
E pollFirst();
|
||||
|
||||
/**
|
||||
* Retrieves and removes the last (highest) element,
|
||||
* or returns {@code null} if this set is empty.
|
||||
*
|
||||
* @return the last element, or {@code null} if this set is empty
|
||||
*/
|
||||
E pollLast();
|
||||
|
||||
/**
|
||||
* Returns an iterator over the elements in this set, in ascending order.
|
||||
*
|
||||
* @return an iterator over the elements in this set, in ascending order
|
||||
*/
|
||||
Iterator<E> iterator();
|
||||
|
||||
/**
|
||||
* Returns a reverse order view of the elements contained in this set.
|
||||
* The descending set is backed by this set, so changes to the set are
|
||||
* reflected in the descending set, and vice-versa. If either set is
|
||||
* modified while an iteration over either set is in progress (except
|
||||
* through the iterator's own {@code remove} operation), the results of
|
||||
* the iteration are undefined.
|
||||
*
|
||||
* <p>The returned set has an ordering equivalent to
|
||||
* <tt>{@link Collections#reverseOrder(Comparator) Collections.reverseOrder}(comparator())</tt>.
|
||||
* The expression {@code s.descendingSet().descendingSet()} returns a
|
||||
* view of {@code s} essentially equivalent to {@code s}.
|
||||
*
|
||||
* @return a reverse order view of this set
|
||||
*/
|
||||
NavigableSet<E> descendingSet();
|
||||
|
||||
/**
|
||||
* Returns an iterator over the elements in this set, in descending order.
|
||||
* Equivalent in effect to {@code descendingSet().iterator()}.
|
||||
*
|
||||
* @return an iterator over the elements in this set, in descending order
|
||||
*/
|
||||
Iterator<E> descendingIterator();
|
||||
|
||||
/**
|
||||
* Returns a view of the portion of this set whose elements range from
|
||||
* {@code fromElement} to {@code toElement}. If {@code fromElement} and
|
||||
* {@code toElement} are equal, the returned set is empty unless {@code
|
||||
* fromInclusive} and {@code toInclusive} are both true. The returned set
|
||||
* is backed by this set, so changes in the returned set are reflected in
|
||||
* this set, and vice-versa. The returned set supports all optional set
|
||||
* operations that this set supports.
|
||||
*
|
||||
* <p>The returned set will throw an {@code IllegalArgumentException}
|
||||
* on an attempt to insert an element outside its range.
|
||||
*
|
||||
* @param fromElement low endpoint of the returned set
|
||||
* @param fromInclusive {@code true} if the low endpoint
|
||||
* is to be included in the returned view
|
||||
* @param toElement high endpoint of the returned set
|
||||
* @param toInclusive {@code true} if the high endpoint
|
||||
* is to be included in the returned view
|
||||
* @return a view of the portion of this set whose elements range from
|
||||
* {@code fromElement}, inclusive, to {@code toElement}, exclusive
|
||||
* @throws ClassCastException if {@code fromElement} and
|
||||
* {@code toElement} cannot be compared to one another using this
|
||||
* set's comparator (or, if the set has no comparator, using
|
||||
* natural ordering). Implementations may, but are not required
|
||||
* to, throw this exception if {@code fromElement} or
|
||||
* {@code toElement} cannot be compared to elements currently in
|
||||
* the set.
|
||||
* @throws NullPointerException if {@code fromElement} or
|
||||
* {@code toElement} is null and this set does
|
||||
* not permit null elements
|
||||
* @throws IllegalArgumentException if {@code fromElement} is
|
||||
* greater than {@code toElement}; or if this set itself
|
||||
* has a restricted range, and {@code fromElement} or
|
||||
* {@code toElement} lies outside the bounds of the range.
|
||||
*/
|
||||
NavigableSet<E> subSet(E fromElement, boolean fromInclusive,
|
||||
E toElement, boolean toInclusive);
|
||||
|
||||
/**
|
||||
* Returns a view of the portion of this set whose elements are less than
|
||||
* (or equal to, if {@code inclusive} is true) {@code toElement}. The
|
||||
* returned set is backed by this set, so changes in the returned set are
|
||||
* reflected in this set, and vice-versa. The returned set supports all
|
||||
* optional set operations that this set supports.
|
||||
*
|
||||
* <p>The returned set will throw an {@code IllegalArgumentException}
|
||||
* on an attempt to insert an element outside its range.
|
||||
*
|
||||
* @param toElement high endpoint of the returned set
|
||||
* @param inclusive {@code true} if the high endpoint
|
||||
* is to be included in the returned view
|
||||
* @return a view of the portion of this set whose elements are less than
|
||||
* (or equal to, if {@code inclusive} is true) {@code toElement}
|
||||
* @throws ClassCastException if {@code toElement} is not compatible
|
||||
* with this set's comparator (or, if the set has no comparator,
|
||||
* if {@code toElement} does not implement {@link Comparable}).
|
||||
* Implementations may, but are not required to, throw this
|
||||
* exception if {@code toElement} cannot be compared to elements
|
||||
* currently in the set.
|
||||
* @throws NullPointerException if {@code toElement} is null and
|
||||
* this set does not permit null elements
|
||||
* @throws IllegalArgumentException if this set itself has a
|
||||
* restricted range, and {@code toElement} lies outside the
|
||||
* bounds of the range
|
||||
*/
|
||||
NavigableSet<E> headSet(E toElement, boolean inclusive);
|
||||
|
||||
/**
|
||||
* Returns a view of the portion of this set whose elements are greater
|
||||
* than (or equal to, if {@code inclusive} is true) {@code fromElement}.
|
||||
* The returned set is backed by this set, so changes in the returned set
|
||||
* are reflected in this set, and vice-versa. The returned set supports
|
||||
* all optional set operations that this set supports.
|
||||
*
|
||||
* <p>The returned set will throw an {@code IllegalArgumentException}
|
||||
* on an attempt to insert an element outside its range.
|
||||
*
|
||||
* @param fromElement low endpoint of the returned set
|
||||
* @param inclusive {@code true} if the low endpoint
|
||||
* is to be included in the returned view
|
||||
* @return a view of the portion of this set whose elements are greater
|
||||
* than or equal to {@code fromElement}
|
||||
* @throws ClassCastException if {@code fromElement} is not compatible
|
||||
* with this set's comparator (or, if the set has no comparator,
|
||||
* if {@code fromElement} does not implement {@link Comparable}).
|
||||
* Implementations may, but are not required to, throw this
|
||||
* exception if {@code fromElement} cannot be compared to elements
|
||||
* currently in the set.
|
||||
* @throws NullPointerException if {@code fromElement} is null
|
||||
* and this set does not permit null elements
|
||||
* @throws IllegalArgumentException if this set itself has a
|
||||
* restricted range, and {@code fromElement} lies outside the
|
||||
* bounds of the range
|
||||
*/
|
||||
NavigableSet<E> tailSet(E fromElement, boolean inclusive);
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>Equivalent to {@code subSet(fromElement, true, toElement, false)}.
|
||||
*
|
||||
* @throws ClassCastException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
* @throws IllegalArgumentException {@inheritDoc}
|
||||
*/
|
||||
SortedSet<E> subSet(E fromElement, E toElement);
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>Equivalent to {@code headSet(toElement, false)}.
|
||||
*
|
||||
* @throws ClassCastException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
* @throws IllegalArgumentException {@inheritDoc}
|
||||
*/
|
||||
SortedSet<E> headSet(E toElement);
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>Equivalent to {@code tailSet(fromElement, true)}.
|
||||
*
|
||||
* @throws ClassCastException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
* @throws IllegalArgumentException {@inheritDoc}
|
||||
*/
|
||||
SortedSet<E> tailSet(E fromElement);
|
||||
}
|
||||
59
jdkSrc/jdk8/java/util/NoSuchElementException.java
Normal file
59
jdkSrc/jdk8/java/util/NoSuchElementException.java
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* Thrown by various accessor methods to indicate that the element being requested
|
||||
* does not exist.
|
||||
*
|
||||
* @author unascribed
|
||||
* @see java.util.Enumeration#nextElement()
|
||||
* @see java.util.Iterator#next()
|
||||
* @since JDK1.0
|
||||
*/
|
||||
public
|
||||
class NoSuchElementException extends RuntimeException {
|
||||
private static final long serialVersionUID = 6769829250639411880L;
|
||||
|
||||
/**
|
||||
* Constructs a <code>NoSuchElementException</code> with <tt>null</tt>
|
||||
* as its error message string.
|
||||
*/
|
||||
public NoSuchElementException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>NoSuchElementException</code>, saving a reference
|
||||
* to the error message string <tt>s</tt> for later retrieval by the
|
||||
* <tt>getMessage</tt> method.
|
||||
*
|
||||
* @param s the detail message.
|
||||
*/
|
||||
public NoSuchElementException(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
293
jdkSrc/jdk8/java/util/Objects.java
Normal file
293
jdkSrc/jdk8/java/util/Objects.java
Normal file
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* This class consists of {@code static} utility methods for operating
|
||||
* on objects. These utilities include {@code null}-safe or {@code
|
||||
* null}-tolerant methods for computing the hash code of an object,
|
||||
* returning a string for an object, and comparing two objects.
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public final class Objects {
|
||||
private Objects() {
|
||||
throw new AssertionError("No java.util.Objects instances for you!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the arguments are equal to each other
|
||||
* and {@code false} otherwise.
|
||||
* Consequently, if both arguments are {@code null}, {@code true}
|
||||
* is returned and if exactly one argument is {@code null}, {@code
|
||||
* false} is returned. Otherwise, equality is determined by using
|
||||
* the {@link Object#equals equals} method of the first
|
||||
* argument.
|
||||
*
|
||||
* @param a an object
|
||||
* @param b an object to be compared with {@code a} for equality
|
||||
* @return {@code true} if the arguments are equal to each other
|
||||
* and {@code false} otherwise
|
||||
* @see Object#equals(Object)
|
||||
*/
|
||||
public static boolean equals(Object a, Object b) {
|
||||
return (a == b) || (a != null && a.equals(b));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the arguments are deeply equal to each other
|
||||
* and {@code false} otherwise.
|
||||
*
|
||||
* Two {@code null} values are deeply equal. If both arguments are
|
||||
* arrays, the algorithm in {@link Arrays#deepEquals(Object[],
|
||||
* Object[]) Arrays.deepEquals} is used to determine equality.
|
||||
* Otherwise, equality is determined by using the {@link
|
||||
* Object#equals equals} method of the first argument.
|
||||
*
|
||||
* @param a an object
|
||||
* @param b an object to be compared with {@code a} for deep equality
|
||||
* @return {@code true} if the arguments are deeply equal to each other
|
||||
* and {@code false} otherwise
|
||||
* @see Arrays#deepEquals(Object[], Object[])
|
||||
* @see Objects#equals(Object, Object)
|
||||
*/
|
||||
public static boolean deepEquals(Object a, Object b) {
|
||||
if (a == b)
|
||||
return true;
|
||||
else if (a == null || b == null)
|
||||
return false;
|
||||
else
|
||||
return Arrays.deepEquals0(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code of a non-{@code null} argument and 0 for
|
||||
* a {@code null} argument.
|
||||
*
|
||||
* @param o an object
|
||||
* @return the hash code of a non-{@code null} argument and 0 for
|
||||
* a {@code null} argument
|
||||
* @see Object#hashCode
|
||||
*/
|
||||
public static int hashCode(Object o) {
|
||||
return o != null ? o.hashCode() : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a hash code for a sequence of input values. The hash
|
||||
* code is generated as if all the input values were placed into an
|
||||
* array, and that array were hashed by calling {@link
|
||||
* Arrays#hashCode(Object[])}.
|
||||
*
|
||||
* <p>This method is useful for implementing {@link
|
||||
* Object#hashCode()} on objects containing multiple fields. For
|
||||
* example, if an object that has three fields, {@code x}, {@code
|
||||
* y}, and {@code z}, one could write:
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* @Override public int hashCode() {
|
||||
* return Objects.hash(x, y, z);
|
||||
* }
|
||||
* </pre></blockquote>
|
||||
*
|
||||
* <b>Warning: When a single object reference is supplied, the returned
|
||||
* value does not equal the hash code of that object reference.</b> This
|
||||
* value can be computed by calling {@link #hashCode(Object)}.
|
||||
*
|
||||
* @param values the values to be hashed
|
||||
* @return a hash value of the sequence of input values
|
||||
* @see Arrays#hashCode(Object[])
|
||||
* @see List#hashCode
|
||||
*/
|
||||
public static int hash(Object... values) {
|
||||
return Arrays.hashCode(values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of calling {@code toString} for a non-{@code
|
||||
* null} argument and {@code "null"} for a {@code null} argument.
|
||||
*
|
||||
* @param o an object
|
||||
* @return the result of calling {@code toString} for a non-{@code
|
||||
* null} argument and {@code "null"} for a {@code null} argument
|
||||
* @see Object#toString
|
||||
* @see String#valueOf(Object)
|
||||
*/
|
||||
public static String toString(Object o) {
|
||||
return String.valueOf(o);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of calling {@code toString} on the first
|
||||
* argument if the first argument is not {@code null} and returns
|
||||
* the second argument otherwise.
|
||||
*
|
||||
* @param o an object
|
||||
* @param nullDefault string to return if the first argument is
|
||||
* {@code null}
|
||||
* @return the result of calling {@code toString} on the first
|
||||
* argument if it is not {@code null} and the second argument
|
||||
* otherwise.
|
||||
* @see Objects#toString(Object)
|
||||
*/
|
||||
public static String toString(Object o, String nullDefault) {
|
||||
return (o != null) ? o.toString() : nullDefault;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 0 if the arguments are identical and {@code
|
||||
* c.compare(a, b)} otherwise.
|
||||
* Consequently, if both arguments are {@code null} 0
|
||||
* is returned.
|
||||
*
|
||||
* <p>Note that if one of the arguments is {@code null}, a {@code
|
||||
* NullPointerException} may or may not be thrown depending on
|
||||
* what ordering policy, if any, the {@link Comparator Comparator}
|
||||
* chooses to have for {@code null} values.
|
||||
*
|
||||
* @param <T> the type of the objects being compared
|
||||
* @param a an object
|
||||
* @param b an object to be compared with {@code a}
|
||||
* @param c the {@code Comparator} to compare the first two arguments
|
||||
* @return 0 if the arguments are identical and {@code
|
||||
* c.compare(a, b)} otherwise.
|
||||
* @see Comparable
|
||||
* @see Comparator
|
||||
*/
|
||||
public static <T> int compare(T a, T b, Comparator<? super T> c) {
|
||||
return (a == b) ? 0 : c.compare(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the specified object reference is not {@code null}. This
|
||||
* method is designed primarily for doing parameter validation in methods
|
||||
* and constructors, as demonstrated below:
|
||||
* <blockquote><pre>
|
||||
* public Foo(Bar bar) {
|
||||
* this.bar = Objects.requireNonNull(bar);
|
||||
* }
|
||||
* </pre></blockquote>
|
||||
*
|
||||
* @param obj the object reference to check for nullity
|
||||
* @param <T> the type of the reference
|
||||
* @return {@code obj} if not {@code null}
|
||||
* @throws NullPointerException if {@code obj} is {@code null}
|
||||
*/
|
||||
public static <T> T requireNonNull(T obj) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException();
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the specified object reference is not {@code null} and
|
||||
* throws a customized {@link NullPointerException} if it is. This method
|
||||
* is designed primarily for doing parameter validation in methods and
|
||||
* constructors with multiple parameters, as demonstrated below:
|
||||
* <blockquote><pre>
|
||||
* public Foo(Bar bar, Baz baz) {
|
||||
* this.bar = Objects.requireNonNull(bar, "bar must not be null");
|
||||
* this.baz = Objects.requireNonNull(baz, "baz must not be null");
|
||||
* }
|
||||
* </pre></blockquote>
|
||||
*
|
||||
* @param obj the object reference to check for nullity
|
||||
* @param message detail message to be used in the event that a {@code
|
||||
* NullPointerException} is thrown
|
||||
* @param <T> the type of the reference
|
||||
* @return {@code obj} if not {@code null}
|
||||
* @throws NullPointerException if {@code obj} is {@code null}
|
||||
*/
|
||||
public static <T> T requireNonNull(T obj, String message) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException(message);
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the provided reference is {@code null} otherwise
|
||||
* returns {@code false}.
|
||||
*
|
||||
* @apiNote This method exists to be used as a
|
||||
* {@link java.util.function.Predicate}, {@code filter(Objects::isNull)}
|
||||
*
|
||||
* @param obj a reference to be checked against {@code null}
|
||||
* @return {@code true} if the provided reference is {@code null} otherwise
|
||||
* {@code false}
|
||||
*
|
||||
* @see java.util.function.Predicate
|
||||
* @since 1.8
|
||||
*/
|
||||
public static boolean isNull(Object obj) {
|
||||
return obj == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the provided reference is non-{@code null}
|
||||
* otherwise returns {@code false}.
|
||||
*
|
||||
* @apiNote This method exists to be used as a
|
||||
* {@link java.util.function.Predicate}, {@code filter(Objects::nonNull)}
|
||||
*
|
||||
* @param obj a reference to be checked against {@code null}
|
||||
* @return {@code true} if the provided reference is non-{@code null}
|
||||
* otherwise {@code false}
|
||||
*
|
||||
* @see java.util.function.Predicate
|
||||
* @since 1.8
|
||||
*/
|
||||
public static boolean nonNull(Object obj) {
|
||||
return obj != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the specified object reference is not {@code null} and
|
||||
* throws a customized {@link NullPointerException} if it is.
|
||||
*
|
||||
* <p>Unlike the method {@link #requireNonNull(Object, String)},
|
||||
* this method allows creation of the message to be deferred until
|
||||
* after the null check is made. While this may confer a
|
||||
* performance advantage in the non-null case, when deciding to
|
||||
* call this method care should be taken that the costs of
|
||||
* creating the message supplier are less than the cost of just
|
||||
* creating the string message directly.
|
||||
*
|
||||
* @param obj the object reference to check for nullity
|
||||
* @param messageSupplier supplier of the detail message to be
|
||||
* used in the event that a {@code NullPointerException} is thrown
|
||||
* @param <T> the type of the reference
|
||||
* @return {@code obj} if not {@code null}
|
||||
* @throws NullPointerException if {@code obj} is {@code null}
|
||||
* @since 1.8
|
||||
*/
|
||||
public static <T> T requireNonNull(T obj, Supplier<String> messageSupplier) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException(messageSupplier.get());
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
213
jdkSrc/jdk8/java/util/Observable.java
Normal file
213
jdkSrc/jdk8/java/util/Observable.java
Normal file
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* This class represents an observable object, or "data"
|
||||
* in the model-view paradigm. It can be subclassed to represent an
|
||||
* object that the application wants to have observed.
|
||||
* <p>
|
||||
* An observable object can have one or more observers. An observer
|
||||
* may be any object that implements interface <tt>Observer</tt>. After an
|
||||
* observable instance changes, an application calling the
|
||||
* <code>Observable</code>'s <code>notifyObservers</code> method
|
||||
* causes all of its observers to be notified of the change by a call
|
||||
* to their <code>update</code> method.
|
||||
* <p>
|
||||
* The order in which notifications will be delivered is unspecified.
|
||||
* The default implementation provided in the Observable class will
|
||||
* notify Observers in the order in which they registered interest, but
|
||||
* subclasses may change this order, use no guaranteed order, deliver
|
||||
* notifications on separate threads, or may guarantee that their
|
||||
* subclass follows this order, as they choose.
|
||||
* <p>
|
||||
* Note that this notification mechanism has nothing to do with threads
|
||||
* and is completely separate from the <tt>wait</tt> and <tt>notify</tt>
|
||||
* mechanism of class <tt>Object</tt>.
|
||||
* <p>
|
||||
* When an observable object is newly created, its set of observers is
|
||||
* empty. Two observers are considered the same if and only if the
|
||||
* <tt>equals</tt> method returns true for them.
|
||||
*
|
||||
* @author Chris Warth
|
||||
* @see java.util.Observable#notifyObservers()
|
||||
* @see java.util.Observable#notifyObservers(java.lang.Object)
|
||||
* @see java.util.Observer
|
||||
* @see java.util.Observer#update(java.util.Observable, java.lang.Object)
|
||||
* @since JDK1.0
|
||||
*/
|
||||
public class Observable {
|
||||
private boolean changed = false;
|
||||
private Vector<Observer> obs;
|
||||
|
||||
/** Construct an Observable with zero Observers. */
|
||||
|
||||
public Observable() {
|
||||
obs = new Vector<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an observer to the set of observers for this object, provided
|
||||
* that it is not the same as some observer already in the set.
|
||||
* The order in which notifications will be delivered to multiple
|
||||
* observers is not specified. See the class comment.
|
||||
*
|
||||
* @param o an observer to be added.
|
||||
* @throws NullPointerException if the parameter o is null.
|
||||
*/
|
||||
public synchronized void addObserver(Observer o) {
|
||||
if (o == null)
|
||||
throw new NullPointerException();
|
||||
if (!obs.contains(o)) {
|
||||
obs.addElement(o);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an observer from the set of observers of this object.
|
||||
* Passing <CODE>null</CODE> to this method will have no effect.
|
||||
* @param o the observer to be deleted.
|
||||
*/
|
||||
public synchronized void deleteObserver(Observer o) {
|
||||
obs.removeElement(o);
|
||||
}
|
||||
|
||||
/**
|
||||
* If this object has changed, as indicated by the
|
||||
* <code>hasChanged</code> method, then notify all of its observers
|
||||
* and then call the <code>clearChanged</code> method to
|
||||
* indicate that this object has no longer changed.
|
||||
* <p>
|
||||
* Each observer has its <code>update</code> method called with two
|
||||
* arguments: this observable object and <code>null</code>. In other
|
||||
* words, this method is equivalent to:
|
||||
* <blockquote><tt>
|
||||
* notifyObservers(null)</tt></blockquote>
|
||||
*
|
||||
* @see java.util.Observable#clearChanged()
|
||||
* @see java.util.Observable#hasChanged()
|
||||
* @see java.util.Observer#update(java.util.Observable, java.lang.Object)
|
||||
*/
|
||||
public void notifyObservers() {
|
||||
notifyObservers(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* If this object has changed, as indicated by the
|
||||
* <code>hasChanged</code> method, then notify all of its observers
|
||||
* and then call the <code>clearChanged</code> method to indicate
|
||||
* that this object has no longer changed.
|
||||
* <p>
|
||||
* Each observer has its <code>update</code> method called with two
|
||||
* arguments: this observable object and the <code>arg</code> argument.
|
||||
*
|
||||
* @param arg any object.
|
||||
* @see java.util.Observable#clearChanged()
|
||||
* @see java.util.Observable#hasChanged()
|
||||
* @see java.util.Observer#update(java.util.Observable, java.lang.Object)
|
||||
*/
|
||||
public void notifyObservers(Object arg) {
|
||||
/*
|
||||
* a temporary array buffer, used as a snapshot of the state of
|
||||
* current Observers.
|
||||
*/
|
||||
Object[] arrLocal;
|
||||
|
||||
synchronized (this) {
|
||||
/* We don't want the Observer doing callbacks into
|
||||
* arbitrary code while holding its own Monitor.
|
||||
* The code where we extract each Observable from
|
||||
* the Vector and store the state of the Observer
|
||||
* needs synchronization, but notifying observers
|
||||
* does not (should not). The worst result of any
|
||||
* potential race-condition here is that:
|
||||
* 1) a newly-added Observer will miss a
|
||||
* notification in progress
|
||||
* 2) a recently unregistered Observer will be
|
||||
* wrongly notified when it doesn't care
|
||||
*/
|
||||
if (!changed)
|
||||
return;
|
||||
arrLocal = obs.toArray();
|
||||
clearChanged();
|
||||
}
|
||||
|
||||
for (int i = arrLocal.length-1; i>=0; i--)
|
||||
((Observer)arrLocal[i]).update(this, arg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the observer list so that this object no longer has any observers.
|
||||
*/
|
||||
public synchronized void deleteObservers() {
|
||||
obs.removeAllElements();
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks this <tt>Observable</tt> object as having been changed; the
|
||||
* <tt>hasChanged</tt> method will now return <tt>true</tt>.
|
||||
*/
|
||||
protected synchronized void setChanged() {
|
||||
changed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates that this object has no longer changed, or that it has
|
||||
* already notified all of its observers of its most recent change,
|
||||
* so that the <tt>hasChanged</tt> method will now return <tt>false</tt>.
|
||||
* This method is called automatically by the
|
||||
* <code>notifyObservers</code> methods.
|
||||
*
|
||||
* @see java.util.Observable#notifyObservers()
|
||||
* @see java.util.Observable#notifyObservers(java.lang.Object)
|
||||
*/
|
||||
protected synchronized void clearChanged() {
|
||||
changed = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if this object has changed.
|
||||
*
|
||||
* @return <code>true</code> if and only if the <code>setChanged</code>
|
||||
* method has been called more recently than the
|
||||
* <code>clearChanged</code> method on this object;
|
||||
* <code>false</code> otherwise.
|
||||
* @see java.util.Observable#clearChanged()
|
||||
* @see java.util.Observable#setChanged()
|
||||
*/
|
||||
public synchronized boolean hasChanged() {
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of observers of this <tt>Observable</tt> object.
|
||||
*
|
||||
* @return the number of observers of this object.
|
||||
*/
|
||||
public synchronized int countObservers() {
|
||||
return obs.size();
|
||||
}
|
||||
}
|
||||
47
jdkSrc/jdk8/java/util/Observer.java
Normal file
47
jdkSrc/jdk8/java/util/Observer.java
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 1998, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* A class can implement the <code>Observer</code> interface when it
|
||||
* wants to be informed of changes in observable objects.
|
||||
*
|
||||
* @author Chris Warth
|
||||
* @see java.util.Observable
|
||||
* @since JDK1.0
|
||||
*/
|
||||
public interface Observer {
|
||||
/**
|
||||
* This method is called whenever the observed object is changed. An
|
||||
* application calls an <tt>Observable</tt> object's
|
||||
* <code>notifyObservers</code> method to have all the object's
|
||||
* observers notified of the change.
|
||||
*
|
||||
* @param o the observable object.
|
||||
* @param arg an argument passed to the <code>notifyObservers</code>
|
||||
* method.
|
||||
*/
|
||||
void update(Observable o, Object arg);
|
||||
}
|
||||
349
jdkSrc/jdk8/java/util/Optional.java
Normal file
349
jdkSrc/jdk8/java/util/Optional.java
Normal file
@@ -0,0 +1,349 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.util;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* A container object which may or may not contain a non-null value.
|
||||
* If a value is present, {@code isPresent()} will return {@code true} and
|
||||
* {@code get()} will return the value.
|
||||
*
|
||||
* <p>Additional methods that depend on the presence or absence of a contained
|
||||
* value are provided, such as {@link #orElse(java.lang.Object) orElse()}
|
||||
* (return a default value if value not present) and
|
||||
* {@link #ifPresent(java.util.function.Consumer) ifPresent()} (execute a block
|
||||
* of code if the value is present).
|
||||
*
|
||||
* <p>This is a <a href="../lang/doc-files/ValueBased.html">value-based</a>
|
||||
* class; use of identity-sensitive operations (including reference equality
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code Optional} may have unpredictable results and should be avoided.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public final class Optional<T> {
|
||||
/**
|
||||
* Common instance for {@code empty()}.
|
||||
*/
|
||||
private static final Optional<?> EMPTY = new Optional<>();
|
||||
|
||||
/**
|
||||
* If non-null, the value; if null, indicates no value is present
|
||||
*/
|
||||
private final T value;
|
||||
|
||||
/**
|
||||
* Constructs an empty instance.
|
||||
*
|
||||
* @implNote Generally only one empty instance, {@link Optional#EMPTY},
|
||||
* should exist per VM.
|
||||
*/
|
||||
private Optional() {
|
||||
this.value = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an empty {@code Optional} instance. No value is present for this
|
||||
* Optional.
|
||||
*
|
||||
* @apiNote Though it may be tempting to do so, avoid testing if an object
|
||||
* is empty by comparing with {@code ==} against instances returned by
|
||||
* {@code Option.empty()}. There is no guarantee that it is a singleton.
|
||||
* Instead, use {@link #isPresent()}.
|
||||
*
|
||||
* @param <T> Type of the non-existent value
|
||||
* @return an empty {@code Optional}
|
||||
*/
|
||||
public static<T> Optional<T> empty() {
|
||||
@SuppressWarnings("unchecked")
|
||||
Optional<T> t = (Optional<T>) EMPTY;
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance with the value present.
|
||||
*
|
||||
* @param value the non-null value to be present
|
||||
* @throws NullPointerException if value is null
|
||||
*/
|
||||
private Optional(T value) {
|
||||
this.value = Objects.requireNonNull(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@code Optional} with the specified present non-null value.
|
||||
*
|
||||
* @param <T> the class of the value
|
||||
* @param value the value to be present, which must be non-null
|
||||
* @return an {@code Optional} with the value present
|
||||
* @throws NullPointerException if value is null
|
||||
*/
|
||||
public static <T> Optional<T> of(T value) {
|
||||
return new Optional<>(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@code Optional} describing the specified value, if non-null,
|
||||
* otherwise returns an empty {@code Optional}.
|
||||
*
|
||||
* @param <T> the class of the value
|
||||
* @param value the possibly-null value to describe
|
||||
* @return an {@code Optional} with a present value if the specified value
|
||||
* is non-null, otherwise an empty {@code Optional}
|
||||
*/
|
||||
public static <T> Optional<T> ofNullable(T value) {
|
||||
return value == null ? empty() : of(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* If a value is present in this {@code Optional}, returns the value,
|
||||
* otherwise throws {@code NoSuchElementException}.
|
||||
*
|
||||
* @return the non-null value held by this {@code Optional}
|
||||
* @throws NoSuchElementException if there is no value present
|
||||
*
|
||||
* @see Optional#isPresent()
|
||||
*/
|
||||
public T get() {
|
||||
if (value == null) {
|
||||
throw new NoSuchElementException("No value present");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if there is a value present, otherwise {@code false}.
|
||||
*
|
||||
* @return {@code true} if there is a value present, otherwise {@code false}
|
||||
*/
|
||||
public boolean isPresent() {
|
||||
return value != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a value is present, invoke the specified consumer with the value,
|
||||
* otherwise do nothing.
|
||||
*
|
||||
* @param consumer block to be executed if a value is present
|
||||
* @throws NullPointerException if value is present and {@code consumer} is
|
||||
* null
|
||||
*/
|
||||
public void ifPresent(Consumer<? super T> consumer) {
|
||||
if (value != null)
|
||||
consumer.accept(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* If a value is present, and the value matches the given predicate,
|
||||
* return an {@code Optional} describing the value, otherwise return an
|
||||
* empty {@code Optional}.
|
||||
*
|
||||
* @param predicate a predicate to apply to the value, if present
|
||||
* @return an {@code Optional} describing the value of this {@code Optional}
|
||||
* if a value is present and the value matches the given predicate,
|
||||
* otherwise an empty {@code Optional}
|
||||
* @throws NullPointerException if the predicate is null
|
||||
*/
|
||||
public Optional<T> filter(Predicate<? super T> predicate) {
|
||||
Objects.requireNonNull(predicate);
|
||||
if (!isPresent())
|
||||
return this;
|
||||
else
|
||||
return predicate.test(value) ? this : empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* If a value is present, apply the provided mapping function to it,
|
||||
* and if the result is non-null, return an {@code Optional} describing the
|
||||
* result. Otherwise return an empty {@code Optional}.
|
||||
*
|
||||
* @apiNote This method supports post-processing on optional values, without
|
||||
* the need to explicitly check for a return status. For example, the
|
||||
* following code traverses a stream of file names, selects one that has
|
||||
* not yet been processed, and then opens that file, returning an
|
||||
* {@code Optional<FileInputStream>}:
|
||||
*
|
||||
* <pre>{@code
|
||||
* Optional<FileInputStream> fis =
|
||||
* names.stream().filter(name -> !isProcessedYet(name))
|
||||
* .findFirst()
|
||||
* .map(name -> new FileInputStream(name));
|
||||
* }</pre>
|
||||
*
|
||||
* Here, {@code findFirst} returns an {@code Optional<String>}, and then
|
||||
* {@code map} returns an {@code Optional<FileInputStream>} for the desired
|
||||
* file if one exists.
|
||||
*
|
||||
* @param <U> The type of the result of the mapping function
|
||||
* @param mapper a mapping function to apply to the value, if present
|
||||
* @return an {@code Optional} describing the result of applying a mapping
|
||||
* function to the value of this {@code Optional}, if a value is present,
|
||||
* otherwise an empty {@code Optional}
|
||||
* @throws NullPointerException if the mapping function is null
|
||||
*/
|
||||
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
|
||||
Objects.requireNonNull(mapper);
|
||||
if (!isPresent())
|
||||
return empty();
|
||||
else {
|
||||
return Optional.ofNullable(mapper.apply(value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If a value is present, apply the provided {@code Optional}-bearing
|
||||
* mapping function to it, return that result, otherwise return an empty
|
||||
* {@code Optional}. This method is similar to {@link #map(Function)},
|
||||
* but the provided mapper is one whose result is already an {@code Optional},
|
||||
* and if invoked, {@code flatMap} does not wrap it with an additional
|
||||
* {@code Optional}.
|
||||
*
|
||||
* @param <U> The type parameter to the {@code Optional} returned by
|
||||
* @param mapper a mapping function to apply to the value, if present
|
||||
* the mapping function
|
||||
* @return the result of applying an {@code Optional}-bearing mapping
|
||||
* function to the value of this {@code Optional}, if a value is present,
|
||||
* otherwise an empty {@code Optional}
|
||||
* @throws NullPointerException if the mapping function is null or returns
|
||||
* a null result
|
||||
*/
|
||||
public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
|
||||
Objects.requireNonNull(mapper);
|
||||
if (!isPresent())
|
||||
return empty();
|
||||
else {
|
||||
return Objects.requireNonNull(mapper.apply(value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value if present, otherwise return {@code other}.
|
||||
*
|
||||
* @param other the value to be returned if there is no value present, may
|
||||
* be null
|
||||
* @return the value, if present, otherwise {@code other}
|
||||
*/
|
||||
public T orElse(T other) {
|
||||
return value != null ? value : other;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value if present, otherwise invoke {@code other} and return
|
||||
* the result of that invocation.
|
||||
*
|
||||
* @param other a {@code Supplier} whose result is returned if no value
|
||||
* is present
|
||||
* @return the value if present otherwise the result of {@code other.get()}
|
||||
* @throws NullPointerException if value is not present and {@code other} is
|
||||
* null
|
||||
*/
|
||||
public T orElseGet(Supplier<? extends T> other) {
|
||||
return value != null ? value : other.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the contained value, if present, otherwise throw an exception
|
||||
* to be created by the provided supplier.
|
||||
*
|
||||
* @apiNote A method reference to the exception constructor with an empty
|
||||
* argument list can be used as the supplier. For example,
|
||||
* {@code IllegalStateException::new}
|
||||
*
|
||||
* @param <X> Type of the exception to be thrown
|
||||
* @param exceptionSupplier The supplier which will return the exception to
|
||||
* be thrown
|
||||
* @return the present value
|
||||
* @throws X if there is no value present
|
||||
* @throws NullPointerException if no value is present and
|
||||
* {@code exceptionSupplier} is null
|
||||
*/
|
||||
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
|
||||
if (value != null) {
|
||||
return value;
|
||||
} else {
|
||||
throw exceptionSupplier.get();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether some other object is "equal to" this Optional. The
|
||||
* other object is considered equal if:
|
||||
* <ul>
|
||||
* <li>it is also an {@code Optional} and;
|
||||
* <li>both instances have no value present or;
|
||||
* <li>the present values are "equal to" each other via {@code equals()}.
|
||||
* </ul>
|
||||
*
|
||||
* @param obj an object to be tested for equality
|
||||
* @return {code true} if the other object is "equal to" this object
|
||||
* otherwise {@code false}
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof Optional)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Optional<?> other = (Optional<?>) obj;
|
||||
return Objects.equals(value, other.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code value of the present value, if any, or 0 (zero) if
|
||||
* no value is present.
|
||||
*
|
||||
* @return hash code value of the present value or 0 if no value is present
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a non-empty string representation of this Optional suitable for
|
||||
* debugging. The exact presentation format is unspecified and may vary
|
||||
* between implementations and versions.
|
||||
*
|
||||
* @implSpec If a value is present the result must include its string
|
||||
* representation in the result. Empty and present Optionals must be
|
||||
* unambiguously differentiable.
|
||||
*
|
||||
* @return the string representation of this instance
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return value != null
|
||||
? String.format("Optional[%s]", value)
|
||||
: "Optional.empty";
|
||||
}
|
||||
}
|
||||
252
jdkSrc/jdk8/java/util/OptionalDouble.java
Normal file
252
jdkSrc/jdk8/java/util/OptionalDouble.java
Normal file
@@ -0,0 +1,252 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.util;
|
||||
|
||||
import java.util.function.DoubleConsumer;
|
||||
import java.util.function.DoubleSupplier;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* A container object which may or may not contain a {@code double} value.
|
||||
* If a value is present, {@code isPresent()} will return {@code true} and
|
||||
* {@code getAsDouble()} will return the value.
|
||||
*
|
||||
* <p>Additional methods that depend on the presence or absence of a contained
|
||||
* value are provided, such as {@link #orElse(double) orElse()}
|
||||
* (return a default value if value not present) and
|
||||
* {@link #ifPresent(java.util.function.DoubleConsumer) ifPresent()} (execute a block
|
||||
* of code if the value is present).
|
||||
*
|
||||
* <p>This is a <a href="../lang/doc-files/ValueBased.html">value-based</a>
|
||||
* class; use of identity-sensitive operations (including reference equality
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code OptionalDouble} may have unpredictable results and should be avoided.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public final class OptionalDouble {
|
||||
/**
|
||||
* Common instance for {@code empty()}.
|
||||
*/
|
||||
private static final OptionalDouble EMPTY = new OptionalDouble();
|
||||
|
||||
/**
|
||||
* If true then the value is present, otherwise indicates no value is present
|
||||
*/
|
||||
private final boolean isPresent;
|
||||
private final double value;
|
||||
|
||||
/**
|
||||
* Construct an empty instance.
|
||||
*
|
||||
* @implNote generally only one empty instance, {@link OptionalDouble#EMPTY},
|
||||
* should exist per VM.
|
||||
*/
|
||||
private OptionalDouble() {
|
||||
this.isPresent = false;
|
||||
this.value = Double.NaN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an empty {@code OptionalDouble} instance. No value is present for this
|
||||
* OptionalDouble.
|
||||
*
|
||||
* @apiNote Though it may be tempting to do so, avoid testing if an object
|
||||
* is empty by comparing with {@code ==} against instances returned by
|
||||
* {@code Option.empty()}. There is no guarantee that it is a singleton.
|
||||
* Instead, use {@link #isPresent()}.
|
||||
*
|
||||
* @return an empty {@code OptionalDouble}.
|
||||
*/
|
||||
public static OptionalDouble empty() {
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an instance with the value present.
|
||||
*
|
||||
* @param value the double value to be present.
|
||||
*/
|
||||
private OptionalDouble(double value) {
|
||||
this.isPresent = true;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an {@code OptionalDouble} with the specified value present.
|
||||
*
|
||||
* @param value the value to be present
|
||||
* @return an {@code OptionalDouble} with the value present
|
||||
*/
|
||||
public static OptionalDouble of(double value) {
|
||||
return new OptionalDouble(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* If a value is present in this {@code OptionalDouble}, returns the value,
|
||||
* otherwise throws {@code NoSuchElementException}.
|
||||
*
|
||||
* @return the value held by this {@code OptionalDouble}
|
||||
* @throws NoSuchElementException if there is no value present
|
||||
*
|
||||
* @see OptionalDouble#isPresent()
|
||||
*/
|
||||
public double getAsDouble() {
|
||||
if (!isPresent) {
|
||||
throw new NoSuchElementException("No value present");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if there is a value present, otherwise {@code false}.
|
||||
*
|
||||
* @return {@code true} if there is a value present, otherwise {@code false}
|
||||
*/
|
||||
public boolean isPresent() {
|
||||
return isPresent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Have the specified consumer accept the value if a value is present,
|
||||
* otherwise do nothing.
|
||||
*
|
||||
* @param consumer block to be executed if a value is present
|
||||
* @throws NullPointerException if value is present and {@code consumer} is
|
||||
* null
|
||||
*/
|
||||
public void ifPresent(DoubleConsumer consumer) {
|
||||
if (isPresent)
|
||||
consumer.accept(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value if present, otherwise return {@code other}.
|
||||
*
|
||||
* @param other the value to be returned if there is no value present
|
||||
* @return the value, if present, otherwise {@code other}
|
||||
*/
|
||||
public double orElse(double other) {
|
||||
return isPresent ? value : other;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value if present, otherwise invoke {@code other} and return
|
||||
* the result of that invocation.
|
||||
*
|
||||
* @param other a {@code DoubleSupplier} whose result is returned if no value
|
||||
* is present
|
||||
* @return the value if present otherwise the result of {@code other.getAsDouble()}
|
||||
* @throws NullPointerException if value is not present and {@code other} is
|
||||
* null
|
||||
*/
|
||||
public double orElseGet(DoubleSupplier other) {
|
||||
return isPresent ? value : other.getAsDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the contained value, if present, otherwise throw an exception
|
||||
* to be created by the provided supplier.
|
||||
*
|
||||
* @apiNote A method reference to the exception constructor with an empty
|
||||
* argument list can be used as the supplier. For example,
|
||||
* {@code IllegalStateException::new}
|
||||
*
|
||||
* @param <X> Type of the exception to be thrown
|
||||
* @param exceptionSupplier The supplier which will return the exception to
|
||||
* be thrown
|
||||
* @return the present value
|
||||
* @throws X if there is no value present
|
||||
* @throws NullPointerException if no value is present and
|
||||
* {@code exceptionSupplier} is null
|
||||
*/
|
||||
public<X extends Throwable> double orElseThrow(Supplier<X> exceptionSupplier) throws X {
|
||||
if (isPresent) {
|
||||
return value;
|
||||
} else {
|
||||
throw exceptionSupplier.get();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether some other object is "equal to" this OptionalDouble. The
|
||||
* other object is considered equal if:
|
||||
* <ul>
|
||||
* <li>it is also an {@code OptionalDouble} and;
|
||||
* <li>both instances have no value present or;
|
||||
* <li>the present values are "equal to" each other via {@code Double.compare() == 0}.
|
||||
* </ul>
|
||||
*
|
||||
* @param obj an object to be tested for equality
|
||||
* @return {code true} if the other object is "equal to" this object
|
||||
* otherwise {@code false}
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof OptionalDouble)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OptionalDouble other = (OptionalDouble) obj;
|
||||
return (isPresent && other.isPresent)
|
||||
? Double.compare(value, other.value) == 0
|
||||
: isPresent == other.isPresent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code value of the present value, if any, or 0 (zero) if
|
||||
* no value is present.
|
||||
*
|
||||
* @return hash code value of the present value or 0 if no value is present
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return isPresent ? Double.hashCode(value) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* Returns a non-empty string representation of this object suitable for
|
||||
* debugging. The exact presentation format is unspecified and may vary
|
||||
* between implementations and versions.
|
||||
*
|
||||
* @implSpec If a value is present the result must include its string
|
||||
* representation in the result. Empty and present instances must be
|
||||
* unambiguously differentiable.
|
||||
*
|
||||
* @return the string representation of this instance
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return isPresent
|
||||
? String.format("OptionalDouble[%s]", value)
|
||||
: "OptionalDouble.empty";
|
||||
}
|
||||
}
|
||||
252
jdkSrc/jdk8/java/util/OptionalInt.java
Normal file
252
jdkSrc/jdk8/java/util/OptionalInt.java
Normal file
@@ -0,0 +1,252 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.util;
|
||||
|
||||
import java.util.function.IntConsumer;
|
||||
import java.util.function.IntSupplier;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* A container object which may or may not contain a {@code int} value.
|
||||
* If a value is present, {@code isPresent()} will return {@code true} and
|
||||
* {@code getAsInt()} will return the value.
|
||||
*
|
||||
* <p>Additional methods that depend on the presence or absence of a contained
|
||||
* value are provided, such as {@link #orElse(int) orElse()}
|
||||
* (return a default value if value not present) and
|
||||
* {@link #ifPresent(java.util.function.IntConsumer) ifPresent()} (execute a block
|
||||
* of code if the value is present).
|
||||
*
|
||||
* <p>This is a <a href="../lang/doc-files/ValueBased.html">value-based</a>
|
||||
* class; use of identity-sensitive operations (including reference equality
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code OptionalInt} may have unpredictable results and should be avoided.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public final class OptionalInt {
|
||||
/**
|
||||
* Common instance for {@code empty()}.
|
||||
*/
|
||||
private static final OptionalInt EMPTY = new OptionalInt();
|
||||
|
||||
/**
|
||||
* If true then the value is present, otherwise indicates no value is present
|
||||
*/
|
||||
private final boolean isPresent;
|
||||
private final int value;
|
||||
|
||||
/**
|
||||
* Construct an empty instance.
|
||||
*
|
||||
* @implNote Generally only one empty instance, {@link OptionalInt#EMPTY},
|
||||
* should exist per VM.
|
||||
*/
|
||||
private OptionalInt() {
|
||||
this.isPresent = false;
|
||||
this.value = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an empty {@code OptionalInt} instance. No value is present for this
|
||||
* OptionalInt.
|
||||
*
|
||||
* @apiNote Though it may be tempting to do so, avoid testing if an object
|
||||
* is empty by comparing with {@code ==} against instances returned by
|
||||
* {@code Option.empty()}. There is no guarantee that it is a singleton.
|
||||
* Instead, use {@link #isPresent()}.
|
||||
*
|
||||
* @return an empty {@code OptionalInt}
|
||||
*/
|
||||
public static OptionalInt empty() {
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an instance with the value present.
|
||||
*
|
||||
* @param value the int value to be present
|
||||
*/
|
||||
private OptionalInt(int value) {
|
||||
this.isPresent = true;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an {@code OptionalInt} with the specified value present.
|
||||
*
|
||||
* @param value the value to be present
|
||||
* @return an {@code OptionalInt} with the value present
|
||||
*/
|
||||
public static OptionalInt of(int value) {
|
||||
return new OptionalInt(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* If a value is present in this {@code OptionalInt}, returns the value,
|
||||
* otherwise throws {@code NoSuchElementException}.
|
||||
*
|
||||
* @return the value held by this {@code OptionalInt}
|
||||
* @throws NoSuchElementException if there is no value present
|
||||
*
|
||||
* @see OptionalInt#isPresent()
|
||||
*/
|
||||
public int getAsInt() {
|
||||
if (!isPresent) {
|
||||
throw new NoSuchElementException("No value present");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if there is a value present, otherwise {@code false}.
|
||||
*
|
||||
* @return {@code true} if there is a value present, otherwise {@code false}
|
||||
*/
|
||||
public boolean isPresent() {
|
||||
return isPresent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Have the specified consumer accept the value if a value is present,
|
||||
* otherwise do nothing.
|
||||
*
|
||||
* @param consumer block to be executed if a value is present
|
||||
* @throws NullPointerException if value is present and {@code consumer} is
|
||||
* null
|
||||
*/
|
||||
public void ifPresent(IntConsumer consumer) {
|
||||
if (isPresent)
|
||||
consumer.accept(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value if present, otherwise return {@code other}.
|
||||
*
|
||||
* @param other the value to be returned if there is no value present
|
||||
* @return the value, if present, otherwise {@code other}
|
||||
*/
|
||||
public int orElse(int other) {
|
||||
return isPresent ? value : other;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value if present, otherwise invoke {@code other} and return
|
||||
* the result of that invocation.
|
||||
*
|
||||
* @param other a {@code IntSupplier} whose result is returned if no value
|
||||
* is present
|
||||
* @return the value if present otherwise the result of {@code other.getAsInt()}
|
||||
* @throws NullPointerException if value is not present and {@code other} is
|
||||
* null
|
||||
*/
|
||||
public int orElseGet(IntSupplier other) {
|
||||
return isPresent ? value : other.getAsInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the contained value, if present, otherwise throw an exception
|
||||
* to be created by the provided supplier.
|
||||
*
|
||||
* @apiNote A method reference to the exception constructor with an empty
|
||||
* argument list can be used as the supplier. For example,
|
||||
* {@code IllegalStateException::new}
|
||||
*
|
||||
* @param <X> Type of the exception to be thrown
|
||||
* @param exceptionSupplier The supplier which will return the exception to
|
||||
* be thrown
|
||||
* @return the present value
|
||||
* @throws X if there is no value present
|
||||
* @throws NullPointerException if no value is present and
|
||||
* {@code exceptionSupplier} is null
|
||||
*/
|
||||
public<X extends Throwable> int orElseThrow(Supplier<X> exceptionSupplier) throws X {
|
||||
if (isPresent) {
|
||||
return value;
|
||||
} else {
|
||||
throw exceptionSupplier.get();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether some other object is "equal to" this OptionalInt. The
|
||||
* other object is considered equal if:
|
||||
* <ul>
|
||||
* <li>it is also an {@code OptionalInt} and;
|
||||
* <li>both instances have no value present or;
|
||||
* <li>the present values are "equal to" each other via {@code ==}.
|
||||
* </ul>
|
||||
*
|
||||
* @param obj an object to be tested for equality
|
||||
* @return {code true} if the other object is "equal to" this object
|
||||
* otherwise {@code false}
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof OptionalInt)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OptionalInt other = (OptionalInt) obj;
|
||||
return (isPresent && other.isPresent)
|
||||
? value == other.value
|
||||
: isPresent == other.isPresent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code value of the present value, if any, or 0 (zero) if
|
||||
* no value is present.
|
||||
*
|
||||
* @return hash code value of the present value or 0 if no value is present
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return isPresent ? Integer.hashCode(value) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* Returns a non-empty string representation of this object suitable for
|
||||
* debugging. The exact presentation format is unspecified and may vary
|
||||
* between implementations and versions.
|
||||
*
|
||||
* @implSpec If a value is present the result must include its string
|
||||
* representation in the result. Empty and present instances must be
|
||||
* unambiguously differentiable.
|
||||
*
|
||||
* @return the string representation of this instance
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return isPresent
|
||||
? String.format("OptionalInt[%s]", value)
|
||||
: "OptionalInt.empty";
|
||||
}
|
||||
}
|
||||
252
jdkSrc/jdk8/java/util/OptionalLong.java
Normal file
252
jdkSrc/jdk8/java/util/OptionalLong.java
Normal file
@@ -0,0 +1,252 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.util;
|
||||
|
||||
import java.util.function.LongConsumer;
|
||||
import java.util.function.LongSupplier;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* A container object which may or may not contain a {@code long} value.
|
||||
* If a value is present, {@code isPresent()} will return {@code true} and
|
||||
* {@code getAsLong()} will return the value.
|
||||
*
|
||||
* <p>Additional methods that depend on the presence or absence of a contained
|
||||
* value are provided, such as {@link #orElse(long) orElse()}
|
||||
* (return a default value if value not present) and
|
||||
* {@link #ifPresent(java.util.function.LongConsumer) ifPresent()} (execute a block
|
||||
* of code if the value is present).
|
||||
*
|
||||
* <p>This is a <a href="../lang/doc-files/ValueBased.html">value-based</a>
|
||||
* class; use of identity-sensitive operations (including reference equality
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code OptionalLong} may have unpredictable results and should be avoided.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public final class OptionalLong {
|
||||
/**
|
||||
* Common instance for {@code empty()}.
|
||||
*/
|
||||
private static final OptionalLong EMPTY = new OptionalLong();
|
||||
|
||||
/**
|
||||
* If true then the value is present, otherwise indicates no value is present
|
||||
*/
|
||||
private final boolean isPresent;
|
||||
private final long value;
|
||||
|
||||
/**
|
||||
* Construct an empty instance.
|
||||
*
|
||||
* @implNote generally only one empty instance, {@link OptionalLong#EMPTY},
|
||||
* should exist per VM.
|
||||
*/
|
||||
private OptionalLong() {
|
||||
this.isPresent = false;
|
||||
this.value = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an empty {@code OptionalLong} instance. No value is present for this
|
||||
* OptionalLong.
|
||||
*
|
||||
* @apiNote Though it may be tempting to do so, avoid testing if an object
|
||||
* is empty by comparing with {@code ==} against instances returned by
|
||||
* {@code Option.empty()}. There is no guarantee that it is a singleton.
|
||||
* Instead, use {@link #isPresent()}.
|
||||
*
|
||||
* @return an empty {@code OptionalLong}.
|
||||
*/
|
||||
public static OptionalLong empty() {
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an instance with the value present.
|
||||
*
|
||||
* @param value the long value to be present
|
||||
*/
|
||||
private OptionalLong(long value) {
|
||||
this.isPresent = true;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an {@code OptionalLong} with the specified value present.
|
||||
*
|
||||
* @param value the value to be present
|
||||
* @return an {@code OptionalLong} with the value present
|
||||
*/
|
||||
public static OptionalLong of(long value) {
|
||||
return new OptionalLong(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* If a value is present in this {@code OptionalLong}, returns the value,
|
||||
* otherwise throws {@code NoSuchElementException}.
|
||||
*
|
||||
* @return the value held by this {@code OptionalLong}
|
||||
* @throws NoSuchElementException if there is no value present
|
||||
*
|
||||
* @see OptionalLong#isPresent()
|
||||
*/
|
||||
public long getAsLong() {
|
||||
if (!isPresent) {
|
||||
throw new NoSuchElementException("No value present");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if there is a value present, otherwise {@code false}.
|
||||
*
|
||||
* @return {@code true} if there is a value present, otherwise {@code false}
|
||||
*/
|
||||
public boolean isPresent() {
|
||||
return isPresent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Have the specified consumer accept the value if a value is present,
|
||||
* otherwise do nothing.
|
||||
*
|
||||
* @param consumer block to be executed if a value is present
|
||||
* @throws NullPointerException if value is present and {@code consumer} is
|
||||
* null
|
||||
*/
|
||||
public void ifPresent(LongConsumer consumer) {
|
||||
if (isPresent)
|
||||
consumer.accept(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value if present, otherwise return {@code other}.
|
||||
*
|
||||
* @param other the value to be returned if there is no value present
|
||||
* @return the value, if present, otherwise {@code other}
|
||||
*/
|
||||
public long orElse(long other) {
|
||||
return isPresent ? value : other;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value if present, otherwise invoke {@code other} and return
|
||||
* the result of that invocation.
|
||||
*
|
||||
* @param other a {@code LongSupplier} whose result is returned if no value
|
||||
* is present
|
||||
* @return the value if present otherwise the result of {@code other.getAsLong()}
|
||||
* @throws NullPointerException if value is not present and {@code other} is
|
||||
* null
|
||||
*/
|
||||
public long orElseGet(LongSupplier other) {
|
||||
return isPresent ? value : other.getAsLong();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the contained value, if present, otherwise throw an exception
|
||||
* to be created by the provided supplier.
|
||||
*
|
||||
* @apiNote A method reference to the exception constructor with an empty
|
||||
* argument list can be used as the supplier. For example,
|
||||
* {@code IllegalStateException::new}
|
||||
*
|
||||
* @param <X> Type of the exception to be thrown
|
||||
* @param exceptionSupplier The supplier which will return the exception to
|
||||
* be thrown
|
||||
* @return the present value
|
||||
* @throws X if there is no value present
|
||||
* @throws NullPointerException if no value is present and
|
||||
* {@code exceptionSupplier} is null
|
||||
*/
|
||||
public<X extends Throwable> long orElseThrow(Supplier<X> exceptionSupplier) throws X {
|
||||
if (isPresent) {
|
||||
return value;
|
||||
} else {
|
||||
throw exceptionSupplier.get();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether some other object is "equal to" this OptionalLong. The
|
||||
* other object is considered equal if:
|
||||
* <ul>
|
||||
* <li>it is also an {@code OptionalLong} and;
|
||||
* <li>both instances have no value present or;
|
||||
* <li>the present values are "equal to" each other via {@code ==}.
|
||||
* </ul>
|
||||
*
|
||||
* @param obj an object to be tested for equality
|
||||
* @return {code true} if the other object is "equal to" this object
|
||||
* otherwise {@code false}
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof OptionalLong)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OptionalLong other = (OptionalLong) obj;
|
||||
return (isPresent && other.isPresent)
|
||||
? value == other.value
|
||||
: isPresent == other.isPresent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code value of the present value, if any, or 0 (zero) if
|
||||
* no value is present.
|
||||
*
|
||||
* @return hash code value of the present value or 0 if no value is present
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return isPresent ? Long.hashCode(value) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* Returns a non-empty string representation of this object suitable for
|
||||
* debugging. The exact presentation format is unspecified and may vary
|
||||
* between implementations and versions.
|
||||
*
|
||||
* @implSpec If a value is present the result must include its string
|
||||
* representation in the result. Empty and present instances must be
|
||||
* unambiguously differentiable.
|
||||
*
|
||||
* @return the string representation of this instance
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return isPresent
|
||||
? String.format("OptionalLong[%s]", value)
|
||||
: "OptionalLong.empty";
|
||||
}
|
||||
}
|
||||
302
jdkSrc/jdk8/java/util/PrimitiveIterator.java
Normal file
302
jdkSrc/jdk8/java/util/PrimitiveIterator.java
Normal file
@@ -0,0 +1,302 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.util;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.DoubleConsumer;
|
||||
import java.util.function.IntConsumer;
|
||||
import java.util.function.LongConsumer;
|
||||
|
||||
/**
|
||||
* A base type for primitive specializations of {@code Iterator}. Specialized
|
||||
* subtypes are provided for {@link OfInt int}, {@link OfLong long}, and
|
||||
* {@link OfDouble double} values.
|
||||
*
|
||||
* <p>The specialized subtype default implementations of {@link Iterator#next}
|
||||
* and {@link Iterator#forEachRemaining(java.util.function.Consumer)} box
|
||||
* primitive values to instances of their corresponding wrapper class. Such
|
||||
* boxing may offset any advantages gained when using the primitive
|
||||
* specializations. To avoid boxing, the corresponding primitive-based methods
|
||||
* should be used. For example, {@link PrimitiveIterator.OfInt#nextInt()} and
|
||||
* {@link PrimitiveIterator.OfInt#forEachRemaining(java.util.function.IntConsumer)}
|
||||
* should be used in preference to {@link PrimitiveIterator.OfInt#next()} and
|
||||
* {@link PrimitiveIterator.OfInt#forEachRemaining(java.util.function.Consumer)}.
|
||||
*
|
||||
* <p>Iteration of primitive values using boxing-based methods
|
||||
* {@link Iterator#next next()} and
|
||||
* {@link Iterator#forEachRemaining(java.util.function.Consumer) forEachRemaining()},
|
||||
* does not affect the order in which the values, transformed to boxed values,
|
||||
* are encountered.
|
||||
*
|
||||
* @implNote
|
||||
* If the boolean system property {@code org.openjdk.java.util.stream.tripwire}
|
||||
* is set to {@code true} then diagnostic warnings are reported if boxing of
|
||||
* primitive values occur when operating on primitive subtype specializations.
|
||||
*
|
||||
* @param <T> the type of elements returned by this PrimitiveIterator. The
|
||||
* type must be a wrapper type for a primitive type, such as
|
||||
* {@code Integer} for the primitive {@code int} type.
|
||||
* @param <T_CONS> the type of primitive consumer. The type must be a
|
||||
* primitive specialization of {@link java.util.function.Consumer} for
|
||||
* {@code T}, such as {@link java.util.function.IntConsumer} for
|
||||
* {@code Integer}.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public interface PrimitiveIterator<T, T_CONS> extends Iterator<T> {
|
||||
|
||||
/**
|
||||
* Performs the given action for each remaining element, in the order
|
||||
* elements occur when iterating, until all elements have been processed
|
||||
* or the action throws an exception. Errors or runtime exceptions
|
||||
* thrown by the action are relayed to the caller.
|
||||
*
|
||||
* @param action The action to be performed for each element
|
||||
* @throws NullPointerException if the specified action is null
|
||||
*/
|
||||
@SuppressWarnings("overloads")
|
||||
void forEachRemaining(T_CONS action);
|
||||
|
||||
/**
|
||||
* An Iterator specialized for {@code int} values.
|
||||
* @since 1.8
|
||||
*/
|
||||
public static interface OfInt extends PrimitiveIterator<Integer, IntConsumer> {
|
||||
|
||||
/**
|
||||
* Returns the next {@code int} element in the iteration.
|
||||
*
|
||||
* @return the next {@code int} element in the iteration
|
||||
* @throws NoSuchElementException if the iteration has no more elements
|
||||
*/
|
||||
int nextInt();
|
||||
|
||||
/**
|
||||
* Performs the given action for each remaining element until all elements
|
||||
* have been processed or the action throws an exception. Actions are
|
||||
* performed in the order of iteration, if that order is specified.
|
||||
* Exceptions thrown by the action are relayed to the caller.
|
||||
*
|
||||
* @implSpec
|
||||
* <p>The default implementation behaves as if:
|
||||
* <pre>{@code
|
||||
* while (hasNext())
|
||||
* action.accept(nextInt());
|
||||
* }</pre>
|
||||
*
|
||||
* @param action The action to be performed for each element
|
||||
* @throws NullPointerException if the specified action is null
|
||||
*/
|
||||
default void forEachRemaining(IntConsumer action) {
|
||||
Objects.requireNonNull(action);
|
||||
while (hasNext())
|
||||
action.accept(nextInt());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @implSpec
|
||||
* The default implementation boxes the result of calling
|
||||
* {@link #nextInt()}, and returns that boxed result.
|
||||
*/
|
||||
@Override
|
||||
default Integer next() {
|
||||
if (Tripwire.ENABLED)
|
||||
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfInt.nextInt()");
|
||||
return nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @implSpec
|
||||
* If the action is an instance of {@code IntConsumer} then it is cast
|
||||
* to {@code IntConsumer} and passed to {@link #forEachRemaining};
|
||||
* otherwise the action is adapted to an instance of
|
||||
* {@code IntConsumer}, by boxing the argument of {@code IntConsumer},
|
||||
* and then passed to {@link #forEachRemaining}.
|
||||
*/
|
||||
@Override
|
||||
default void forEachRemaining(Consumer<? super Integer> action) {
|
||||
if (action instanceof IntConsumer) {
|
||||
forEachRemaining((IntConsumer) action);
|
||||
}
|
||||
else {
|
||||
// The method reference action::accept is never null
|
||||
Objects.requireNonNull(action);
|
||||
if (Tripwire.ENABLED)
|
||||
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfInt.forEachRemainingInt(action::accept)");
|
||||
forEachRemaining((IntConsumer) action::accept);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* An Iterator specialized for {@code long} values.
|
||||
* @since 1.8
|
||||
*/
|
||||
public static interface OfLong extends PrimitiveIterator<Long, LongConsumer> {
|
||||
|
||||
/**
|
||||
* Returns the next {@code long} element in the iteration.
|
||||
*
|
||||
* @return the next {@code long} element in the iteration
|
||||
* @throws NoSuchElementException if the iteration has no more elements
|
||||
*/
|
||||
long nextLong();
|
||||
|
||||
/**
|
||||
* Performs the given action for each remaining element until all elements
|
||||
* have been processed or the action throws an exception. Actions are
|
||||
* performed in the order of iteration, if that order is specified.
|
||||
* Exceptions thrown by the action are relayed to the caller.
|
||||
*
|
||||
* @implSpec
|
||||
* <p>The default implementation behaves as if:
|
||||
* <pre>{@code
|
||||
* while (hasNext())
|
||||
* action.accept(nextLong());
|
||||
* }</pre>
|
||||
*
|
||||
* @param action The action to be performed for each element
|
||||
* @throws NullPointerException if the specified action is null
|
||||
*/
|
||||
default void forEachRemaining(LongConsumer action) {
|
||||
Objects.requireNonNull(action);
|
||||
while (hasNext())
|
||||
action.accept(nextLong());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @implSpec
|
||||
* The default implementation boxes the result of calling
|
||||
* {@link #nextLong()}, and returns that boxed result.
|
||||
*/
|
||||
@Override
|
||||
default Long next() {
|
||||
if (Tripwire.ENABLED)
|
||||
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfLong.nextLong()");
|
||||
return nextLong();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @implSpec
|
||||
* If the action is an instance of {@code LongConsumer} then it is cast
|
||||
* to {@code LongConsumer} and passed to {@link #forEachRemaining};
|
||||
* otherwise the action is adapted to an instance of
|
||||
* {@code LongConsumer}, by boxing the argument of {@code LongConsumer},
|
||||
* and then passed to {@link #forEachRemaining}.
|
||||
*/
|
||||
@Override
|
||||
default void forEachRemaining(Consumer<? super Long> action) {
|
||||
if (action instanceof LongConsumer) {
|
||||
forEachRemaining((LongConsumer) action);
|
||||
}
|
||||
else {
|
||||
// The method reference action::accept is never null
|
||||
Objects.requireNonNull(action);
|
||||
if (Tripwire.ENABLED)
|
||||
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfLong.forEachRemainingLong(action::accept)");
|
||||
forEachRemaining((LongConsumer) action::accept);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An Iterator specialized for {@code double} values.
|
||||
* @since 1.8
|
||||
*/
|
||||
public static interface OfDouble extends PrimitiveIterator<Double, DoubleConsumer> {
|
||||
|
||||
/**
|
||||
* Returns the next {@code double} element in the iteration.
|
||||
*
|
||||
* @return the next {@code double} element in the iteration
|
||||
* @throws NoSuchElementException if the iteration has no more elements
|
||||
*/
|
||||
double nextDouble();
|
||||
|
||||
/**
|
||||
* Performs the given action for each remaining element until all elements
|
||||
* have been processed or the action throws an exception. Actions are
|
||||
* performed in the order of iteration, if that order is specified.
|
||||
* Exceptions thrown by the action are relayed to the caller.
|
||||
*
|
||||
* @implSpec
|
||||
* <p>The default implementation behaves as if:
|
||||
* <pre>{@code
|
||||
* while (hasNext())
|
||||
* action.accept(nextDouble());
|
||||
* }</pre>
|
||||
*
|
||||
* @param action The action to be performed for each element
|
||||
* @throws NullPointerException if the specified action is null
|
||||
*/
|
||||
default void forEachRemaining(DoubleConsumer action) {
|
||||
Objects.requireNonNull(action);
|
||||
while (hasNext())
|
||||
action.accept(nextDouble());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @implSpec
|
||||
* The default implementation boxes the result of calling
|
||||
* {@link #nextDouble()}, and returns that boxed result.
|
||||
*/
|
||||
@Override
|
||||
default Double next() {
|
||||
if (Tripwire.ENABLED)
|
||||
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfDouble.nextLong()");
|
||||
return nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @implSpec
|
||||
* If the action is an instance of {@code DoubleConsumer} then it is
|
||||
* cast to {@code DoubleConsumer} and passed to
|
||||
* {@link #forEachRemaining}; otherwise the action is adapted to
|
||||
* an instance of {@code DoubleConsumer}, by boxing the argument of
|
||||
* {@code DoubleConsumer}, and then passed to
|
||||
* {@link #forEachRemaining}.
|
||||
*/
|
||||
@Override
|
||||
default void forEachRemaining(Consumer<? super Double> action) {
|
||||
if (action instanceof DoubleConsumer) {
|
||||
forEachRemaining((DoubleConsumer) action);
|
||||
}
|
||||
else {
|
||||
// The method reference action::accept is never null
|
||||
Objects.requireNonNull(action);
|
||||
if (Tripwire.ENABLED)
|
||||
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfDouble.forEachRemainingDouble(action::accept)");
|
||||
forEachRemaining((DoubleConsumer) action::accept);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
906
jdkSrc/jdk8/java/util/PriorityQueue.java
Normal file
906
jdkSrc/jdk8/java/util/PriorityQueue.java
Normal file
@@ -0,0 +1,906 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import sun.misc.SharedSecrets;
|
||||
|
||||
/**
|
||||
* An unbounded priority {@linkplain Queue queue} based on a priority heap.
|
||||
* The elements of the priority queue are ordered according to their
|
||||
* {@linkplain Comparable natural ordering}, or by a {@link Comparator}
|
||||
* provided at queue construction time, depending on which constructor is
|
||||
* used. A priority queue does not permit {@code null} elements.
|
||||
* A priority queue relying on natural ordering also does not permit
|
||||
* insertion of non-comparable objects (doing so may result in
|
||||
* {@code ClassCastException}).
|
||||
*
|
||||
* <p>The <em>head</em> of this queue is the <em>least</em> element
|
||||
* with respect to the specified ordering. If multiple elements are
|
||||
* tied for least value, the head is one of those elements -- ties are
|
||||
* broken arbitrarily. The queue retrieval operations {@code poll},
|
||||
* {@code remove}, {@code peek}, and {@code element} access the
|
||||
* element at the head of the queue.
|
||||
*
|
||||
* <p>A priority queue is unbounded, but has an internal
|
||||
* <i>capacity</i> governing the size of an array used to store the
|
||||
* elements on the queue. It is always at least as large as the queue
|
||||
* size. As elements are added to a priority queue, its capacity
|
||||
* grows automatically. The details of the growth policy are not
|
||||
* specified.
|
||||
*
|
||||
* <p>This class and its iterator implement all of the
|
||||
* <em>optional</em> methods of the {@link Collection} and {@link
|
||||
* Iterator} interfaces. The Iterator provided in method {@link
|
||||
* #iterator()} is <em>not</em> guaranteed to traverse the elements of
|
||||
* the priority queue in any particular order. If you need ordered
|
||||
* traversal, consider using {@code Arrays.sort(pq.toArray())}.
|
||||
*
|
||||
* <p><strong>Note that this implementation is not synchronized.</strong>
|
||||
* Multiple threads should not access a {@code PriorityQueue}
|
||||
* instance concurrently if any of the threads modifies the queue.
|
||||
* Instead, use the thread-safe {@link
|
||||
* java.util.concurrent.PriorityBlockingQueue} class.
|
||||
*
|
||||
* <p>Implementation note: this implementation provides
|
||||
* O(log(n)) time for the enqueuing and dequeuing methods
|
||||
* ({@code offer}, {@code poll}, {@code remove()} and {@code add});
|
||||
* linear time for the {@code remove(Object)} and {@code contains(Object)}
|
||||
* methods; and constant time for the retrieval methods
|
||||
* ({@code peek}, {@code element}, and {@code size}).
|
||||
*
|
||||
* <p>This class is a member of the
|
||||
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
|
||||
* Java Collections Framework</a>.
|
||||
*
|
||||
* @since 1.5
|
||||
* @author Josh Bloch, Doug Lea
|
||||
* @param <E> the type of elements held in this collection
|
||||
*/
|
||||
public class PriorityQueue<E> extends AbstractQueue<E>
|
||||
implements java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = -7720805057305804111L;
|
||||
|
||||
private static final int DEFAULT_INITIAL_CAPACITY = 11;
|
||||
|
||||
/**
|
||||
* Priority queue represented as a balanced binary heap: the two
|
||||
* children of queue[n] are queue[2*n+1] and queue[2*(n+1)]. The
|
||||
* priority queue is ordered by comparator, or by the elements'
|
||||
* natural ordering, if comparator is null: For each node n in the
|
||||
* heap and each descendant d of n, n <= d. The element with the
|
||||
* lowest value is in queue[0], assuming the queue is nonempty.
|
||||
*/
|
||||
transient Object[] queue; // non-private to simplify nested class access
|
||||
|
||||
/**
|
||||
* The number of elements in the priority queue.
|
||||
*/
|
||||
private int size = 0;
|
||||
|
||||
/**
|
||||
* The comparator, or null if priority queue uses elements'
|
||||
* natural ordering.
|
||||
*/
|
||||
private final Comparator<? super E> comparator;
|
||||
|
||||
/**
|
||||
* The number of times this priority queue has been
|
||||
* <i>structurally modified</i>. See AbstractList for gory details.
|
||||
*/
|
||||
transient int modCount = 0; // non-private to simplify nested class access
|
||||
|
||||
/**
|
||||
* Creates a {@code PriorityQueue} with the default initial
|
||||
* capacity (11) that orders its elements according to their
|
||||
* {@linkplain Comparable natural ordering}.
|
||||
*/
|
||||
public PriorityQueue() {
|
||||
this(DEFAULT_INITIAL_CAPACITY, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code PriorityQueue} with the specified initial
|
||||
* capacity that orders its elements according to their
|
||||
* {@linkplain Comparable natural ordering}.
|
||||
*
|
||||
* @param initialCapacity the initial capacity for this priority queue
|
||||
* @throws IllegalArgumentException if {@code initialCapacity} is less
|
||||
* than 1
|
||||
*/
|
||||
public PriorityQueue(int initialCapacity) {
|
||||
this(initialCapacity, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code PriorityQueue} with the default initial capacity and
|
||||
* whose elements are ordered according to the specified comparator.
|
||||
*
|
||||
* @param comparator the comparator that will be used to order this
|
||||
* priority queue. If {@code null}, the {@linkplain Comparable
|
||||
* natural ordering} of the elements will be used.
|
||||
* @since 1.8
|
||||
*/
|
||||
public PriorityQueue(Comparator<? super E> comparator) {
|
||||
this(DEFAULT_INITIAL_CAPACITY, comparator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code PriorityQueue} with the specified initial capacity
|
||||
* that orders its elements according to the specified comparator.
|
||||
*
|
||||
* @param initialCapacity the initial capacity for this priority queue
|
||||
* @param comparator the comparator that will be used to order this
|
||||
* priority queue. If {@code null}, the {@linkplain Comparable
|
||||
* natural ordering} of the elements will be used.
|
||||
* @throws IllegalArgumentException if {@code initialCapacity} is
|
||||
* less than 1
|
||||
*/
|
||||
public PriorityQueue(int initialCapacity,
|
||||
Comparator<? super E> comparator) {
|
||||
// Note: This restriction of at least one is not actually needed,
|
||||
// but continues for 1.5 compatibility
|
||||
if (initialCapacity < 1)
|
||||
throw new IllegalArgumentException();
|
||||
this.queue = new Object[initialCapacity];
|
||||
this.comparator = comparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code PriorityQueue} containing the elements in the
|
||||
* specified collection. If the specified collection is an instance of
|
||||
* a {@link SortedSet} or is another {@code PriorityQueue}, this
|
||||
* priority queue will be ordered according to the same ordering.
|
||||
* Otherwise, this priority queue will be ordered according to the
|
||||
* {@linkplain Comparable natural ordering} of its elements.
|
||||
*
|
||||
* @param c the collection whose elements are to be placed
|
||||
* into this priority queue
|
||||
* @throws ClassCastException if elements of the specified collection
|
||||
* cannot be compared to one another according to the priority
|
||||
* queue's ordering
|
||||
* @throws NullPointerException if the specified collection or any
|
||||
* of its elements are null
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public PriorityQueue(Collection<? extends E> c) {
|
||||
if (c instanceof SortedSet<?>) {
|
||||
SortedSet<? extends E> ss = (SortedSet<? extends E>) c;
|
||||
this.comparator = (Comparator<? super E>) ss.comparator();
|
||||
initElementsFromCollection(ss);
|
||||
}
|
||||
else if (c instanceof PriorityQueue<?>) {
|
||||
PriorityQueue<? extends E> pq = (PriorityQueue<? extends E>) c;
|
||||
this.comparator = (Comparator<? super E>) pq.comparator();
|
||||
initFromPriorityQueue(pq);
|
||||
}
|
||||
else {
|
||||
this.comparator = null;
|
||||
initFromCollection(c);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code PriorityQueue} containing the elements in the
|
||||
* specified priority queue. This priority queue will be
|
||||
* ordered according to the same ordering as the given priority
|
||||
* queue.
|
||||
*
|
||||
* @param c the priority queue whose elements are to be placed
|
||||
* into this priority queue
|
||||
* @throws ClassCastException if elements of {@code c} cannot be
|
||||
* compared to one another according to {@code c}'s
|
||||
* ordering
|
||||
* @throws NullPointerException if the specified priority queue or any
|
||||
* of its elements are null
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public PriorityQueue(PriorityQueue<? extends E> c) {
|
||||
this.comparator = (Comparator<? super E>) c.comparator();
|
||||
initFromPriorityQueue(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code PriorityQueue} containing the elements in the
|
||||
* specified sorted set. This priority queue will be ordered
|
||||
* according to the same ordering as the given sorted set.
|
||||
*
|
||||
* @param c the sorted set whose elements are to be placed
|
||||
* into this priority queue
|
||||
* @throws ClassCastException if elements of the specified sorted
|
||||
* set cannot be compared to one another according to the
|
||||
* sorted set's ordering
|
||||
* @throws NullPointerException if the specified sorted set or any
|
||||
* of its elements are null
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public PriorityQueue(SortedSet<? extends E> c) {
|
||||
this.comparator = (Comparator<? super E>) c.comparator();
|
||||
initElementsFromCollection(c);
|
||||
}
|
||||
|
||||
private void initFromPriorityQueue(PriorityQueue<? extends E> c) {
|
||||
if (c.getClass() == PriorityQueue.class) {
|
||||
this.queue = c.toArray();
|
||||
this.size = c.size();
|
||||
} else {
|
||||
initFromCollection(c);
|
||||
}
|
||||
}
|
||||
|
||||
private void initElementsFromCollection(Collection<? extends E> c) {
|
||||
Object[] a = c.toArray();
|
||||
if (c.getClass() != ArrayList.class)
|
||||
a = Arrays.copyOf(a, a.length, Object[].class);
|
||||
int len = a.length;
|
||||
if (len == 1 || this.comparator != null)
|
||||
for (int i = 0; i < len; i++)
|
||||
if (a[i] == null)
|
||||
throw new NullPointerException();
|
||||
this.queue = a;
|
||||
this.size = a.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes queue array with elements from the given Collection.
|
||||
*
|
||||
* @param c the collection
|
||||
*/
|
||||
private void initFromCollection(Collection<? extends E> c) {
|
||||
initElementsFromCollection(c);
|
||||
heapify();
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum size of array to allocate.
|
||||
* Some VMs reserve some header words in an array.
|
||||
* Attempts to allocate larger arrays may result in
|
||||
* OutOfMemoryError: Requested array size exceeds VM limit
|
||||
*/
|
||||
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
|
||||
|
||||
/**
|
||||
* Increases the capacity of the array.
|
||||
*
|
||||
* @param minCapacity the desired minimum capacity
|
||||
*/
|
||||
private void grow(int minCapacity) {
|
||||
int oldCapacity = queue.length;
|
||||
// Double size if small; else grow by 50%
|
||||
int newCapacity = oldCapacity + ((oldCapacity < 64) ?
|
||||
(oldCapacity + 2) :
|
||||
(oldCapacity >> 1));
|
||||
// overflow-conscious code
|
||||
if (newCapacity - MAX_ARRAY_SIZE > 0)
|
||||
newCapacity = hugeCapacity(minCapacity);
|
||||
queue = Arrays.copyOf(queue, newCapacity);
|
||||
}
|
||||
|
||||
private static int hugeCapacity(int minCapacity) {
|
||||
if (minCapacity < 0) // overflow
|
||||
throw new OutOfMemoryError();
|
||||
return (minCapacity > MAX_ARRAY_SIZE) ?
|
||||
Integer.MAX_VALUE :
|
||||
MAX_ARRAY_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the specified element into this priority queue.
|
||||
*
|
||||
* @return {@code true} (as specified by {@link Collection#add})
|
||||
* @throws ClassCastException if the specified element cannot be
|
||||
* compared with elements currently in this priority queue
|
||||
* according to the priority queue's ordering
|
||||
* @throws NullPointerException if the specified element is null
|
||||
*/
|
||||
public boolean add(E e) {
|
||||
return offer(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the specified element into this priority queue.
|
||||
*
|
||||
* @return {@code true} (as specified by {@link Queue#offer})
|
||||
* @throws ClassCastException if the specified element cannot be
|
||||
* compared with elements currently in this priority queue
|
||||
* according to the priority queue's ordering
|
||||
* @throws NullPointerException if the specified element is null
|
||||
*/
|
||||
public boolean offer(E e) {
|
||||
if (e == null)
|
||||
throw new NullPointerException();
|
||||
modCount++;
|
||||
int i = size;
|
||||
if (i >= queue.length)
|
||||
grow(i + 1);
|
||||
size = i + 1;
|
||||
if (i == 0)
|
||||
queue[0] = e;
|
||||
else
|
||||
siftUp(i, e);
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public E peek() {
|
||||
return (size == 0) ? null : (E) queue[0];
|
||||
}
|
||||
|
||||
private int indexOf(Object o) {
|
||||
if (o != null) {
|
||||
for (int i = 0; i < size; i++)
|
||||
if (o.equals(queue[i]))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a single instance of the specified element from this queue,
|
||||
* if it is present. More formally, removes an element {@code e} such
|
||||
* that {@code o.equals(e)}, if this queue contains one or more such
|
||||
* elements. Returns {@code true} if and only if this queue contained
|
||||
* the specified element (or equivalently, if this queue changed as a
|
||||
* result of the call).
|
||||
*
|
||||
* @param o element to be removed from this queue, if present
|
||||
* @return {@code true} if this queue changed as a result of the call
|
||||
*/
|
||||
public boolean remove(Object o) {
|
||||
int i = indexOf(o);
|
||||
if (i == -1)
|
||||
return false;
|
||||
else {
|
||||
removeAt(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Version of remove using reference equality, not equals.
|
||||
* Needed by iterator.remove.
|
||||
*
|
||||
* @param o element to be removed from this queue, if present
|
||||
* @return {@code true} if removed
|
||||
*/
|
||||
boolean removeEq(Object o) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (o == queue[i]) {
|
||||
removeAt(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this queue contains the specified element.
|
||||
* More formally, returns {@code true} if and only if this queue contains
|
||||
* at least one element {@code e} such that {@code o.equals(e)}.
|
||||
*
|
||||
* @param o object to be checked for containment in this queue
|
||||
* @return {@code true} if this queue contains the specified element
|
||||
*/
|
||||
public boolean contains(Object o) {
|
||||
return indexOf(o) != -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing all of the elements in this queue.
|
||||
* The elements are in no particular order.
|
||||
*
|
||||
* <p>The returned array will be "safe" in that no references to it are
|
||||
* maintained by this queue. (In other words, this method must allocate
|
||||
* a new array). The caller is thus free to modify the returned array.
|
||||
*
|
||||
* <p>This method acts as bridge between array-based and collection-based
|
||||
* APIs.
|
||||
*
|
||||
* @return an array containing all of the elements in this queue
|
||||
*/
|
||||
public Object[] toArray() {
|
||||
return Arrays.copyOf(queue, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing all of the elements in this queue; the
|
||||
* runtime type of the returned array is that of the specified array.
|
||||
* The returned array elements are in no particular order.
|
||||
* If the queue fits in the specified array, it is returned therein.
|
||||
* Otherwise, a new array is allocated with the runtime type of the
|
||||
* specified array and the size of this queue.
|
||||
*
|
||||
* <p>If the queue fits in the specified array with room to spare
|
||||
* (i.e., the array has more elements than the queue), the element in
|
||||
* the array immediately following the end of the collection is set to
|
||||
* {@code null}.
|
||||
*
|
||||
* <p>Like the {@link #toArray()} method, this method acts as bridge between
|
||||
* array-based and collection-based APIs. Further, this method allows
|
||||
* precise control over the runtime type of the output array, and may,
|
||||
* under certain circumstances, be used to save allocation costs.
|
||||
*
|
||||
* <p>Suppose {@code x} is a queue known to contain only strings.
|
||||
* The following code can be used to dump the queue into a newly
|
||||
* allocated array of {@code String}:
|
||||
*
|
||||
* <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
|
||||
*
|
||||
* Note that {@code toArray(new Object[0])} is identical in function to
|
||||
* {@code toArray()}.
|
||||
*
|
||||
* @param a the array into which the elements of the queue are to
|
||||
* be stored, if it is big enough; otherwise, a new array of the
|
||||
* same runtime type is allocated for this purpose.
|
||||
* @return an array containing all of the elements in this queue
|
||||
* @throws ArrayStoreException if the runtime type of the specified array
|
||||
* is not a supertype of the runtime type of every element in
|
||||
* this queue
|
||||
* @throws NullPointerException if the specified array is null
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T[] toArray(T[] a) {
|
||||
final int size = this.size;
|
||||
if (a.length < size)
|
||||
// Make a new array of a's runtime type, but my contents:
|
||||
return (T[]) Arrays.copyOf(queue, size, a.getClass());
|
||||
System.arraycopy(queue, 0, a, 0, size);
|
||||
if (a.length > size)
|
||||
a[size] = null;
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator over the elements in this queue. The iterator
|
||||
* does not return the elements in any particular order.
|
||||
*
|
||||
* @return an iterator over the elements in this queue
|
||||
*/
|
||||
public Iterator<E> iterator() {
|
||||
return new Itr();
|
||||
}
|
||||
|
||||
private final class Itr implements Iterator<E> {
|
||||
/**
|
||||
* Index (into queue array) of element to be returned by
|
||||
* subsequent call to next.
|
||||
*/
|
||||
private int cursor = 0;
|
||||
|
||||
/**
|
||||
* Index of element returned by most recent call to next,
|
||||
* unless that element came from the forgetMeNot list.
|
||||
* Set to -1 if element is deleted by a call to remove.
|
||||
*/
|
||||
private int lastRet = -1;
|
||||
|
||||
/**
|
||||
* A queue of elements that were moved from the unvisited portion of
|
||||
* the heap into the visited portion as a result of "unlucky" element
|
||||
* removals during the iteration. (Unlucky element removals are those
|
||||
* that require a siftup instead of a siftdown.) We must visit all of
|
||||
* the elements in this list to complete the iteration. We do this
|
||||
* after we've completed the "normal" iteration.
|
||||
*
|
||||
* We expect that most iterations, even those involving removals,
|
||||
* will not need to store elements in this field.
|
||||
*/
|
||||
private ArrayDeque<E> forgetMeNot = null;
|
||||
|
||||
/**
|
||||
* Element returned by the most recent call to next iff that
|
||||
* element was drawn from the forgetMeNot list.
|
||||
*/
|
||||
private E lastRetElt = null;
|
||||
|
||||
/**
|
||||
* The modCount value that the iterator believes that the backing
|
||||
* Queue should have. If this expectation is violated, the iterator
|
||||
* has detected concurrent modification.
|
||||
*/
|
||||
private int expectedModCount = modCount;
|
||||
|
||||
public boolean hasNext() {
|
||||
return cursor < size ||
|
||||
(forgetMeNot != null && !forgetMeNot.isEmpty());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public E next() {
|
||||
if (expectedModCount != modCount)
|
||||
throw new ConcurrentModificationException();
|
||||
if (cursor < size)
|
||||
return (E) queue[lastRet = cursor++];
|
||||
if (forgetMeNot != null) {
|
||||
lastRet = -1;
|
||||
lastRetElt = forgetMeNot.poll();
|
||||
if (lastRetElt != null)
|
||||
return lastRetElt;
|
||||
}
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
if (expectedModCount != modCount)
|
||||
throw new ConcurrentModificationException();
|
||||
if (lastRet != -1) {
|
||||
E moved = PriorityQueue.this.removeAt(lastRet);
|
||||
lastRet = -1;
|
||||
if (moved == null)
|
||||
cursor--;
|
||||
else {
|
||||
if (forgetMeNot == null)
|
||||
forgetMeNot = new ArrayDeque<>();
|
||||
forgetMeNot.add(moved);
|
||||
}
|
||||
} else if (lastRetElt != null) {
|
||||
PriorityQueue.this.removeEq(lastRetElt);
|
||||
lastRetElt = null;
|
||||
} else {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
expectedModCount = modCount;
|
||||
}
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all of the elements from this priority queue.
|
||||
* The queue will be empty after this call returns.
|
||||
*/
|
||||
public void clear() {
|
||||
modCount++;
|
||||
for (int i = 0; i < size; i++)
|
||||
queue[i] = null;
|
||||
size = 0;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public E poll() {
|
||||
if (size == 0)
|
||||
return null;
|
||||
int s = --size;
|
||||
modCount++;
|
||||
E result = (E) queue[0];
|
||||
E x = (E) queue[s];
|
||||
queue[s] = null;
|
||||
if (s != 0)
|
||||
siftDown(0, x);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the ith element from queue.
|
||||
*
|
||||
* Normally this method leaves the elements at up to i-1,
|
||||
* inclusive, untouched. Under these circumstances, it returns
|
||||
* null. Occasionally, in order to maintain the heap invariant,
|
||||
* it must swap a later element of the list with one earlier than
|
||||
* i. Under these circumstances, this method returns the element
|
||||
* that was previously at the end of the list and is now at some
|
||||
* position before i. This fact is used by iterator.remove so as to
|
||||
* avoid missing traversing elements.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private E removeAt(int i) {
|
||||
// assert i >= 0 && i < size;
|
||||
modCount++;
|
||||
int s = --size;
|
||||
if (s == i) // removed last element
|
||||
queue[i] = null;
|
||||
else {
|
||||
E moved = (E) queue[s];
|
||||
queue[s] = null;
|
||||
siftDown(i, moved);
|
||||
if (queue[i] == moved) {
|
||||
siftUp(i, moved);
|
||||
if (queue[i] != moved)
|
||||
return moved;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts item x at position k, maintaining heap invariant by
|
||||
* promoting x up the tree until it is greater than or equal to
|
||||
* its parent, or is the root.
|
||||
*
|
||||
* To simplify and speed up coercions and comparisons. the
|
||||
* Comparable and Comparator versions are separated into different
|
||||
* methods that are otherwise identical. (Similarly for siftDown.)
|
||||
*
|
||||
* @param k the position to fill
|
||||
* @param x the item to insert
|
||||
*/
|
||||
private void siftUp(int k, E x) {
|
||||
if (comparator != null)
|
||||
siftUpUsingComparator(k, x);
|
||||
else
|
||||
siftUpComparable(k, x);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void siftUpComparable(int k, E x) {
|
||||
Comparable<? super E> key = (Comparable<? super E>) x;
|
||||
while (k > 0) {
|
||||
int parent = (k - 1) >>> 1;
|
||||
Object e = queue[parent];
|
||||
if (key.compareTo((E) e) >= 0)
|
||||
break;
|
||||
queue[k] = e;
|
||||
k = parent;
|
||||
}
|
||||
queue[k] = key;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void siftUpUsingComparator(int k, E x) {
|
||||
while (k > 0) {
|
||||
int parent = (k - 1) >>> 1;
|
||||
Object e = queue[parent];
|
||||
if (comparator.compare(x, (E) e) >= 0)
|
||||
break;
|
||||
queue[k] = e;
|
||||
k = parent;
|
||||
}
|
||||
queue[k] = x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts item x at position k, maintaining heap invariant by
|
||||
* demoting x down the tree repeatedly until it is less than or
|
||||
* equal to its children or is a leaf.
|
||||
*
|
||||
* @param k the position to fill
|
||||
* @param x the item to insert
|
||||
*/
|
||||
private void siftDown(int k, E x) {
|
||||
if (comparator != null)
|
||||
siftDownUsingComparator(k, x);
|
||||
else
|
||||
siftDownComparable(k, x);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void siftDownComparable(int k, E x) {
|
||||
Comparable<? super E> key = (Comparable<? super E>)x;
|
||||
int half = size >>> 1; // loop while a non-leaf
|
||||
while (k < half) {
|
||||
int child = (k << 1) + 1; // assume left child is least
|
||||
Object c = queue[child];
|
||||
int right = child + 1;
|
||||
if (right < size &&
|
||||
((Comparable<? super E>) c).compareTo((E) queue[right]) > 0)
|
||||
c = queue[child = right];
|
||||
if (key.compareTo((E) c) <= 0)
|
||||
break;
|
||||
queue[k] = c;
|
||||
k = child;
|
||||
}
|
||||
queue[k] = key;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void siftDownUsingComparator(int k, E x) {
|
||||
int half = size >>> 1;
|
||||
while (k < half) {
|
||||
int child = (k << 1) + 1;
|
||||
Object c = queue[child];
|
||||
int right = child + 1;
|
||||
if (right < size &&
|
||||
comparator.compare((E) c, (E) queue[right]) > 0)
|
||||
c = queue[child = right];
|
||||
if (comparator.compare(x, (E) c) <= 0)
|
||||
break;
|
||||
queue[k] = c;
|
||||
k = child;
|
||||
}
|
||||
queue[k] = x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Establishes the heap invariant (described above) in the entire tree,
|
||||
* assuming nothing about the order of the elements prior to the call.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private void heapify() {
|
||||
for (int i = (size >>> 1) - 1; i >= 0; i--)
|
||||
siftDown(i, (E) queue[i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the comparator used to order the elements in this
|
||||
* queue, or {@code null} if this queue is sorted according to
|
||||
* the {@linkplain Comparable natural ordering} of its elements.
|
||||
*
|
||||
* @return the comparator used to order this queue, or
|
||||
* {@code null} if this queue is sorted according to the
|
||||
* natural ordering of its elements
|
||||
*/
|
||||
public Comparator<? super E> comparator() {
|
||||
return comparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves this queue to a stream (that is, serializes it).
|
||||
*
|
||||
* @serialData The length of the array backing the instance is
|
||||
* emitted (int), followed by all of its elements
|
||||
* (each an {@code Object}) in the proper order.
|
||||
* @param s the stream
|
||||
*/
|
||||
private void writeObject(java.io.ObjectOutputStream s)
|
||||
throws java.io.IOException {
|
||||
// Write out element count, and any hidden stuff
|
||||
s.defaultWriteObject();
|
||||
|
||||
// Write out array length, for compatibility with 1.5 version
|
||||
s.writeInt(Math.max(2, size + 1));
|
||||
|
||||
// Write out all elements in the "proper order".
|
||||
for (int i = 0; i < size; i++)
|
||||
s.writeObject(queue[i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconstitutes the {@code PriorityQueue} instance from a stream
|
||||
* (that is, deserializes it).
|
||||
*
|
||||
* @param s the stream
|
||||
*/
|
||||
private void readObject(java.io.ObjectInputStream s)
|
||||
throws java.io.IOException, ClassNotFoundException {
|
||||
// Read in size, and any hidden stuff
|
||||
s.defaultReadObject();
|
||||
|
||||
// Read in (and discard) array length
|
||||
s.readInt();
|
||||
|
||||
SharedSecrets.getJavaOISAccess().checkArray(s, Object[].class, size);
|
||||
queue = new Object[size];
|
||||
|
||||
// Read in all elements.
|
||||
for (int i = 0; i < size; i++)
|
||||
queue[i] = s.readObject();
|
||||
|
||||
// Elements are guaranteed to be in "proper order", but the
|
||||
// spec has never explained what that might be.
|
||||
heapify();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
|
||||
* and <em>fail-fast</em> {@link Spliterator} over the elements in this
|
||||
* queue.
|
||||
*
|
||||
* <p>The {@code Spliterator} reports {@link Spliterator#SIZED},
|
||||
* {@link Spliterator#SUBSIZED}, and {@link Spliterator#NONNULL}.
|
||||
* Overriding implementations should document the reporting of additional
|
||||
* characteristic values.
|
||||
*
|
||||
* @return a {@code Spliterator} over the elements in this queue
|
||||
* @since 1.8
|
||||
*/
|
||||
public final Spliterator<E> spliterator() {
|
||||
return new PriorityQueueSpliterator<E>(this, 0, -1, 0);
|
||||
}
|
||||
|
||||
static final class PriorityQueueSpliterator<E> implements Spliterator<E> {
|
||||
/*
|
||||
* This is very similar to ArrayList Spliterator, except for
|
||||
* extra null checks.
|
||||
*/
|
||||
private final PriorityQueue<E> pq;
|
||||
private int index; // current index, modified on advance/split
|
||||
private int fence; // -1 until first use
|
||||
private int expectedModCount; // initialized when fence set
|
||||
|
||||
/** Creates new spliterator covering the given range */
|
||||
PriorityQueueSpliterator(PriorityQueue<E> pq, int origin, int fence,
|
||||
int expectedModCount) {
|
||||
this.pq = pq;
|
||||
this.index = origin;
|
||||
this.fence = fence;
|
||||
this.expectedModCount = expectedModCount;
|
||||
}
|
||||
|
||||
private int getFence() { // initialize fence to size on first use
|
||||
int hi;
|
||||
if ((hi = fence) < 0) {
|
||||
expectedModCount = pq.modCount;
|
||||
hi = fence = pq.size;
|
||||
}
|
||||
return hi;
|
||||
}
|
||||
|
||||
public PriorityQueueSpliterator<E> trySplit() {
|
||||
int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
|
||||
return (lo >= mid) ? null :
|
||||
new PriorityQueueSpliterator<E>(pq, lo, index = mid,
|
||||
expectedModCount);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void forEachRemaining(Consumer<? super E> action) {
|
||||
int i, hi, mc; // hoist accesses and checks from loop
|
||||
PriorityQueue<E> q; Object[] a;
|
||||
if (action == null)
|
||||
throw new NullPointerException();
|
||||
if ((q = pq) != null && (a = q.queue) != null) {
|
||||
if ((hi = fence) < 0) {
|
||||
mc = q.modCount;
|
||||
hi = q.size;
|
||||
}
|
||||
else
|
||||
mc = expectedModCount;
|
||||
if ((i = index) >= 0 && (index = hi) <= a.length) {
|
||||
for (E e;; ++i) {
|
||||
if (i < hi) {
|
||||
if ((e = (E) a[i]) == null) // must be CME
|
||||
break;
|
||||
action.accept(e);
|
||||
}
|
||||
else if (q.modCount != mc)
|
||||
break;
|
||||
else
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
|
||||
public boolean tryAdvance(Consumer<? super E> action) {
|
||||
if (action == null)
|
||||
throw new NullPointerException();
|
||||
int hi = getFence(), lo = index;
|
||||
if (lo >= 0 && lo < hi) {
|
||||
index = lo + 1;
|
||||
@SuppressWarnings("unchecked") E e = (E)pq.queue[lo];
|
||||
if (e == null)
|
||||
throw new ConcurrentModificationException();
|
||||
action.accept(e);
|
||||
if (pq.modCount != expectedModCount)
|
||||
throw new ConcurrentModificationException();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public long estimateSize() {
|
||||
return (long) (getFence() - index);
|
||||
}
|
||||
|
||||
public int characteristics() {
|
||||
return Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.NONNULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
1211
jdkSrc/jdk8/java/util/Properties.java
Normal file
1211
jdkSrc/jdk8/java/util/Properties.java
Normal file
File diff suppressed because it is too large
Load Diff
657
jdkSrc/jdk8/java/util/PropertyPermission.java
Normal file
657
jdkSrc/jdk8/java/util/PropertyPermission.java
Normal file
@@ -0,0 +1,657 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.IOException;
|
||||
import java.security.*;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Collections;
|
||||
import java.io.ObjectStreamField;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.IOException;
|
||||
import sun.security.util.SecurityConstants;
|
||||
|
||||
/**
|
||||
* This class is for property permissions.
|
||||
*
|
||||
* <P>
|
||||
* The name is the name of the property ("java.home",
|
||||
* "os.name", etc). The naming
|
||||
* convention follows the hierarchical property naming convention.
|
||||
* Also, an asterisk
|
||||
* may appear at the end of the name, following a ".", or by itself, to
|
||||
* signify a wildcard match. For example: "java.*" and "*" signify a wildcard
|
||||
* match, while "*java" and "a*b" do not.
|
||||
* <P>
|
||||
* The actions to be granted are passed to the constructor in a string containing
|
||||
* a list of one or more comma-separated keywords. The possible keywords are
|
||||
* "read" and "write". Their meaning is defined as follows:
|
||||
*
|
||||
* <DL>
|
||||
* <DT> read
|
||||
* <DD> read permission. Allows <code>System.getProperty</code> to
|
||||
* be called.
|
||||
* <DT> write
|
||||
* <DD> write permission. Allows <code>System.setProperty</code> to
|
||||
* be called.
|
||||
* </DL>
|
||||
* <P>
|
||||
* The actions string is converted to lowercase before processing.
|
||||
* <P>
|
||||
* Care should be taken before granting code permission to access
|
||||
* certain system properties. For example, granting permission to
|
||||
* access the "java.home" system property gives potentially malevolent
|
||||
* code sensitive information about the system environment (the Java
|
||||
* installation directory). Also, granting permission to access
|
||||
* the "user.name" and "user.home" system properties gives potentially
|
||||
* malevolent code sensitive information about the user environment
|
||||
* (the user's account name and home directory).
|
||||
*
|
||||
* @see java.security.BasicPermission
|
||||
* @see java.security.Permission
|
||||
* @see java.security.Permissions
|
||||
* @see java.security.PermissionCollection
|
||||
* @see java.lang.SecurityManager
|
||||
*
|
||||
*
|
||||
* @author Roland Schemers
|
||||
* @since 1.2
|
||||
*
|
||||
* @serial exclude
|
||||
*/
|
||||
|
||||
public final class PropertyPermission extends BasicPermission {
|
||||
|
||||
/**
|
||||
* Read action.
|
||||
*/
|
||||
private final static int READ = 0x1;
|
||||
|
||||
/**
|
||||
* Write action.
|
||||
*/
|
||||
private final static int WRITE = 0x2;
|
||||
/**
|
||||
* All actions (read,write);
|
||||
*/
|
||||
private final static int ALL = READ|WRITE;
|
||||
/**
|
||||
* No actions.
|
||||
*/
|
||||
private final static int NONE = 0x0;
|
||||
|
||||
/**
|
||||
* The actions mask.
|
||||
*
|
||||
*/
|
||||
private transient int mask;
|
||||
|
||||
/**
|
||||
* The actions string.
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
private String actions; // Left null as long as possible, then
|
||||
// created and re-used in the getAction function.
|
||||
|
||||
/**
|
||||
* initialize a PropertyPermission object. Common to all constructors.
|
||||
* Also called during de-serialization.
|
||||
*
|
||||
* @param mask the actions mask to use.
|
||||
*
|
||||
*/
|
||||
private void init(int mask) {
|
||||
if ((mask & ALL) != mask)
|
||||
throw new IllegalArgumentException("invalid actions mask");
|
||||
|
||||
if (mask == NONE)
|
||||
throw new IllegalArgumentException("invalid actions mask");
|
||||
|
||||
if (getName() == null)
|
||||
throw new NullPointerException("name can't be null");
|
||||
|
||||
this.mask = mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new PropertyPermission object with the specified name.
|
||||
* The name is the name of the system property, and
|
||||
* <i>actions</i> contains a comma-separated list of the
|
||||
* desired actions granted on the property. Possible actions are
|
||||
* "read" and "write".
|
||||
*
|
||||
* @param name the name of the PropertyPermission.
|
||||
* @param actions the actions string.
|
||||
*
|
||||
* @throws NullPointerException if <code>name</code> is <code>null</code>.
|
||||
* @throws IllegalArgumentException if <code>name</code> is empty or if
|
||||
* <code>actions</code> is invalid.
|
||||
*/
|
||||
public PropertyPermission(String name, String actions) {
|
||||
super(name,actions);
|
||||
init(getMask(actions));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this PropertyPermission object "implies" the specified
|
||||
* permission.
|
||||
* <P>
|
||||
* More specifically, this method returns true if:
|
||||
* <ul>
|
||||
* <li> <i>p</i> is an instanceof PropertyPermission,
|
||||
* <li> <i>p</i>'s actions are a subset of this
|
||||
* object's actions, and
|
||||
* <li> <i>p</i>'s name is implied by this object's
|
||||
* name. For example, "java.*" implies "java.home".
|
||||
* </ul>
|
||||
* @param p the permission to check against.
|
||||
*
|
||||
* @return true if the specified permission is implied by this object,
|
||||
* false if not.
|
||||
*/
|
||||
public boolean implies(Permission p) {
|
||||
if (!(p instanceof PropertyPermission))
|
||||
return false;
|
||||
|
||||
PropertyPermission that = (PropertyPermission) p;
|
||||
|
||||
// we get the effective mask. i.e., the "and" of this and that.
|
||||
// They must be equal to that.mask for implies to return true.
|
||||
|
||||
return ((this.mask & that.mask) == that.mask) && super.implies(that);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks two PropertyPermission objects for equality. Checks that <i>obj</i> is
|
||||
* a PropertyPermission, and has the same name and actions as this object.
|
||||
* <P>
|
||||
* @param obj the object we are testing for equality with this object.
|
||||
* @return true if obj is a PropertyPermission, and has the same name and
|
||||
* actions as this PropertyPermission object.
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this)
|
||||
return true;
|
||||
|
||||
if (! (obj instanceof PropertyPermission))
|
||||
return false;
|
||||
|
||||
PropertyPermission that = (PropertyPermission) obj;
|
||||
|
||||
return (this.mask == that.mask) &&
|
||||
(this.getName().equals(that.getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code value for this object.
|
||||
* The hash code used is the hash code of this permissions name, that is,
|
||||
* <code>getName().hashCode()</code>, where <code>getName</code> is
|
||||
* from the Permission superclass.
|
||||
*
|
||||
* @return a hash code value for this object.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return this.getName().hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an actions String to an actions mask.
|
||||
*
|
||||
* @param actions the action string.
|
||||
* @return the actions mask.
|
||||
*/
|
||||
private static int getMask(String actions) {
|
||||
|
||||
int mask = NONE;
|
||||
|
||||
if (actions == null) {
|
||||
return mask;
|
||||
}
|
||||
|
||||
// Use object identity comparison against known-interned strings for
|
||||
// performance benefit (these values are used heavily within the JDK).
|
||||
if (actions == SecurityConstants.PROPERTY_READ_ACTION) {
|
||||
return READ;
|
||||
} if (actions == SecurityConstants.PROPERTY_WRITE_ACTION) {
|
||||
return WRITE;
|
||||
} else if (actions == SecurityConstants.PROPERTY_RW_ACTION) {
|
||||
return READ|WRITE;
|
||||
}
|
||||
|
||||
char[] a = actions.toCharArray();
|
||||
|
||||
int i = a.length - 1;
|
||||
if (i < 0)
|
||||
return mask;
|
||||
|
||||
while (i != -1) {
|
||||
char c;
|
||||
|
||||
// skip whitespace
|
||||
while ((i!=-1) && ((c = a[i]) == ' ' ||
|
||||
c == '\r' ||
|
||||
c == '\n' ||
|
||||
c == '\f' ||
|
||||
c == '\t'))
|
||||
i--;
|
||||
|
||||
// check for the known strings
|
||||
int matchlen;
|
||||
|
||||
if (i >= 3 && (a[i-3] == 'r' || a[i-3] == 'R') &&
|
||||
(a[i-2] == 'e' || a[i-2] == 'E') &&
|
||||
(a[i-1] == 'a' || a[i-1] == 'A') &&
|
||||
(a[i] == 'd' || a[i] == 'D'))
|
||||
{
|
||||
matchlen = 4;
|
||||
mask |= READ;
|
||||
|
||||
} else if (i >= 4 && (a[i-4] == 'w' || a[i-4] == 'W') &&
|
||||
(a[i-3] == 'r' || a[i-3] == 'R') &&
|
||||
(a[i-2] == 'i' || a[i-2] == 'I') &&
|
||||
(a[i-1] == 't' || a[i-1] == 'T') &&
|
||||
(a[i] == 'e' || a[i] == 'E'))
|
||||
{
|
||||
matchlen = 5;
|
||||
mask |= WRITE;
|
||||
|
||||
} else {
|
||||
// parse error
|
||||
throw new IllegalArgumentException(
|
||||
"invalid permission: " + actions);
|
||||
}
|
||||
|
||||
// make sure we didn't just match the tail of a word
|
||||
// like "ackbarfaccept". Also, skip to the comma.
|
||||
boolean seencomma = false;
|
||||
while (i >= matchlen && !seencomma) {
|
||||
switch(a[i-matchlen]) {
|
||||
case ',':
|
||||
seencomma = true;
|
||||
break;
|
||||
case ' ': case '\r': case '\n':
|
||||
case '\f': case '\t':
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"invalid permission: " + actions);
|
||||
}
|
||||
i--;
|
||||
}
|
||||
|
||||
// point i at the location of the comma minus one (or -1).
|
||||
i -= matchlen;
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the canonical string representation of the actions.
|
||||
* Always returns present actions in the following order:
|
||||
* read, write.
|
||||
*
|
||||
* @return the canonical string representation of the actions.
|
||||
*/
|
||||
static String getActions(int mask) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
boolean comma = false;
|
||||
|
||||
if ((mask & READ) == READ) {
|
||||
comma = true;
|
||||
sb.append("read");
|
||||
}
|
||||
|
||||
if ((mask & WRITE) == WRITE) {
|
||||
if (comma) sb.append(',');
|
||||
else comma = true;
|
||||
sb.append("write");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the "canonical string representation" of the actions.
|
||||
* That is, this method always returns present actions in the following order:
|
||||
* read, write. For example, if this PropertyPermission object
|
||||
* allows both write and read actions, a call to <code>getActions</code>
|
||||
* will return the string "read,write".
|
||||
*
|
||||
* @return the canonical string representation of the actions.
|
||||
*/
|
||||
public String getActions() {
|
||||
if (actions == null)
|
||||
actions = getActions(this.mask);
|
||||
|
||||
return actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current action mask.
|
||||
* Used by the PropertyPermissionCollection
|
||||
*
|
||||
* @return the actions mask.
|
||||
*/
|
||||
int getMask() {
|
||||
return mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new PermissionCollection object for storing
|
||||
* PropertyPermission objects.
|
||||
* <p>
|
||||
*
|
||||
* @return a new PermissionCollection object suitable for storing
|
||||
* PropertyPermissions.
|
||||
*/
|
||||
public PermissionCollection newPermissionCollection() {
|
||||
return new PropertyPermissionCollection();
|
||||
}
|
||||
|
||||
|
||||
private static final long serialVersionUID = 885438825399942851L;
|
||||
|
||||
/**
|
||||
* WriteObject is called to save the state of the PropertyPermission
|
||||
* to a stream. The actions are serialized, and the superclass
|
||||
* takes care of the name.
|
||||
*/
|
||||
private synchronized void writeObject(java.io.ObjectOutputStream s)
|
||||
throws IOException
|
||||
{
|
||||
// Write out the actions. The superclass takes care of the name
|
||||
// call getActions to make sure actions field is initialized
|
||||
if (actions == null)
|
||||
getActions();
|
||||
s.defaultWriteObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* readObject is called to restore the state of the PropertyPermission from
|
||||
* a stream.
|
||||
*/
|
||||
private synchronized void readObject(java.io.ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
// Read in the action, then initialize the rest
|
||||
s.defaultReadObject();
|
||||
init(getMask(actions));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A PropertyPermissionCollection stores a set of PropertyPermission
|
||||
* permissions.
|
||||
*
|
||||
* @see java.security.Permission
|
||||
* @see java.security.Permissions
|
||||
* @see java.security.PermissionCollection
|
||||
*
|
||||
*
|
||||
* @author Roland Schemers
|
||||
*
|
||||
* @serial include
|
||||
*/
|
||||
final class PropertyPermissionCollection extends PermissionCollection
|
||||
implements Serializable
|
||||
{
|
||||
|
||||
/**
|
||||
* Key is property name; value is PropertyPermission.
|
||||
* Not serialized; see serialization section at end of class.
|
||||
*/
|
||||
private transient Map<String, PropertyPermission> perms;
|
||||
|
||||
/**
|
||||
* Boolean saying if "*" is in the collection.
|
||||
*
|
||||
* @see #serialPersistentFields
|
||||
*/
|
||||
// No sync access; OK for this to be stale.
|
||||
private boolean all_allowed;
|
||||
|
||||
/**
|
||||
* Create an empty PropertyPermissionCollection object.
|
||||
*/
|
||||
public PropertyPermissionCollection() {
|
||||
perms = new HashMap<>(32); // Capacity for default policy
|
||||
all_allowed = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a permission to the PropertyPermissions. The key for the hash is
|
||||
* the name.
|
||||
*
|
||||
* @param permission the Permission object to add.
|
||||
*
|
||||
* @exception IllegalArgumentException - if the permission is not a
|
||||
* PropertyPermission
|
||||
*
|
||||
* @exception SecurityException - if this PropertyPermissionCollection
|
||||
* object has been marked readonly
|
||||
*/
|
||||
public void add(Permission permission) {
|
||||
if (! (permission instanceof PropertyPermission))
|
||||
throw new IllegalArgumentException("invalid permission: "+
|
||||
permission);
|
||||
if (isReadOnly())
|
||||
throw new SecurityException(
|
||||
"attempt to add a Permission to a readonly PermissionCollection");
|
||||
|
||||
PropertyPermission pp = (PropertyPermission) permission;
|
||||
String propName = pp.getName();
|
||||
|
||||
synchronized (this) {
|
||||
PropertyPermission existing = perms.get(propName);
|
||||
|
||||
if (existing != null) {
|
||||
int oldMask = existing.getMask();
|
||||
int newMask = pp.getMask();
|
||||
if (oldMask != newMask) {
|
||||
int effective = oldMask | newMask;
|
||||
String actions = PropertyPermission.getActions(effective);
|
||||
perms.put(propName, new PropertyPermission(propName, actions));
|
||||
}
|
||||
} else {
|
||||
perms.put(propName, pp);
|
||||
}
|
||||
}
|
||||
|
||||
if (!all_allowed) {
|
||||
if (propName.equals("*"))
|
||||
all_allowed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check and see if this set of permissions implies the permissions
|
||||
* expressed in "permission".
|
||||
*
|
||||
* @param permission the Permission object to compare
|
||||
*
|
||||
* @return true if "permission" is a proper subset of a permission in
|
||||
* the set, false if not.
|
||||
*/
|
||||
public boolean implies(Permission permission) {
|
||||
if (! (permission instanceof PropertyPermission))
|
||||
return false;
|
||||
|
||||
PropertyPermission pp = (PropertyPermission) permission;
|
||||
PropertyPermission x;
|
||||
|
||||
int desired = pp.getMask();
|
||||
int effective = 0;
|
||||
|
||||
// short circuit if the "*" Permission was added
|
||||
if (all_allowed) {
|
||||
synchronized (this) {
|
||||
x = perms.get("*");
|
||||
}
|
||||
if (x != null) {
|
||||
effective |= x.getMask();
|
||||
if ((effective & desired) == desired)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// strategy:
|
||||
// Check for full match first. Then work our way up the
|
||||
// name looking for matches on a.b.*
|
||||
|
||||
String name = pp.getName();
|
||||
//System.out.println("check "+name);
|
||||
|
||||
synchronized (this) {
|
||||
x = perms.get(name);
|
||||
}
|
||||
|
||||
if (x != null) {
|
||||
// we have a direct hit!
|
||||
effective |= x.getMask();
|
||||
if ((effective & desired) == desired)
|
||||
return true;
|
||||
}
|
||||
|
||||
// work our way up the tree...
|
||||
int last, offset;
|
||||
|
||||
offset = name.length()-1;
|
||||
|
||||
while ((last = name.lastIndexOf(".", offset)) != -1) {
|
||||
|
||||
name = name.substring(0, last+1) + "*";
|
||||
//System.out.println("check "+name);
|
||||
synchronized (this) {
|
||||
x = perms.get(name);
|
||||
}
|
||||
|
||||
if (x != null) {
|
||||
effective |= x.getMask();
|
||||
if ((effective & desired) == desired)
|
||||
return true;
|
||||
}
|
||||
offset = last -1;
|
||||
}
|
||||
|
||||
// we don't have to check for "*" as it was already checked
|
||||
// at the top (all_allowed), so we just return false
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an enumeration of all the PropertyPermission objects in the
|
||||
* container.
|
||||
*
|
||||
* @return an enumeration of all the PropertyPermission objects.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Enumeration<Permission> elements() {
|
||||
// Convert Iterator of Map values into an Enumeration
|
||||
synchronized (this) {
|
||||
/**
|
||||
* Casting to rawtype since Enumeration<PropertyPermission>
|
||||
* cannot be directly cast to Enumeration<Permission>
|
||||
*/
|
||||
return (Enumeration)Collections.enumeration(perms.values());
|
||||
}
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 7015263904581634791L;
|
||||
|
||||
// Need to maintain serialization interoperability with earlier releases,
|
||||
// which had the serializable field:
|
||||
//
|
||||
// Table of permissions.
|
||||
//
|
||||
// @serial
|
||||
//
|
||||
// private Hashtable permissions;
|
||||
/**
|
||||
* @serialField permissions java.util.Hashtable
|
||||
* A table of the PropertyPermissions.
|
||||
* @serialField all_allowed boolean
|
||||
* boolean saying if "*" is in the collection.
|
||||
*/
|
||||
private static final ObjectStreamField[] serialPersistentFields = {
|
||||
new ObjectStreamField("permissions", Hashtable.class),
|
||||
new ObjectStreamField("all_allowed", Boolean.TYPE),
|
||||
};
|
||||
|
||||
/**
|
||||
* @serialData Default fields.
|
||||
*/
|
||||
/*
|
||||
* Writes the contents of the perms field out as a Hashtable for
|
||||
* serialization compatibility with earlier releases. all_allowed
|
||||
* unchanged.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream out) throws IOException {
|
||||
// Don't call out.defaultWriteObject()
|
||||
|
||||
// Copy perms into a Hashtable
|
||||
Hashtable<String, Permission> permissions =
|
||||
new Hashtable<>(perms.size()*2);
|
||||
synchronized (this) {
|
||||
permissions.putAll(perms);
|
||||
}
|
||||
|
||||
// Write out serializable fields
|
||||
ObjectOutputStream.PutField pfields = out.putFields();
|
||||
pfields.put("all_allowed", all_allowed);
|
||||
pfields.put("permissions", permissions);
|
||||
out.writeFields();
|
||||
}
|
||||
|
||||
/*
|
||||
* Reads in a Hashtable of PropertyPermissions and saves them in the
|
||||
* perms field. Reads in all_allowed.
|
||||
*/
|
||||
private void readObject(ObjectInputStream in)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
// Don't call defaultReadObject()
|
||||
|
||||
// Read in serialized fields
|
||||
ObjectInputStream.GetField gfields = in.readFields();
|
||||
|
||||
// Get all_allowed
|
||||
all_allowed = gfields.get("all_allowed", false);
|
||||
|
||||
// Get permissions
|
||||
@SuppressWarnings("unchecked")
|
||||
Hashtable<String, PropertyPermission> permissions =
|
||||
(Hashtable<String, PropertyPermission>)gfields.get("permissions", null);
|
||||
perms = new HashMap<>(permissions.size()*2);
|
||||
perms.putAll(permissions);
|
||||
}
|
||||
}
|
||||
201
jdkSrc/jdk8/java/util/PropertyResourceBundle.java
Normal file
201
jdkSrc/jdk8/java/util/PropertyResourceBundle.java
Normal file
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
|
||||
*
|
||||
* The original version of this source code and documentation
|
||||
* is copyrighted and owned by Taligent, Inc., a wholly-owned
|
||||
* subsidiary of IBM. These materials are provided under terms
|
||||
* of a License Agreement between Taligent and Sun. This technology
|
||||
* is protected by multiple US and International patents.
|
||||
*
|
||||
* This notice and attribution to Taligent may not be removed.
|
||||
* Taligent is a registered trademark of Taligent, Inc.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.IOException;
|
||||
import sun.util.ResourceBundleEnumeration;
|
||||
|
||||
/**
|
||||
* <code>PropertyResourceBundle</code> is a concrete subclass of
|
||||
* <code>ResourceBundle</code> that manages resources for a locale
|
||||
* using a set of static strings from a property file. See
|
||||
* {@link ResourceBundle ResourceBundle} for more information about resource
|
||||
* bundles.
|
||||
*
|
||||
* <p>
|
||||
* Unlike other types of resource bundle, you don't subclass
|
||||
* <code>PropertyResourceBundle</code>. Instead, you supply properties
|
||||
* files containing the resource data. <code>ResourceBundle.getBundle</code>
|
||||
* will automatically look for the appropriate properties file and create a
|
||||
* <code>PropertyResourceBundle</code> that refers to it. See
|
||||
* {@link ResourceBundle#getBundle(java.lang.String, java.util.Locale, java.lang.ClassLoader) ResourceBundle.getBundle}
|
||||
* for a complete description of the search and instantiation strategy.
|
||||
*
|
||||
* <p>
|
||||
* The following <a name="sample">example</a> shows a member of a resource
|
||||
* bundle family with the base name "MyResources".
|
||||
* The text defines the bundle "MyResources_de",
|
||||
* the German member of the bundle family.
|
||||
* This member is based on <code>PropertyResourceBundle</code>, and the text
|
||||
* therefore is the content of the file "MyResources_de.properties"
|
||||
* (a related <a href="ListResourceBundle.html#sample">example</a> shows
|
||||
* how you can add bundles to this family that are implemented as subclasses
|
||||
* of <code>ListResourceBundle</code>).
|
||||
* The keys in this example are of the form "s1" etc. The actual
|
||||
* keys are entirely up to your choice, so long as they are the same as
|
||||
* the keys you use in your program to retrieve the objects from the bundle.
|
||||
* Keys are case-sensitive.
|
||||
* <blockquote>
|
||||
* <pre>
|
||||
* # MessageFormat pattern
|
||||
* s1=Die Platte \"{1}\" enthält {0}.
|
||||
*
|
||||
* # location of {0} in pattern
|
||||
* s2=1
|
||||
*
|
||||
* # sample disk name
|
||||
* s3=Meine Platte
|
||||
*
|
||||
* # first ChoiceFormat choice
|
||||
* s4=keine Dateien
|
||||
*
|
||||
* # second ChoiceFormat choice
|
||||
* s5=eine Datei
|
||||
*
|
||||
* # third ChoiceFormat choice
|
||||
* s6={0,number} Dateien
|
||||
*
|
||||
* # sample date
|
||||
* s7=3. März 1996
|
||||
* </pre>
|
||||
* </blockquote>
|
||||
*
|
||||
* <p>
|
||||
* The implementation of a {@code PropertyResourceBundle} subclass must be
|
||||
* thread-safe if it's simultaneously used by multiple threads. The default
|
||||
* implementations of the non-abstract methods in this class are thread-safe.
|
||||
*
|
||||
* <p>
|
||||
* <strong>Note:</strong> PropertyResourceBundle can be constructed either
|
||||
* from an InputStream or a Reader, which represents a property file.
|
||||
* Constructing a PropertyResourceBundle instance from an InputStream requires
|
||||
* that the input stream be encoded in ISO-8859-1. In that case, characters
|
||||
* that cannot be represented in ISO-8859-1 encoding must be represented by Unicode Escapes
|
||||
* as defined in section 3.3 of
|
||||
* <cite>The Java™ Language Specification</cite>
|
||||
* whereas the other constructor which takes a Reader does not have that limitation.
|
||||
*
|
||||
* @see ResourceBundle
|
||||
* @see ListResourceBundle
|
||||
* @see Properties
|
||||
* @since JDK1.1
|
||||
*/
|
||||
public class PropertyResourceBundle extends ResourceBundle {
|
||||
/**
|
||||
* Creates a property resource bundle from an {@link java.io.InputStream
|
||||
* InputStream}. The property file read with this constructor
|
||||
* must be encoded in ISO-8859-1.
|
||||
*
|
||||
* @param stream an InputStream that represents a property file
|
||||
* to read from.
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NullPointerException if <code>stream</code> is null
|
||||
* @throws IllegalArgumentException if {@code stream} contains a
|
||||
* malformed Unicode escape sequence.
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public PropertyResourceBundle (InputStream stream) throws IOException {
|
||||
Properties properties = new Properties();
|
||||
properties.load(stream);
|
||||
lookup = new HashMap(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a property resource bundle from a {@link java.io.Reader
|
||||
* Reader}. Unlike the constructor
|
||||
* {@link #PropertyResourceBundle(java.io.InputStream) PropertyResourceBundle(InputStream)},
|
||||
* there is no limitation as to the encoding of the input property file.
|
||||
*
|
||||
* @param reader a Reader that represents a property file to
|
||||
* read from.
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws NullPointerException if <code>reader</code> is null
|
||||
* @throws IllegalArgumentException if a malformed Unicode escape sequence appears
|
||||
* from {@code reader}.
|
||||
* @since 1.6
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public PropertyResourceBundle (Reader reader) throws IOException {
|
||||
Properties properties = new Properties();
|
||||
properties.load(reader);
|
||||
lookup = new HashMap(properties);
|
||||
}
|
||||
|
||||
// Implements java.util.ResourceBundle.handleGetObject; inherits javadoc specification.
|
||||
public Object handleGetObject(String key) {
|
||||
if (key == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
return lookup.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an <code>Enumeration</code> of the keys contained in
|
||||
* this <code>ResourceBundle</code> and its parent bundles.
|
||||
*
|
||||
* @return an <code>Enumeration</code> of the keys contained in
|
||||
* this <code>ResourceBundle</code> and its parent bundles.
|
||||
* @see #keySet()
|
||||
*/
|
||||
public Enumeration<String> getKeys() {
|
||||
ResourceBundle parent = this.parent;
|
||||
return new ResourceBundleEnumeration(lookup.keySet(),
|
||||
(parent != null) ? parent.getKeys() : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a <code>Set</code> of the keys contained
|
||||
* <em>only</em> in this <code>ResourceBundle</code>.
|
||||
*
|
||||
* @return a <code>Set</code> of the keys contained only in this
|
||||
* <code>ResourceBundle</code>
|
||||
* @since 1.6
|
||||
* @see #keySet()
|
||||
*/
|
||||
protected Set<String> handleKeySet() {
|
||||
return lookup.keySet();
|
||||
}
|
||||
|
||||
// ==================privates====================
|
||||
|
||||
private Map<String,Object> lookup;
|
||||
}
|
||||
218
jdkSrc/jdk8/java/util/Queue.java
Normal file
218
jdkSrc/jdk8/java/util/Queue.java
Normal file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is available under and governed by the GNU General Public
|
||||
* License version 2 only, as published by the Free Software Foundation.
|
||||
* However, the following notice accompanied the original version of this
|
||||
* file:
|
||||
*
|
||||
* Written by Doug Lea with assistance from members of JCP JSR-166
|
||||
* Expert Group and released to the public domain, as explained at
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* A collection designed for holding elements prior to processing.
|
||||
* Besides basic {@link java.util.Collection Collection} operations,
|
||||
* queues provide additional insertion, extraction, and inspection
|
||||
* operations. Each of these methods exists in two forms: one throws
|
||||
* an exception if the operation fails, the other returns a special
|
||||
* value (either {@code null} or {@code false}, depending on the
|
||||
* operation). The latter form of the insert operation is designed
|
||||
* specifically for use with capacity-restricted {@code Queue}
|
||||
* implementations; in most implementations, insert operations cannot
|
||||
* fail.
|
||||
*
|
||||
* <table BORDER CELLPADDING=3 CELLSPACING=1>
|
||||
* <caption>Summary of Queue methods</caption>
|
||||
* <tr>
|
||||
* <td></td>
|
||||
* <td ALIGN=CENTER><em>Throws exception</em></td>
|
||||
* <td ALIGN=CENTER><em>Returns special value</em></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Insert</b></td>
|
||||
* <td>{@link Queue#add add(e)}</td>
|
||||
* <td>{@link Queue#offer offer(e)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Remove</b></td>
|
||||
* <td>{@link Queue#remove remove()}</td>
|
||||
* <td>{@link Queue#poll poll()}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Examine</b></td>
|
||||
* <td>{@link Queue#element element()}</td>
|
||||
* <td>{@link Queue#peek peek()}</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* <p>Queues typically, but do not necessarily, order elements in a
|
||||
* FIFO (first-in-first-out) manner. Among the exceptions are
|
||||
* priority queues, which order elements according to a supplied
|
||||
* comparator, or the elements' natural ordering, and LIFO queues (or
|
||||
* stacks) which order the elements LIFO (last-in-first-out).
|
||||
* Whatever the ordering used, the <em>head</em> of the queue is that
|
||||
* element which would be removed by a call to {@link #remove() } or
|
||||
* {@link #poll()}. In a FIFO queue, all new elements are inserted at
|
||||
* the <em>tail</em> of the queue. Other kinds of queues may use
|
||||
* different placement rules. Every {@code Queue} implementation
|
||||
* must specify its ordering properties.
|
||||
*
|
||||
* <p>The {@link #offer offer} method inserts an element if possible,
|
||||
* otherwise returning {@code false}. This differs from the {@link
|
||||
* java.util.Collection#add Collection.add} method, which can fail to
|
||||
* add an element only by throwing an unchecked exception. The
|
||||
* {@code offer} method is designed for use when failure is a normal,
|
||||
* rather than exceptional occurrence, for example, in fixed-capacity
|
||||
* (or "bounded") queues.
|
||||
*
|
||||
* <p>The {@link #remove()} and {@link #poll()} methods remove and
|
||||
* return the head of the queue.
|
||||
* Exactly which element is removed from the queue is a
|
||||
* function of the queue's ordering policy, which differs from
|
||||
* implementation to implementation. The {@code remove()} and
|
||||
* {@code poll()} methods differ only in their behavior when the
|
||||
* queue is empty: the {@code remove()} method throws an exception,
|
||||
* while the {@code poll()} method returns {@code null}.
|
||||
*
|
||||
* <p>The {@link #element()} and {@link #peek()} methods return, but do
|
||||
* not remove, the head of the queue.
|
||||
*
|
||||
* <p>The {@code Queue} interface does not define the <i>blocking queue
|
||||
* methods</i>, which are common in concurrent programming. These methods,
|
||||
* which wait for elements to appear or for space to become available, are
|
||||
* defined in the {@link java.util.concurrent.BlockingQueue} interface, which
|
||||
* extends this interface.
|
||||
*
|
||||
* <p>{@code Queue} implementations generally do not allow insertion
|
||||
* of {@code null} elements, although some implementations, such as
|
||||
* {@link LinkedList}, do not prohibit insertion of {@code null}.
|
||||
* Even in the implementations that permit it, {@code null} should
|
||||
* not be inserted into a {@code Queue}, as {@code null} is also
|
||||
* used as a special return value by the {@code poll} method to
|
||||
* indicate that the queue contains no elements.
|
||||
*
|
||||
* <p>{@code Queue} implementations generally do not define
|
||||
* element-based versions of methods {@code equals} and
|
||||
* {@code hashCode} but instead inherit the identity based versions
|
||||
* from class {@code Object}, because element-based equality is not
|
||||
* always well-defined for queues with the same elements but different
|
||||
* ordering properties.
|
||||
*
|
||||
*
|
||||
* <p>This interface is a member of the
|
||||
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
|
||||
* Java Collections Framework</a>.
|
||||
*
|
||||
* @see java.util.Collection
|
||||
* @see LinkedList
|
||||
* @see PriorityQueue
|
||||
* @see java.util.concurrent.LinkedBlockingQueue
|
||||
* @see java.util.concurrent.BlockingQueue
|
||||
* @see java.util.concurrent.ArrayBlockingQueue
|
||||
* @see java.util.concurrent.LinkedBlockingQueue
|
||||
* @see java.util.concurrent.PriorityBlockingQueue
|
||||
* @since 1.5
|
||||
* @author Doug Lea
|
||||
* @param <E> the type of elements held in this collection
|
||||
*/
|
||||
public interface Queue<E> extends Collection<E> {
|
||||
/**
|
||||
* Inserts the specified element into this queue if it is possible to do so
|
||||
* immediately without violating capacity restrictions, returning
|
||||
* {@code true} upon success and throwing an {@code IllegalStateException}
|
||||
* if no space is currently available.
|
||||
*
|
||||
* @param e the element to add
|
||||
* @return {@code true} (as specified by {@link Collection#add})
|
||||
* @throws IllegalStateException if the element cannot be added at this
|
||||
* time due to capacity restrictions
|
||||
* @throws ClassCastException if the class of the specified element
|
||||
* prevents it from being added to this queue
|
||||
* @throws NullPointerException if the specified element is null and
|
||||
* this queue does not permit null elements
|
||||
* @throws IllegalArgumentException if some property of this element
|
||||
* prevents it from being added to this queue
|
||||
*/
|
||||
boolean add(E e);
|
||||
|
||||
/**
|
||||
* Inserts the specified element into this queue if it is possible to do
|
||||
* so immediately without violating capacity restrictions.
|
||||
* When using a capacity-restricted queue, this method is generally
|
||||
* preferable to {@link #add}, which can fail to insert an element only
|
||||
* by throwing an exception.
|
||||
*
|
||||
* @param e the element to add
|
||||
* @return {@code true} if the element was added to this queue, else
|
||||
* {@code false}
|
||||
* @throws ClassCastException if the class of the specified element
|
||||
* prevents it from being added to this queue
|
||||
* @throws NullPointerException if the specified element is null and
|
||||
* this queue does not permit null elements
|
||||
* @throws IllegalArgumentException if some property of this element
|
||||
* prevents it from being added to this queue
|
||||
*/
|
||||
boolean offer(E e);
|
||||
|
||||
/**
|
||||
* Retrieves and removes the head of this queue. This method differs
|
||||
* from {@link #poll poll} only in that it throws an exception if this
|
||||
* queue is empty.
|
||||
*
|
||||
* @return the head of this queue
|
||||
* @throws NoSuchElementException if this queue is empty
|
||||
*/
|
||||
E remove();
|
||||
|
||||
/**
|
||||
* Retrieves and removes the head of this queue,
|
||||
* or returns {@code null} if this queue is empty.
|
||||
*
|
||||
* @return the head of this queue, or {@code null} if this queue is empty
|
||||
*/
|
||||
E poll();
|
||||
|
||||
/**
|
||||
* Retrieves, but does not remove, the head of this queue. This method
|
||||
* differs from {@link #peek peek} only in that it throws an exception
|
||||
* if this queue is empty.
|
||||
*
|
||||
* @return the head of this queue
|
||||
* @throws NoSuchElementException if this queue is empty
|
||||
*/
|
||||
E element();
|
||||
|
||||
/**
|
||||
* Retrieves, but does not remove, the head of this queue,
|
||||
* or returns {@code null} if this queue is empty.
|
||||
*
|
||||
* @return the head of this queue, or {@code null} if this queue is empty
|
||||
*/
|
||||
E peek();
|
||||
}
|
||||
1227
jdkSrc/jdk8/java/util/Random.java
Normal file
1227
jdkSrc/jdk8/java/util/Random.java
Normal file
File diff suppressed because it is too large
Load Diff
68
jdkSrc/jdk8/java/util/RandomAccess.java
Normal file
68
jdkSrc/jdk8/java/util/RandomAccess.java
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* Marker interface used by <tt>List</tt> implementations to indicate that
|
||||
* they support fast (generally constant time) random access. The primary
|
||||
* purpose of this interface is to allow generic algorithms to alter their
|
||||
* behavior to provide good performance when applied to either random or
|
||||
* sequential access lists.
|
||||
*
|
||||
* <p>The best algorithms for manipulating random access lists (such as
|
||||
* <tt>ArrayList</tt>) can produce quadratic behavior when applied to
|
||||
* sequential access lists (such as <tt>LinkedList</tt>). Generic list
|
||||
* algorithms are encouraged to check whether the given list is an
|
||||
* <tt>instanceof</tt> this interface before applying an algorithm that would
|
||||
* provide poor performance if it were applied to a sequential access list,
|
||||
* and to alter their behavior if necessary to guarantee acceptable
|
||||
* performance.
|
||||
*
|
||||
* <p>It is recognized that the distinction between random and sequential
|
||||
* access is often fuzzy. For example, some <tt>List</tt> implementations
|
||||
* provide asymptotically linear access times if they get huge, but constant
|
||||
* access times in practice. Such a <tt>List</tt> implementation
|
||||
* should generally implement this interface. As a rule of thumb, a
|
||||
* <tt>List</tt> implementation should implement this interface if,
|
||||
* for typical instances of the class, this loop:
|
||||
* <pre>
|
||||
* for (int i=0, n=list.size(); i < n; i++)
|
||||
* list.get(i);
|
||||
* </pre>
|
||||
* runs faster than this loop:
|
||||
* <pre>
|
||||
* for (Iterator i=list.iterator(); i.hasNext(); )
|
||||
* i.next();
|
||||
* </pre>
|
||||
*
|
||||
* <p>This interface is a member of the
|
||||
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
|
||||
* Java Collections Framework</a>.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
public interface RandomAccess {
|
||||
}
|
||||
304
jdkSrc/jdk8/java/util/RegularEnumSet.java
Normal file
304
jdkSrc/jdk8/java/util/RegularEnumSet.java
Normal file
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* Private implementation class for EnumSet, for "regular sized" enum types
|
||||
* (i.e., those with 64 or fewer enum constants).
|
||||
*
|
||||
* @author Josh Bloch
|
||||
* @since 1.5
|
||||
* @serial exclude
|
||||
*/
|
||||
class RegularEnumSet<E extends Enum<E>> extends EnumSet<E> {
|
||||
private static final long serialVersionUID = 3411599620347842686L;
|
||||
/**
|
||||
* Bit vector representation of this set. The 2^k bit indicates the
|
||||
* presence of universe[k] in this set.
|
||||
*/
|
||||
private long elements = 0L;
|
||||
|
||||
RegularEnumSet(Class<E>elementType, Enum<?>[] universe) {
|
||||
super(elementType, universe);
|
||||
}
|
||||
|
||||
void addRange(E from, E to) {
|
||||
elements = (-1L >>> (from.ordinal() - to.ordinal() - 1)) << from.ordinal();
|
||||
}
|
||||
|
||||
void addAll() {
|
||||
if (universe.length != 0)
|
||||
elements = -1L >>> -universe.length;
|
||||
}
|
||||
|
||||
void complement() {
|
||||
if (universe.length != 0) {
|
||||
elements = ~elements;
|
||||
elements &= -1L >>> -universe.length; // Mask unused bits
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator over the elements contained in this set. The
|
||||
* iterator traverses the elements in their <i>natural order</i> (which is
|
||||
* the order in which the enum constants are declared). The returned
|
||||
* Iterator is a "snapshot" iterator that will never throw {@link
|
||||
* ConcurrentModificationException}; the elements are traversed as they
|
||||
* existed when this call was invoked.
|
||||
*
|
||||
* @return an iterator over the elements contained in this set
|
||||
*/
|
||||
public Iterator<E> iterator() {
|
||||
return new EnumSetIterator<>();
|
||||
}
|
||||
|
||||
private class EnumSetIterator<E extends Enum<E>> implements Iterator<E> {
|
||||
/**
|
||||
* A bit vector representing the elements in the set not yet
|
||||
* returned by this iterator.
|
||||
*/
|
||||
long unseen;
|
||||
|
||||
/**
|
||||
* The bit representing the last element returned by this iterator
|
||||
* but not removed, or zero if no such element exists.
|
||||
*/
|
||||
long lastReturned = 0;
|
||||
|
||||
EnumSetIterator() {
|
||||
unseen = elements;
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return unseen != 0;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public E next() {
|
||||
if (unseen == 0)
|
||||
throw new NoSuchElementException();
|
||||
lastReturned = unseen & -unseen;
|
||||
unseen -= lastReturned;
|
||||
return (E) universe[Long.numberOfTrailingZeros(lastReturned)];
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
if (lastReturned == 0)
|
||||
throw new IllegalStateException();
|
||||
elements &= ~lastReturned;
|
||||
lastReturned = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of elements in this set.
|
||||
*
|
||||
* @return the number of elements in this set
|
||||
*/
|
||||
public int size() {
|
||||
return Long.bitCount(elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this set contains no elements.
|
||||
*
|
||||
* @return <tt>true</tt> if this set contains no elements
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return elements == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this set contains the specified element.
|
||||
*
|
||||
* @param e element to be checked for containment in this collection
|
||||
* @return <tt>true</tt> if this set contains the specified element
|
||||
*/
|
||||
public boolean contains(Object e) {
|
||||
if (e == null)
|
||||
return false;
|
||||
Class<?> eClass = e.getClass();
|
||||
if (eClass != elementType && eClass.getSuperclass() != elementType)
|
||||
return false;
|
||||
|
||||
return (elements & (1L << ((Enum<?>)e).ordinal())) != 0;
|
||||
}
|
||||
|
||||
// Modification Operations
|
||||
|
||||
/**
|
||||
* Adds the specified element to this set if it is not already present.
|
||||
*
|
||||
* @param e element to be added to this set
|
||||
* @return <tt>true</tt> if the set changed as a result of the call
|
||||
*
|
||||
* @throws NullPointerException if <tt>e</tt> is null
|
||||
*/
|
||||
public boolean add(E e) {
|
||||
typeCheck(e);
|
||||
|
||||
long oldElements = elements;
|
||||
elements |= (1L << ((Enum<?>)e).ordinal());
|
||||
return elements != oldElements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified element from this set if it is present.
|
||||
*
|
||||
* @param e element to be removed from this set, if present
|
||||
* @return <tt>true</tt> if the set contained the specified element
|
||||
*/
|
||||
public boolean remove(Object e) {
|
||||
if (e == null)
|
||||
return false;
|
||||
Class<?> eClass = e.getClass();
|
||||
if (eClass != elementType && eClass.getSuperclass() != elementType)
|
||||
return false;
|
||||
|
||||
long oldElements = elements;
|
||||
elements &= ~(1L << ((Enum<?>)e).ordinal());
|
||||
return elements != oldElements;
|
||||
}
|
||||
|
||||
// Bulk Operations
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this set contains all of the elements
|
||||
* in the specified collection.
|
||||
*
|
||||
* @param c collection to be checked for containment in this set
|
||||
* @return <tt>true</tt> if this set contains all of the elements
|
||||
* in the specified collection
|
||||
* @throws NullPointerException if the specified collection is null
|
||||
*/
|
||||
public boolean containsAll(Collection<?> c) {
|
||||
if (!(c instanceof RegularEnumSet))
|
||||
return super.containsAll(c);
|
||||
|
||||
RegularEnumSet<?> es = (RegularEnumSet<?>)c;
|
||||
if (es.elementType != elementType)
|
||||
return es.isEmpty();
|
||||
|
||||
return (es.elements & ~elements) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all of the elements in the specified collection to this set.
|
||||
*
|
||||
* @param c collection whose elements are to be added to this set
|
||||
* @return <tt>true</tt> if this set changed as a result of the call
|
||||
* @throws NullPointerException if the specified collection or any
|
||||
* of its elements are null
|
||||
*/
|
||||
public boolean addAll(Collection<? extends E> c) {
|
||||
if (!(c instanceof RegularEnumSet))
|
||||
return super.addAll(c);
|
||||
|
||||
RegularEnumSet<?> es = (RegularEnumSet<?>)c;
|
||||
if (es.elementType != elementType) {
|
||||
if (es.isEmpty())
|
||||
return false;
|
||||
else
|
||||
throw new ClassCastException(
|
||||
es.elementType + " != " + elementType);
|
||||
}
|
||||
|
||||
long oldElements = elements;
|
||||
elements |= es.elements;
|
||||
return elements != oldElements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes from this set all of its elements that are contained in
|
||||
* the specified collection.
|
||||
*
|
||||
* @param c elements to be removed from this set
|
||||
* @return <tt>true</tt> if this set changed as a result of the call
|
||||
* @throws NullPointerException if the specified collection is null
|
||||
*/
|
||||
public boolean removeAll(Collection<?> c) {
|
||||
if (!(c instanceof RegularEnumSet))
|
||||
return super.removeAll(c);
|
||||
|
||||
RegularEnumSet<?> es = (RegularEnumSet<?>)c;
|
||||
if (es.elementType != elementType)
|
||||
return false;
|
||||
|
||||
long oldElements = elements;
|
||||
elements &= ~es.elements;
|
||||
return elements != oldElements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retains only the elements in this set that are contained in the
|
||||
* specified collection.
|
||||
*
|
||||
* @param c elements to be retained in this set
|
||||
* @return <tt>true</tt> if this set changed as a result of the call
|
||||
* @throws NullPointerException if the specified collection is null
|
||||
*/
|
||||
public boolean retainAll(Collection<?> c) {
|
||||
if (!(c instanceof RegularEnumSet))
|
||||
return super.retainAll(c);
|
||||
|
||||
RegularEnumSet<?> es = (RegularEnumSet<?>)c;
|
||||
if (es.elementType != elementType) {
|
||||
boolean changed = (elements != 0);
|
||||
elements = 0;
|
||||
return changed;
|
||||
}
|
||||
|
||||
long oldElements = elements;
|
||||
elements &= es.elements;
|
||||
return elements != oldElements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all of the elements from this set.
|
||||
*/
|
||||
public void clear() {
|
||||
elements = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the specified object with this set for equality. Returns
|
||||
* <tt>true</tt> if the given object is also a set, the two sets have
|
||||
* the same size, and every member of the given set is contained in
|
||||
* this set.
|
||||
*
|
||||
* @param o object to be compared for equality with this set
|
||||
* @return <tt>true</tt> if the specified object is equal to this set
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof RegularEnumSet))
|
||||
return super.equals(o);
|
||||
|
||||
RegularEnumSet<?> es = (RegularEnumSet<?>)o;
|
||||
if (es.elementType != elementType)
|
||||
return elements == 0 && es.elements == 0;
|
||||
return es.elements == elements;
|
||||
}
|
||||
}
|
||||
3017
jdkSrc/jdk8/java/util/ResourceBundle.java
Normal file
3017
jdkSrc/jdk8/java/util/ResourceBundle.java
Normal file
File diff suppressed because it is too large
Load Diff
2617
jdkSrc/jdk8/java/util/Scanner.java
Normal file
2617
jdkSrc/jdk8/java/util/Scanner.java
Normal file
File diff suppressed because it is too large
Load Diff
87
jdkSrc/jdk8/java/util/ServiceConfigurationError.java
Normal file
87
jdkSrc/jdk8/java/util/ServiceConfigurationError.java
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
|
||||
/**
|
||||
* Error thrown when something goes wrong while loading a service provider.
|
||||
*
|
||||
* <p> This error will be thrown in the following situations:
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li> The format of a provider-configuration file violates the <a
|
||||
* href="ServiceLoader.html#format">specification</a>; </li>
|
||||
*
|
||||
* <li> An {@link java.io.IOException IOException} occurs while reading a
|
||||
* provider-configuration file; </li>
|
||||
*
|
||||
* <li> A concrete provider class named in a provider-configuration file
|
||||
* cannot be found; </li>
|
||||
*
|
||||
* <li> A concrete provider class is not a subclass of the service class;
|
||||
* </li>
|
||||
*
|
||||
* <li> A concrete provider class cannot be instantiated; or
|
||||
*
|
||||
* <li> Some other kind of error occurs. </li>
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
*
|
||||
* @author Mark Reinhold
|
||||
* @since 1.6
|
||||
*/
|
||||
|
||||
public class ServiceConfigurationError
|
||||
extends Error
|
||||
{
|
||||
|
||||
private static final long serialVersionUID = 74132770414881L;
|
||||
|
||||
/**
|
||||
* Constructs a new instance with the specified message.
|
||||
*
|
||||
* @param msg The message, or <tt>null</tt> if there is no message
|
||||
*
|
||||
*/
|
||||
public ServiceConfigurationError(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance with the specified message and cause.
|
||||
*
|
||||
* @param msg The message, or <tt>null</tt> if there is no message
|
||||
*
|
||||
* @param cause The cause, or <tt>null</tt> if the cause is nonexistent
|
||||
* or unknown
|
||||
*/
|
||||
public ServiceConfigurationError(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
|
||||
}
|
||||
586
jdkSrc/jdk8/java/util/ServiceLoader.java
Normal file
586
jdkSrc/jdk8/java/util/ServiceLoader.java
Normal file
@@ -0,0 +1,586 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.security.AccessController;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
|
||||
/**
|
||||
* A simple service-provider loading facility.
|
||||
*
|
||||
* <p> A <i>service</i> is a well-known set of interfaces and (usually
|
||||
* abstract) classes. A <i>service provider</i> is a specific implementation
|
||||
* of a service. The classes in a provider typically implement the interfaces
|
||||
* and subclass the classes defined in the service itself. Service providers
|
||||
* can be installed in an implementation of the Java platform in the form of
|
||||
* extensions, that is, jar files placed into any of the usual extension
|
||||
* directories. Providers can also be made available by adding them to the
|
||||
* application's class path or by some other platform-specific means.
|
||||
*
|
||||
* <p> For the purpose of loading, a service is represented by a single type,
|
||||
* that is, a single interface or abstract class. (A concrete class can be
|
||||
* used, but this is not recommended.) A provider of a given service contains
|
||||
* one or more concrete classes that extend this <i>service type</i> with data
|
||||
* and code specific to the provider. The <i>provider class</i> is typically
|
||||
* not the entire provider itself but rather a proxy which contains enough
|
||||
* information to decide whether the provider is able to satisfy a particular
|
||||
* request together with code that can create the actual provider on demand.
|
||||
* The details of provider classes tend to be highly service-specific; no
|
||||
* single class or interface could possibly unify them, so no such type is
|
||||
* defined here. The only requirement enforced by this facility is that
|
||||
* provider classes must have a zero-argument constructor so that they can be
|
||||
* instantiated during loading.
|
||||
*
|
||||
* <p><a name="format"> A service provider is identified by placing a
|
||||
* <i>provider-configuration file</i> in the resource directory
|
||||
* <tt>META-INF/services</tt>.</a> The file's name is the fully-qualified <a
|
||||
* href="../lang/ClassLoader.html#name">binary name</a> of the service's type.
|
||||
* The file contains a list of fully-qualified binary names of concrete
|
||||
* provider classes, one per line. Space and tab characters surrounding each
|
||||
* name, as well as blank lines, are ignored. The comment character is
|
||||
* <tt>'#'</tt> (<tt>'\u0023'</tt>,
|
||||
* <font style="font-size:smaller;">NUMBER SIGN</font>); on
|
||||
* each line all characters following the first comment character are ignored.
|
||||
* The file must be encoded in UTF-8.
|
||||
*
|
||||
* <p> If a particular concrete provider class is named in more than one
|
||||
* configuration file, or is named in the same configuration file more than
|
||||
* once, then the duplicates are ignored. The configuration file naming a
|
||||
* particular provider need not be in the same jar file or other distribution
|
||||
* unit as the provider itself. The provider must be accessible from the same
|
||||
* class loader that was initially queried to locate the configuration file;
|
||||
* note that this is not necessarily the class loader from which the file was
|
||||
* actually loaded.
|
||||
*
|
||||
* <p> Providers are located and instantiated lazily, that is, on demand. A
|
||||
* service loader maintains a cache of the providers that have been loaded so
|
||||
* far. Each invocation of the {@link #iterator iterator} method returns an
|
||||
* iterator that first yields all of the elements of the cache, in
|
||||
* instantiation order, and then lazily locates and instantiates any remaining
|
||||
* providers, adding each one to the cache in turn. The cache can be cleared
|
||||
* via the {@link #reload reload} method.
|
||||
*
|
||||
* <p> Service loaders always execute in the security context of the caller.
|
||||
* Trusted system code should typically invoke the methods in this class, and
|
||||
* the methods of the iterators which they return, from within a privileged
|
||||
* security context.
|
||||
*
|
||||
* <p> Instances of this class are not safe for use by multiple concurrent
|
||||
* threads.
|
||||
*
|
||||
* <p> Unless otherwise specified, passing a <tt>null</tt> argument to any
|
||||
* method in this class will cause a {@link NullPointerException} to be thrown.
|
||||
*
|
||||
*
|
||||
* <p><span style="font-weight: bold; padding-right: 1em">Example</span>
|
||||
* Suppose we have a service type <tt>com.example.CodecSet</tt> which is
|
||||
* intended to represent sets of encoder/decoder pairs for some protocol. In
|
||||
* this case it is an abstract class with two abstract methods:
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* public abstract Encoder getEncoder(String encodingName);
|
||||
* public abstract Decoder getDecoder(String encodingName);</pre></blockquote>
|
||||
*
|
||||
* Each method returns an appropriate object or <tt>null</tt> if the provider
|
||||
* does not support the given encoding. Typical providers support more than
|
||||
* one encoding.
|
||||
*
|
||||
* <p> If <tt>com.example.impl.StandardCodecs</tt> is an implementation of the
|
||||
* <tt>CodecSet</tt> service then its jar file also contains a file named
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* META-INF/services/com.example.CodecSet</pre></blockquote>
|
||||
*
|
||||
* <p> This file contains the single line:
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* com.example.impl.StandardCodecs # Standard codecs</pre></blockquote>
|
||||
*
|
||||
* <p> The <tt>CodecSet</tt> class creates and saves a single service instance
|
||||
* at initialization:
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* private static ServiceLoader<CodecSet> codecSetLoader
|
||||
* = ServiceLoader.load(CodecSet.class);</pre></blockquote>
|
||||
*
|
||||
* <p> To locate an encoder for a given encoding name it defines a static
|
||||
* factory method which iterates through the known and available providers,
|
||||
* returning only when it has located a suitable encoder or has run out of
|
||||
* providers.
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* public static Encoder getEncoder(String encodingName) {
|
||||
* for (CodecSet cp : codecSetLoader) {
|
||||
* Encoder enc = cp.getEncoder(encodingName);
|
||||
* if (enc != null)
|
||||
* return enc;
|
||||
* }
|
||||
* return null;
|
||||
* }</pre></blockquote>
|
||||
*
|
||||
* <p> A <tt>getDecoder</tt> method is defined similarly.
|
||||
*
|
||||
*
|
||||
* <p><span style="font-weight: bold; padding-right: 1em">Usage Note</span> If
|
||||
* the class path of a class loader that is used for provider loading includes
|
||||
* remote network URLs then those URLs will be dereferenced in the process of
|
||||
* searching for provider-configuration files.
|
||||
*
|
||||
* <p> This activity is normal, although it may cause puzzling entries to be
|
||||
* created in web-server logs. If a web server is not configured correctly,
|
||||
* however, then this activity may cause the provider-loading algorithm to fail
|
||||
* spuriously.
|
||||
*
|
||||
* <p> A web server should return an HTTP 404 (Not Found) response when a
|
||||
* requested resource does not exist. Sometimes, however, web servers are
|
||||
* erroneously configured to return an HTTP 200 (OK) response along with a
|
||||
* helpful HTML error page in such cases. This will cause a {@link
|
||||
* ServiceConfigurationError} to be thrown when this class attempts to parse
|
||||
* the HTML page as a provider-configuration file. The best solution to this
|
||||
* problem is to fix the misconfigured web server to return the correct
|
||||
* response code (HTTP 404) along with the HTML error page.
|
||||
*
|
||||
* @param <S>
|
||||
* The type of the service to be loaded by this loader
|
||||
*
|
||||
* @author Mark Reinhold
|
||||
* @since 1.6
|
||||
*/
|
||||
|
||||
public final class ServiceLoader<S>
|
||||
implements Iterable<S>
|
||||
{
|
||||
|
||||
private static final String PREFIX = "META-INF/services/";
|
||||
|
||||
// The class or interface representing the service being loaded
|
||||
private final Class<S> service;
|
||||
|
||||
// The class loader used to locate, load, and instantiate providers
|
||||
private final ClassLoader loader;
|
||||
|
||||
// The access control context taken when the ServiceLoader is created
|
||||
private final AccessControlContext acc;
|
||||
|
||||
// Cached providers, in instantiation order
|
||||
private LinkedHashMap<String,S> providers = new LinkedHashMap<>();
|
||||
|
||||
// The current lazy-lookup iterator
|
||||
private LazyIterator lookupIterator;
|
||||
|
||||
/**
|
||||
* Clear this loader's provider cache so that all providers will be
|
||||
* reloaded.
|
||||
*
|
||||
* <p> After invoking this method, subsequent invocations of the {@link
|
||||
* #iterator() iterator} method will lazily look up and instantiate
|
||||
* providers from scratch, just as is done by a newly-created loader.
|
||||
*
|
||||
* <p> This method is intended for use in situations in which new providers
|
||||
* can be installed into a running Java virtual machine.
|
||||
*/
|
||||
public void reload() {
|
||||
providers.clear();
|
||||
lookupIterator = new LazyIterator(service, loader);
|
||||
}
|
||||
|
||||
private ServiceLoader(Class<S> svc, ClassLoader cl) {
|
||||
service = Objects.requireNonNull(svc, "Service interface cannot be null");
|
||||
loader = (cl == null) ? ClassLoader.getSystemClassLoader() : cl;
|
||||
acc = (System.getSecurityManager() != null) ? AccessController.getContext() : null;
|
||||
reload();
|
||||
}
|
||||
|
||||
private static void fail(Class<?> service, String msg, Throwable cause)
|
||||
throws ServiceConfigurationError
|
||||
{
|
||||
throw new ServiceConfigurationError(service.getName() + ": " + msg,
|
||||
cause);
|
||||
}
|
||||
|
||||
private static void fail(Class<?> service, String msg)
|
||||
throws ServiceConfigurationError
|
||||
{
|
||||
throw new ServiceConfigurationError(service.getName() + ": " + msg);
|
||||
}
|
||||
|
||||
private static void fail(Class<?> service, URL u, int line, String msg)
|
||||
throws ServiceConfigurationError
|
||||
{
|
||||
fail(service, u + ":" + line + ": " + msg);
|
||||
}
|
||||
|
||||
// Parse a single line from the given configuration file, adding the name
|
||||
// on the line to the names list.
|
||||
//
|
||||
private int parseLine(Class<?> service, URL u, BufferedReader r, int lc,
|
||||
List<String> names)
|
||||
throws IOException, ServiceConfigurationError
|
||||
{
|
||||
String ln = r.readLine();
|
||||
if (ln == null) {
|
||||
return -1;
|
||||
}
|
||||
int ci = ln.indexOf('#');
|
||||
if (ci >= 0) ln = ln.substring(0, ci);
|
||||
ln = ln.trim();
|
||||
int n = ln.length();
|
||||
if (n != 0) {
|
||||
if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0))
|
||||
fail(service, u, lc, "Illegal configuration-file syntax");
|
||||
int cp = ln.codePointAt(0);
|
||||
if (!Character.isJavaIdentifierStart(cp))
|
||||
fail(service, u, lc, "Illegal provider-class name: " + ln);
|
||||
for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) {
|
||||
cp = ln.codePointAt(i);
|
||||
if (!Character.isJavaIdentifierPart(cp) && (cp != '.'))
|
||||
fail(service, u, lc, "Illegal provider-class name: " + ln);
|
||||
}
|
||||
if (!providers.containsKey(ln) && !names.contains(ln))
|
||||
names.add(ln);
|
||||
}
|
||||
return lc + 1;
|
||||
}
|
||||
|
||||
// Parse the content of the given URL as a provider-configuration file.
|
||||
//
|
||||
// @param service
|
||||
// The service type for which providers are being sought;
|
||||
// used to construct error detail strings
|
||||
//
|
||||
// @param u
|
||||
// The URL naming the configuration file to be parsed
|
||||
//
|
||||
// @return A (possibly empty) iterator that will yield the provider-class
|
||||
// names in the given configuration file that are not yet members
|
||||
// of the returned set
|
||||
//
|
||||
// @throws ServiceConfigurationError
|
||||
// If an I/O error occurs while reading from the given URL, or
|
||||
// if a configuration-file format error is detected
|
||||
//
|
||||
private Iterator<String> parse(Class<?> service, URL u)
|
||||
throws ServiceConfigurationError
|
||||
{
|
||||
InputStream in = null;
|
||||
BufferedReader r = null;
|
||||
ArrayList<String> names = new ArrayList<>();
|
||||
try {
|
||||
in = u.openStream();
|
||||
r = new BufferedReader(new InputStreamReader(in, "utf-8"));
|
||||
int lc = 1;
|
||||
while ((lc = parseLine(service, u, r, lc, names)) >= 0);
|
||||
} catch (IOException x) {
|
||||
fail(service, "Error reading configuration file", x);
|
||||
} finally {
|
||||
try {
|
||||
if (r != null) r.close();
|
||||
if (in != null) in.close();
|
||||
} catch (IOException y) {
|
||||
fail(service, "Error closing configuration file", y);
|
||||
}
|
||||
}
|
||||
return names.iterator();
|
||||
}
|
||||
|
||||
// Private inner class implementing fully-lazy provider lookup
|
||||
//
|
||||
private class LazyIterator
|
||||
implements Iterator<S>
|
||||
{
|
||||
|
||||
Class<S> service;
|
||||
ClassLoader loader;
|
||||
Enumeration<URL> configs = null;
|
||||
Iterator<String> pending = null;
|
||||
String nextName = null;
|
||||
|
||||
private LazyIterator(Class<S> service, ClassLoader loader) {
|
||||
this.service = service;
|
||||
this.loader = loader;
|
||||
}
|
||||
|
||||
private boolean hasNextService() {
|
||||
if (nextName != null) {
|
||||
return true;
|
||||
}
|
||||
if (configs == null) {
|
||||
try {
|
||||
String fullName = PREFIX + service.getName();
|
||||
if (loader == null)
|
||||
configs = ClassLoader.getSystemResources(fullName);
|
||||
else
|
||||
configs = loader.getResources(fullName);
|
||||
} catch (IOException x) {
|
||||
fail(service, "Error locating configuration files", x);
|
||||
}
|
||||
}
|
||||
while ((pending == null) || !pending.hasNext()) {
|
||||
if (!configs.hasMoreElements()) {
|
||||
return false;
|
||||
}
|
||||
pending = parse(service, configs.nextElement());
|
||||
}
|
||||
nextName = pending.next();
|
||||
return true;
|
||||
}
|
||||
|
||||
private S nextService() {
|
||||
if (!hasNextService())
|
||||
throw new NoSuchElementException();
|
||||
String cn = nextName;
|
||||
nextName = null;
|
||||
Class<?> c = null;
|
||||
try {
|
||||
c = Class.forName(cn, false, loader);
|
||||
} catch (ClassNotFoundException x) {
|
||||
fail(service,
|
||||
"Provider " + cn + " not found");
|
||||
}
|
||||
if (!service.isAssignableFrom(c)) {
|
||||
fail(service,
|
||||
"Provider " + cn + " not a subtype");
|
||||
}
|
||||
try {
|
||||
S p = service.cast(c.newInstance());
|
||||
providers.put(cn, p);
|
||||
return p;
|
||||
} catch (Throwable x) {
|
||||
fail(service,
|
||||
"Provider " + cn + " could not be instantiated",
|
||||
x);
|
||||
}
|
||||
throw new Error(); // This cannot happen
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
if (acc == null) {
|
||||
return hasNextService();
|
||||
} else {
|
||||
PrivilegedAction<Boolean> action = new PrivilegedAction<Boolean>() {
|
||||
public Boolean run() { return hasNextService(); }
|
||||
};
|
||||
return AccessController.doPrivileged(action, acc);
|
||||
}
|
||||
}
|
||||
|
||||
public S next() {
|
||||
if (acc == null) {
|
||||
return nextService();
|
||||
} else {
|
||||
PrivilegedAction<S> action = new PrivilegedAction<S>() {
|
||||
public S run() { return nextService(); }
|
||||
};
|
||||
return AccessController.doPrivileged(action, acc);
|
||||
}
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazily loads the available providers of this loader's service.
|
||||
*
|
||||
* <p> The iterator returned by this method first yields all of the
|
||||
* elements of the provider cache, in instantiation order. It then lazily
|
||||
* loads and instantiates any remaining providers, adding each one to the
|
||||
* cache in turn.
|
||||
*
|
||||
* <p> To achieve laziness the actual work of parsing the available
|
||||
* provider-configuration files and instantiating providers must be done by
|
||||
* the iterator itself. Its {@link java.util.Iterator#hasNext hasNext} and
|
||||
* {@link java.util.Iterator#next next} methods can therefore throw a
|
||||
* {@link ServiceConfigurationError} if a provider-configuration file
|
||||
* violates the specified format, or if it names a provider class that
|
||||
* cannot be found and instantiated, or if the result of instantiating the
|
||||
* class is not assignable to the service type, or if any other kind of
|
||||
* exception or error is thrown as the next provider is located and
|
||||
* instantiated. To write robust code it is only necessary to catch {@link
|
||||
* ServiceConfigurationError} when using a service iterator.
|
||||
*
|
||||
* <p> If such an error is thrown then subsequent invocations of the
|
||||
* iterator will make a best effort to locate and instantiate the next
|
||||
* available provider, but in general such recovery cannot be guaranteed.
|
||||
*
|
||||
* <blockquote style="font-size: smaller; line-height: 1.2"><span
|
||||
* style="padding-right: 1em; font-weight: bold">Design Note</span>
|
||||
* Throwing an error in these cases may seem extreme. The rationale for
|
||||
* this behavior is that a malformed provider-configuration file, like a
|
||||
* malformed class file, indicates a serious problem with the way the Java
|
||||
* virtual machine is configured or is being used. As such it is
|
||||
* preferable to throw an error rather than try to recover or, even worse,
|
||||
* fail silently.</blockquote>
|
||||
*
|
||||
* <p> The iterator returned by this method does not support removal.
|
||||
* Invoking its {@link java.util.Iterator#remove() remove} method will
|
||||
* cause an {@link UnsupportedOperationException} to be thrown.
|
||||
*
|
||||
* @implNote When adding providers to the cache, the {@link #iterator
|
||||
* Iterator} processes resources in the order that the {@link
|
||||
* java.lang.ClassLoader#getResources(java.lang.String)
|
||||
* ClassLoader.getResources(String)} method finds the service configuration
|
||||
* files.
|
||||
*
|
||||
* @return An iterator that lazily loads providers for this loader's
|
||||
* service
|
||||
*/
|
||||
public Iterator<S> iterator() {
|
||||
return new Iterator<S>() {
|
||||
|
||||
Iterator<Map.Entry<String,S>> knownProviders
|
||||
= providers.entrySet().iterator();
|
||||
|
||||
public boolean hasNext() {
|
||||
if (knownProviders.hasNext())
|
||||
return true;
|
||||
return lookupIterator.hasNext();
|
||||
}
|
||||
|
||||
public S next() {
|
||||
if (knownProviders.hasNext())
|
||||
return knownProviders.next().getValue();
|
||||
return lookupIterator.next();
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new service loader for the given service type and class
|
||||
* loader.
|
||||
*
|
||||
* @param <S> the class of the service type
|
||||
*
|
||||
* @param service
|
||||
* The interface or abstract class representing the service
|
||||
*
|
||||
* @param loader
|
||||
* The class loader to be used to load provider-configuration files
|
||||
* and provider classes, or <tt>null</tt> if the system class
|
||||
* loader (or, failing that, the bootstrap class loader) is to be
|
||||
* used
|
||||
*
|
||||
* @return A new service loader
|
||||
*/
|
||||
public static <S> ServiceLoader<S> load(Class<S> service,
|
||||
ClassLoader loader)
|
||||
{
|
||||
return new ServiceLoader<>(service, loader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new service loader for the given service type, using the
|
||||
* current thread's {@linkplain java.lang.Thread#getContextClassLoader
|
||||
* context class loader}.
|
||||
*
|
||||
* <p> An invocation of this convenience method of the form
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* ServiceLoader.load(<i>service</i>)</pre></blockquote>
|
||||
*
|
||||
* is equivalent to
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* ServiceLoader.load(<i>service</i>,
|
||||
* Thread.currentThread().getContextClassLoader())</pre></blockquote>
|
||||
*
|
||||
* @param <S> the class of the service type
|
||||
*
|
||||
* @param service
|
||||
* The interface or abstract class representing the service
|
||||
*
|
||||
* @return A new service loader
|
||||
*/
|
||||
public static <S> ServiceLoader<S> load(Class<S> service) {
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
return ServiceLoader.load(service, cl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new service loader for the given service type, using the
|
||||
* extension class loader.
|
||||
*
|
||||
* <p> This convenience method simply locates the extension class loader,
|
||||
* call it <tt><i>extClassLoader</i></tt>, and then returns
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* ServiceLoader.load(<i>service</i>, <i>extClassLoader</i>)</pre></blockquote>
|
||||
*
|
||||
* <p> If the extension class loader cannot be found then the system class
|
||||
* loader is used; if there is no system class loader then the bootstrap
|
||||
* class loader is used.
|
||||
*
|
||||
* <p> This method is intended for use when only installed providers are
|
||||
* desired. The resulting service will only find and load providers that
|
||||
* have been installed into the current Java virtual machine; providers on
|
||||
* the application's class path will be ignored.
|
||||
*
|
||||
* @param <S> the class of the service type
|
||||
*
|
||||
* @param service
|
||||
* The interface or abstract class representing the service
|
||||
*
|
||||
* @return A new service loader
|
||||
*/
|
||||
public static <S> ServiceLoader<S> loadInstalled(Class<S> service) {
|
||||
ClassLoader cl = ClassLoader.getSystemClassLoader();
|
||||
ClassLoader prev = null;
|
||||
while (cl != null) {
|
||||
prev = cl;
|
||||
cl = cl.getParent();
|
||||
}
|
||||
return ServiceLoader.load(service, prev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string describing this service.
|
||||
*
|
||||
* @return A descriptive string
|
||||
*/
|
||||
public String toString() {
|
||||
return "java.util.ServiceLoader[" + service.getName() + "]";
|
||||
}
|
||||
|
||||
}
|
||||
413
jdkSrc/jdk8/java/util/Set.java
Normal file
413
jdkSrc/jdk8/java/util/Set.java
Normal file
@@ -0,0 +1,413 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* A collection that contains no duplicate elements. More formally, sets
|
||||
* contain no pair of elements <code>e1</code> and <code>e2</code> such that
|
||||
* <code>e1.equals(e2)</code>, and at most one null element. As implied by
|
||||
* its name, this interface models the mathematical <i>set</i> abstraction.
|
||||
*
|
||||
* <p>The <tt>Set</tt> interface places additional stipulations, beyond those
|
||||
* inherited from the <tt>Collection</tt> interface, on the contracts of all
|
||||
* constructors and on the contracts of the <tt>add</tt>, <tt>equals</tt> and
|
||||
* <tt>hashCode</tt> methods. Declarations for other inherited methods are
|
||||
* also included here for convenience. (The specifications accompanying these
|
||||
* declarations have been tailored to the <tt>Set</tt> interface, but they do
|
||||
* not contain any additional stipulations.)
|
||||
*
|
||||
* <p>The additional stipulation on constructors is, not surprisingly,
|
||||
* that all constructors must create a set that contains no duplicate elements
|
||||
* (as defined above).
|
||||
*
|
||||
* <p>Note: Great care must be exercised if mutable objects are used as set
|
||||
* elements. The behavior of a set is not specified if the value of an object
|
||||
* is changed in a manner that affects <tt>equals</tt> comparisons while the
|
||||
* object is an element in the set. A special case of this prohibition is
|
||||
* that it is not permissible for a set to contain itself as an element.
|
||||
*
|
||||
* <p>Some set implementations have restrictions on the elements that
|
||||
* they may contain. For example, some implementations prohibit null elements,
|
||||
* and some have restrictions on the types of their elements. Attempting to
|
||||
* add an ineligible element throws an unchecked exception, typically
|
||||
* <tt>NullPointerException</tt> or <tt>ClassCastException</tt>. Attempting
|
||||
* to query the presence of an ineligible element may throw an exception,
|
||||
* or it may simply return false; some implementations will exhibit the former
|
||||
* behavior and some will exhibit the latter. More generally, attempting an
|
||||
* operation on an ineligible element whose completion would not result in
|
||||
* the insertion of an ineligible element into the set may throw an
|
||||
* exception or it may succeed, at the option of the implementation.
|
||||
* Such exceptions are marked as "optional" in the specification for this
|
||||
* interface.
|
||||
*
|
||||
* <p>This interface is a member of the
|
||||
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
|
||||
* Java Collections Framework</a>.
|
||||
*
|
||||
* @param <E> the type of elements maintained by this set
|
||||
*
|
||||
* @author Josh Bloch
|
||||
* @author Neal Gafter
|
||||
* @see Collection
|
||||
* @see List
|
||||
* @see SortedSet
|
||||
* @see HashSet
|
||||
* @see TreeSet
|
||||
* @see AbstractSet
|
||||
* @see Collections#singleton(java.lang.Object)
|
||||
* @see Collections#EMPTY_SET
|
||||
* @since 1.2
|
||||
*/
|
||||
|
||||
public interface Set<E> extends Collection<E> {
|
||||
// Query Operations
|
||||
|
||||
/**
|
||||
* Returns the number of elements in this set (its cardinality). If this
|
||||
* set contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
|
||||
* <tt>Integer.MAX_VALUE</tt>.
|
||||
*
|
||||
* @return the number of elements in this set (its cardinality)
|
||||
*/
|
||||
int size();
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this set contains no elements.
|
||||
*
|
||||
* @return <tt>true</tt> if this set contains no elements
|
||||
*/
|
||||
boolean isEmpty();
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this set contains the specified element.
|
||||
* More formally, returns <tt>true</tt> if and only if this set
|
||||
* contains an element <tt>e</tt> such that
|
||||
* <tt>(o==null ? e==null : o.equals(e))</tt>.
|
||||
*
|
||||
* @param o element whose presence in this set is to be tested
|
||||
* @return <tt>true</tt> if this set contains the specified element
|
||||
* @throws ClassCastException if the type of the specified element
|
||||
* is incompatible with this set
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if the specified element is null and this
|
||||
* set does not permit null elements
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
*/
|
||||
boolean contains(Object o);
|
||||
|
||||
/**
|
||||
* Returns an iterator over the elements in this set. The elements are
|
||||
* returned in no particular order (unless this set is an instance of some
|
||||
* class that provides a guarantee).
|
||||
*
|
||||
* @return an iterator over the elements in this set
|
||||
*/
|
||||
Iterator<E> iterator();
|
||||
|
||||
/**
|
||||
* Returns an array containing all of the elements in this set.
|
||||
* If this set makes any guarantees as to what order its elements
|
||||
* are returned by its iterator, this method must return the
|
||||
* elements in the same order.
|
||||
*
|
||||
* <p>The returned array will be "safe" in that no references to it
|
||||
* are maintained by this set. (In other words, this method must
|
||||
* allocate a new array even if this set is backed by an array).
|
||||
* The caller is thus free to modify the returned array.
|
||||
*
|
||||
* <p>This method acts as bridge between array-based and collection-based
|
||||
* APIs.
|
||||
*
|
||||
* @return an array containing all the elements in this set
|
||||
*/
|
||||
Object[] toArray();
|
||||
|
||||
/**
|
||||
* Returns an array containing all of the elements in this set; the
|
||||
* runtime type of the returned array is that of the specified array.
|
||||
* If the set fits in the specified array, it is returned therein.
|
||||
* Otherwise, a new array is allocated with the runtime type of the
|
||||
* specified array and the size of this set.
|
||||
*
|
||||
* <p>If this set fits in the specified array with room to spare
|
||||
* (i.e., the array has more elements than this set), the element in
|
||||
* the array immediately following the end of the set is set to
|
||||
* <tt>null</tt>. (This is useful in determining the length of this
|
||||
* set <i>only</i> if the caller knows that this set does not contain
|
||||
* any null elements.)
|
||||
*
|
||||
* <p>If this set makes any guarantees as to what order its elements
|
||||
* are returned by its iterator, this method must return the elements
|
||||
* in the same order.
|
||||
*
|
||||
* <p>Like the {@link #toArray()} method, this method acts as bridge between
|
||||
* array-based and collection-based APIs. Further, this method allows
|
||||
* precise control over the runtime type of the output array, and may,
|
||||
* under certain circumstances, be used to save allocation costs.
|
||||
*
|
||||
* <p>Suppose <tt>x</tt> is a set known to contain only strings.
|
||||
* The following code can be used to dump the set into a newly allocated
|
||||
* array of <tt>String</tt>:
|
||||
*
|
||||
* <pre>
|
||||
* String[] y = x.toArray(new String[0]);</pre>
|
||||
*
|
||||
* Note that <tt>toArray(new Object[0])</tt> is identical in function to
|
||||
* <tt>toArray()</tt>.
|
||||
*
|
||||
* @param a the array into which the elements of this set are to be
|
||||
* stored, if it is big enough; otherwise, a new array of the same
|
||||
* runtime type is allocated for this purpose.
|
||||
* @return an array containing all the elements in this set
|
||||
* @throws ArrayStoreException if the runtime type of the specified array
|
||||
* is not a supertype of the runtime type of every element in this
|
||||
* set
|
||||
* @throws NullPointerException if the specified array is null
|
||||
*/
|
||||
<T> T[] toArray(T[] a);
|
||||
|
||||
|
||||
// Modification Operations
|
||||
|
||||
/**
|
||||
* Adds the specified element to this set if it is not already present
|
||||
* (optional operation). More formally, adds the specified element
|
||||
* <tt>e</tt> to this set if the set contains no element <tt>e2</tt>
|
||||
* such that
|
||||
* <tt>(e==null ? e2==null : e.equals(e2))</tt>.
|
||||
* If this set already contains the element, the call leaves the set
|
||||
* unchanged and returns <tt>false</tt>. In combination with the
|
||||
* restriction on constructors, this ensures that sets never contain
|
||||
* duplicate elements.
|
||||
*
|
||||
* <p>The stipulation above does not imply that sets must accept all
|
||||
* elements; sets may refuse to add any particular element, including
|
||||
* <tt>null</tt>, and throw an exception, as described in the
|
||||
* specification for {@link Collection#add Collection.add}.
|
||||
* Individual set implementations should clearly document any
|
||||
* restrictions on the elements that they may contain.
|
||||
*
|
||||
* @param e element to be added to this set
|
||||
* @return <tt>true</tt> if this set did not already contain the specified
|
||||
* element
|
||||
* @throws UnsupportedOperationException if the <tt>add</tt> operation
|
||||
* is not supported by this set
|
||||
* @throws ClassCastException if the class of the specified element
|
||||
* prevents it from being added to this set
|
||||
* @throws NullPointerException if the specified element is null and this
|
||||
* set does not permit null elements
|
||||
* @throws IllegalArgumentException if some property of the specified element
|
||||
* prevents it from being added to this set
|
||||
*/
|
||||
boolean add(E e);
|
||||
|
||||
|
||||
/**
|
||||
* Removes the specified element from this set if it is present
|
||||
* (optional operation). More formally, removes an element <tt>e</tt>
|
||||
* such that
|
||||
* <tt>(o==null ? e==null : o.equals(e))</tt>, if
|
||||
* this set contains such an element. Returns <tt>true</tt> if this set
|
||||
* contained the element (or equivalently, if this set changed as a
|
||||
* result of the call). (This set will not contain the element once the
|
||||
* call returns.)
|
||||
*
|
||||
* @param o object to be removed from this set, if present
|
||||
* @return <tt>true</tt> if this set contained the specified element
|
||||
* @throws ClassCastException if the type of the specified element
|
||||
* is incompatible with this set
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if the specified element is null and this
|
||||
* set does not permit null elements
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws UnsupportedOperationException if the <tt>remove</tt> operation
|
||||
* is not supported by this set
|
||||
*/
|
||||
boolean remove(Object o);
|
||||
|
||||
|
||||
// Bulk Operations
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this set contains all of the elements of the
|
||||
* specified collection. If the specified collection is also a set, this
|
||||
* method returns <tt>true</tt> if it is a <i>subset</i> of this set.
|
||||
*
|
||||
* @param c collection to be checked for containment in this set
|
||||
* @return <tt>true</tt> if this set contains all of the elements of the
|
||||
* specified collection
|
||||
* @throws ClassCastException if the types of one or more elements
|
||||
* in the specified collection are incompatible with this
|
||||
* set
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if the specified collection contains one
|
||||
* or more null elements and this set does not permit null
|
||||
* elements
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>),
|
||||
* or if the specified collection is null
|
||||
* @see #contains(Object)
|
||||
*/
|
||||
boolean containsAll(Collection<?> c);
|
||||
|
||||
/**
|
||||
* Adds all of the elements in the specified collection to this set if
|
||||
* they're not already present (optional operation). If the specified
|
||||
* collection is also a set, the <tt>addAll</tt> operation effectively
|
||||
* modifies this set so that its value is the <i>union</i> of the two
|
||||
* sets. The behavior of this operation is undefined if the specified
|
||||
* collection is modified while the operation is in progress.
|
||||
*
|
||||
* @param c collection containing elements to be added to this set
|
||||
* @return <tt>true</tt> if this set changed as a result of the call
|
||||
*
|
||||
* @throws UnsupportedOperationException if the <tt>addAll</tt> operation
|
||||
* is not supported by this set
|
||||
* @throws ClassCastException if the class of an element of the
|
||||
* specified collection prevents it from being added to this set
|
||||
* @throws NullPointerException if the specified collection contains one
|
||||
* or more null elements and this set does not permit null
|
||||
* elements, or if the specified collection is null
|
||||
* @throws IllegalArgumentException if some property of an element of the
|
||||
* specified collection prevents it from being added to this set
|
||||
* @see #add(Object)
|
||||
*/
|
||||
boolean addAll(Collection<? extends E> c);
|
||||
|
||||
/**
|
||||
* Retains only the elements in this set that are contained in the
|
||||
* specified collection (optional operation). In other words, removes
|
||||
* from this set all of its elements that are not contained in the
|
||||
* specified collection. If the specified collection is also a set, this
|
||||
* operation effectively modifies this set so that its value is the
|
||||
* <i>intersection</i> of the two sets.
|
||||
*
|
||||
* @param c collection containing elements to be retained in this set
|
||||
* @return <tt>true</tt> if this set changed as a result of the call
|
||||
* @throws UnsupportedOperationException if the <tt>retainAll</tt> operation
|
||||
* is not supported by this set
|
||||
* @throws ClassCastException if the class of an element of this set
|
||||
* is incompatible with the specified collection
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if this set contains a null element and the
|
||||
* specified collection does not permit null elements
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>),
|
||||
* or if the specified collection is null
|
||||
* @see #remove(Object)
|
||||
*/
|
||||
boolean retainAll(Collection<?> c);
|
||||
|
||||
/**
|
||||
* Removes from this set all of its elements that are contained in the
|
||||
* specified collection (optional operation). If the specified
|
||||
* collection is also a set, this operation effectively modifies this
|
||||
* set so that its value is the <i>asymmetric set difference</i> of
|
||||
* the two sets.
|
||||
*
|
||||
* @param c collection containing elements to be removed from this set
|
||||
* @return <tt>true</tt> if this set changed as a result of the call
|
||||
* @throws UnsupportedOperationException if the <tt>removeAll</tt> operation
|
||||
* is not supported by this set
|
||||
* @throws ClassCastException if the class of an element of this set
|
||||
* is incompatible with the specified collection
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if this set contains a null element and the
|
||||
* specified collection does not permit null elements
|
||||
* (<a href="Collection.html#optional-restrictions">optional</a>),
|
||||
* or if the specified collection is null
|
||||
* @see #remove(Object)
|
||||
* @see #contains(Object)
|
||||
*/
|
||||
boolean removeAll(Collection<?> c);
|
||||
|
||||
/**
|
||||
* Removes all of the elements from this set (optional operation).
|
||||
* The set will be empty after this call returns.
|
||||
*
|
||||
* @throws UnsupportedOperationException if the <tt>clear</tt> method
|
||||
* is not supported by this set
|
||||
*/
|
||||
void clear();
|
||||
|
||||
|
||||
// Comparison and hashing
|
||||
|
||||
/**
|
||||
* Compares the specified object with this set for equality. Returns
|
||||
* <tt>true</tt> if the specified object is also a set, the two sets
|
||||
* have the same size, and every member of the specified set is
|
||||
* contained in this set (or equivalently, every member of this set is
|
||||
* contained in the specified set). This definition ensures that the
|
||||
* equals method works properly across different implementations of the
|
||||
* set interface.
|
||||
*
|
||||
* @param o object to be compared for equality with this set
|
||||
* @return <tt>true</tt> if the specified object is equal to this set
|
||||
*/
|
||||
boolean equals(Object o);
|
||||
|
||||
/**
|
||||
* Returns the hash code value for this set. The hash code of a set is
|
||||
* defined to be the sum of the hash codes of the elements in the set,
|
||||
* where the hash code of a <tt>null</tt> element is defined to be zero.
|
||||
* This ensures that <tt>s1.equals(s2)</tt> implies that
|
||||
* <tt>s1.hashCode()==s2.hashCode()</tt> for any two sets <tt>s1</tt>
|
||||
* and <tt>s2</tt>, as required by the general contract of
|
||||
* {@link Object#hashCode}.
|
||||
*
|
||||
* @return the hash code value for this set
|
||||
* @see Object#equals(Object)
|
||||
* @see Set#equals(Object)
|
||||
*/
|
||||
int hashCode();
|
||||
|
||||
/**
|
||||
* Creates a {@code Spliterator} over the elements in this set.
|
||||
*
|
||||
* <p>The {@code Spliterator} reports {@link Spliterator#DISTINCT}.
|
||||
* Implementations should document the reporting of additional
|
||||
* characteristic values.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation creates a
|
||||
* <em><a href="Spliterator.html#binding">late-binding</a></em> spliterator
|
||||
* from the set's {@code Iterator}. The spliterator inherits the
|
||||
* <em>fail-fast</em> properties of the set's iterator.
|
||||
* <p>
|
||||
* The created {@code Spliterator} additionally reports
|
||||
* {@link Spliterator#SIZED}.
|
||||
*
|
||||
* @implNote
|
||||
* The created {@code Spliterator} additionally reports
|
||||
* {@link Spliterator#SUBSIZED}.
|
||||
*
|
||||
* @return a {@code Spliterator} over the elements in this set
|
||||
* @since 1.8
|
||||
*/
|
||||
@Override
|
||||
default Spliterator<E> spliterator() {
|
||||
return Spliterators.spliterator(this, Spliterator.DISTINCT);
|
||||
}
|
||||
}
|
||||
1714
jdkSrc/jdk8/java/util/SimpleTimeZone.java
Normal file
1714
jdkSrc/jdk8/java/util/SimpleTimeZone.java
Normal file
File diff suppressed because it is too large
Load Diff
284
jdkSrc/jdk8/java/util/SortedMap.java
Normal file
284
jdkSrc/jdk8/java/util/SortedMap.java
Normal file
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* A {@link Map} that further provides a <em>total ordering</em> on its keys.
|
||||
* The map is ordered according to the {@linkplain Comparable natural
|
||||
* ordering} of its keys, or by a {@link Comparator} typically
|
||||
* provided at sorted map creation time. This order is reflected when
|
||||
* iterating over the sorted map's collection views (returned by the
|
||||
* {@code entrySet}, {@code keySet} and {@code values} methods).
|
||||
* Several additional operations are provided to take advantage of the
|
||||
* ordering. (This interface is the map analogue of {@link SortedSet}.)
|
||||
*
|
||||
* <p>All keys inserted into a sorted map must implement the {@code Comparable}
|
||||
* interface (or be accepted by the specified comparator). Furthermore, all
|
||||
* such keys must be <em>mutually comparable</em>: {@code k1.compareTo(k2)} (or
|
||||
* {@code comparator.compare(k1, k2)}) must not throw a
|
||||
* {@code ClassCastException} for any keys {@code k1} and {@code k2} in
|
||||
* the sorted map. Attempts to violate this restriction will cause the
|
||||
* offending method or constructor invocation to throw a
|
||||
* {@code ClassCastException}.
|
||||
*
|
||||
* <p>Note that the ordering maintained by a sorted map (whether or not an
|
||||
* explicit comparator is provided) must be <em>consistent with equals</em> if
|
||||
* the sorted map is to correctly implement the {@code Map} interface. (See
|
||||
* the {@code Comparable} interface or {@code Comparator} interface for a
|
||||
* precise definition of <em>consistent with equals</em>.) This is so because
|
||||
* the {@code Map} interface is defined in terms of the {@code equals}
|
||||
* operation, but a sorted map performs all key comparisons using its
|
||||
* {@code compareTo} (or {@code compare}) method, so two keys that are
|
||||
* deemed equal by this method are, from the standpoint of the sorted map,
|
||||
* equal. The behavior of a tree map <em>is</em> well-defined even if its
|
||||
* ordering is inconsistent with equals; it just fails to obey the general
|
||||
* contract of the {@code Map} interface.
|
||||
*
|
||||
* <p>All general-purpose sorted map implementation classes should provide four
|
||||
* "standard" constructors. It is not possible to enforce this recommendation
|
||||
* though as required constructors cannot be specified by interfaces. The
|
||||
* expected "standard" constructors for all sorted map implementations are:
|
||||
* <ol>
|
||||
* <li>A void (no arguments) constructor, which creates an empty sorted map
|
||||
* sorted according to the natural ordering of its keys.</li>
|
||||
* <li>A constructor with a single argument of type {@code Comparator}, which
|
||||
* creates an empty sorted map sorted according to the specified comparator.</li>
|
||||
* <li>A constructor with a single argument of type {@code Map}, which creates
|
||||
* a new map with the same key-value mappings as its argument, sorted
|
||||
* according to the keys' natural ordering.</li>
|
||||
* <li>A constructor with a single argument of type {@code SortedMap}, which
|
||||
* creates a new sorted map with the same key-value mappings and the same
|
||||
* ordering as the input sorted map.</li>
|
||||
* </ol>
|
||||
*
|
||||
* <p><strong>Note</strong>: several methods return submaps with restricted key
|
||||
* ranges. Such ranges are <em>half-open</em>, that is, they include their low
|
||||
* endpoint but not their high endpoint (where applicable). If you need a
|
||||
* <em>closed range</em> (which includes both endpoints), and the key type
|
||||
* allows for calculation of the successor of a given key, merely request
|
||||
* the subrange from {@code lowEndpoint} to
|
||||
* {@code successor(highEndpoint)}. For example, suppose that {@code m}
|
||||
* is a map whose keys are strings. The following idiom obtains a view
|
||||
* containing all of the key-value mappings in {@code m} whose keys are
|
||||
* between {@code low} and {@code high}, inclusive:<pre>
|
||||
* SortedMap<String, V> sub = m.subMap(low, high+"\0");</pre>
|
||||
*
|
||||
* A similar technique can be used to generate an <em>open range</em>
|
||||
* (which contains neither endpoint). The following idiom obtains a
|
||||
* view containing all of the key-value mappings in {@code m} whose keys
|
||||
* are between {@code low} and {@code high}, exclusive:<pre>
|
||||
* SortedMap<String, V> sub = m.subMap(low+"\0", high);</pre>
|
||||
*
|
||||
* <p>This interface is a member of the
|
||||
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
|
||||
* Java Collections Framework</a>.
|
||||
*
|
||||
* @param <K> the type of keys maintained by this map
|
||||
* @param <V> the type of mapped values
|
||||
*
|
||||
* @author Josh Bloch
|
||||
* @see Map
|
||||
* @see TreeMap
|
||||
* @see SortedSet
|
||||
* @see Comparator
|
||||
* @see Comparable
|
||||
* @see Collection
|
||||
* @see ClassCastException
|
||||
* @since 1.2
|
||||
*/
|
||||
|
||||
public interface SortedMap<K,V> extends Map<K,V> {
|
||||
/**
|
||||
* Returns the comparator used to order the keys in this map, or
|
||||
* {@code null} if this map uses the {@linkplain Comparable
|
||||
* natural ordering} of its keys.
|
||||
*
|
||||
* @return the comparator used to order the keys in this map,
|
||||
* or {@code null} if this map uses the natural ordering
|
||||
* of its keys
|
||||
*/
|
||||
Comparator<? super K> comparator();
|
||||
|
||||
/**
|
||||
* Returns a view of the portion of this map whose keys range from
|
||||
* {@code fromKey}, inclusive, to {@code toKey}, exclusive. (If
|
||||
* {@code fromKey} and {@code toKey} are equal, the returned map
|
||||
* is empty.) The returned map is backed by this map, so changes
|
||||
* in the returned map are reflected in this map, and vice-versa.
|
||||
* The returned map supports all optional map operations that this
|
||||
* map supports.
|
||||
*
|
||||
* <p>The returned map will throw an {@code IllegalArgumentException}
|
||||
* on an attempt to insert a key outside its range.
|
||||
*
|
||||
* @param fromKey low endpoint (inclusive) of the keys in the returned map
|
||||
* @param toKey high endpoint (exclusive) of the keys in the returned map
|
||||
* @return a view of the portion of this map whose keys range from
|
||||
* {@code fromKey}, inclusive, to {@code toKey}, exclusive
|
||||
* @throws ClassCastException if {@code fromKey} and {@code toKey}
|
||||
* cannot be compared to one another using this map's comparator
|
||||
* (or, if the map has no comparator, using natural ordering).
|
||||
* Implementations may, but are not required to, throw this
|
||||
* exception if {@code fromKey} or {@code toKey}
|
||||
* cannot be compared to keys currently in the map.
|
||||
* @throws NullPointerException if {@code fromKey} or {@code toKey}
|
||||
* is null and this map does not permit null keys
|
||||
* @throws IllegalArgumentException if {@code fromKey} is greater than
|
||||
* {@code toKey}; or if this map itself has a restricted
|
||||
* range, and {@code fromKey} or {@code toKey} lies
|
||||
* outside the bounds of the range
|
||||
*/
|
||||
SortedMap<K,V> subMap(K fromKey, K toKey);
|
||||
|
||||
/**
|
||||
* Returns a view of the portion of this map whose keys are
|
||||
* strictly less than {@code toKey}. The returned map is backed
|
||||
* by this map, so changes in the returned map are reflected in
|
||||
* this map, and vice-versa. The returned map supports all
|
||||
* optional map operations that this map supports.
|
||||
*
|
||||
* <p>The returned map will throw an {@code IllegalArgumentException}
|
||||
* on an attempt to insert a key outside its range.
|
||||
*
|
||||
* @param toKey high endpoint (exclusive) of the keys in the returned map
|
||||
* @return a view of the portion of this map whose keys are strictly
|
||||
* less than {@code toKey}
|
||||
* @throws ClassCastException if {@code toKey} is not compatible
|
||||
* with this map's comparator (or, if the map has no comparator,
|
||||
* if {@code toKey} does not implement {@link Comparable}).
|
||||
* Implementations may, but are not required to, throw this
|
||||
* exception if {@code toKey} cannot be compared to keys
|
||||
* currently in the map.
|
||||
* @throws NullPointerException if {@code toKey} is null and
|
||||
* this map does not permit null keys
|
||||
* @throws IllegalArgumentException if this map itself has a
|
||||
* restricted range, and {@code toKey} lies outside the
|
||||
* bounds of the range
|
||||
*/
|
||||
SortedMap<K,V> headMap(K toKey);
|
||||
|
||||
/**
|
||||
* Returns a view of the portion of this map whose keys are
|
||||
* greater than or equal to {@code fromKey}. The returned map is
|
||||
* backed by this map, so changes in the returned map are
|
||||
* reflected in this map, and vice-versa. The returned map
|
||||
* supports all optional map operations that this map supports.
|
||||
*
|
||||
* <p>The returned map will throw an {@code IllegalArgumentException}
|
||||
* on an attempt to insert a key outside its range.
|
||||
*
|
||||
* @param fromKey low endpoint (inclusive) of the keys in the returned map
|
||||
* @return a view of the portion of this map whose keys are greater
|
||||
* than or equal to {@code fromKey}
|
||||
* @throws ClassCastException if {@code fromKey} is not compatible
|
||||
* with this map's comparator (or, if the map has no comparator,
|
||||
* if {@code fromKey} does not implement {@link Comparable}).
|
||||
* Implementations may, but are not required to, throw this
|
||||
* exception if {@code fromKey} cannot be compared to keys
|
||||
* currently in the map.
|
||||
* @throws NullPointerException if {@code fromKey} is null and
|
||||
* this map does not permit null keys
|
||||
* @throws IllegalArgumentException if this map itself has a
|
||||
* restricted range, and {@code fromKey} lies outside the
|
||||
* bounds of the range
|
||||
*/
|
||||
SortedMap<K,V> tailMap(K fromKey);
|
||||
|
||||
/**
|
||||
* Returns the first (lowest) key currently in this map.
|
||||
*
|
||||
* @return the first (lowest) key currently in this map
|
||||
* @throws NoSuchElementException if this map is empty
|
||||
*/
|
||||
K firstKey();
|
||||
|
||||
/**
|
||||
* Returns the last (highest) key currently in this map.
|
||||
*
|
||||
* @return the last (highest) key currently in this map
|
||||
* @throws NoSuchElementException if this map is empty
|
||||
*/
|
||||
K lastKey();
|
||||
|
||||
/**
|
||||
* Returns a {@link Set} view of the keys contained in this map.
|
||||
* The set's iterator returns the keys in ascending order.
|
||||
* The set is backed by the map, so changes to the map are
|
||||
* reflected in the set, and vice-versa. If the map is modified
|
||||
* while an iteration over the set is in progress (except through
|
||||
* the iterator's own {@code remove} operation), the results of
|
||||
* the iteration are undefined. The set supports element removal,
|
||||
* which removes the corresponding mapping from the map, via the
|
||||
* {@code Iterator.remove}, {@code Set.remove},
|
||||
* {@code removeAll}, {@code retainAll}, and {@code clear}
|
||||
* operations. It does not support the {@code add} or {@code addAll}
|
||||
* operations.
|
||||
*
|
||||
* @return a set view of the keys contained in this map, sorted in
|
||||
* ascending order
|
||||
*/
|
||||
Set<K> keySet();
|
||||
|
||||
/**
|
||||
* Returns a {@link Collection} view of the values contained in this map.
|
||||
* The collection's iterator returns the values in ascending order
|
||||
* of the corresponding keys.
|
||||
* The collection is backed by the map, so changes to the map are
|
||||
* reflected in the collection, and vice-versa. If the map is
|
||||
* modified while an iteration over the collection is in progress
|
||||
* (except through the iterator's own {@code remove} operation),
|
||||
* the results of the iteration are undefined. The collection
|
||||
* supports element removal, which removes the corresponding
|
||||
* mapping from the map, via the {@code Iterator.remove},
|
||||
* {@code Collection.remove}, {@code removeAll},
|
||||
* {@code retainAll} and {@code clear} operations. It does not
|
||||
* support the {@code add} or {@code addAll} operations.
|
||||
*
|
||||
* @return a collection view of the values contained in this map,
|
||||
* sorted in ascending key order
|
||||
*/
|
||||
Collection<V> values();
|
||||
|
||||
/**
|
||||
* Returns a {@link Set} view of the mappings contained in this map.
|
||||
* The set's iterator returns the entries in ascending key order.
|
||||
* The set is backed by the map, so changes to the map are
|
||||
* reflected in the set, and vice-versa. If the map is modified
|
||||
* while an iteration over the set is in progress (except through
|
||||
* the iterator's own {@code remove} operation, or through the
|
||||
* {@code setValue} operation on a map entry returned by the
|
||||
* iterator) the results of the iteration are undefined. The set
|
||||
* supports element removal, which removes the corresponding
|
||||
* mapping from the map, via the {@code Iterator.remove},
|
||||
* {@code Set.remove}, {@code removeAll}, {@code retainAll} and
|
||||
* {@code clear} operations. It does not support the
|
||||
* {@code add} or {@code addAll} operations.
|
||||
*
|
||||
* @return a set view of the mappings contained in this map,
|
||||
* sorted in ascending key order
|
||||
*/
|
||||
Set<Map.Entry<K, V>> entrySet();
|
||||
}
|
||||
264
jdkSrc/jdk8/java/util/SortedSet.java
Normal file
264
jdkSrc/jdk8/java/util/SortedSet.java
Normal file
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* A {@link Set} that further provides a <i>total ordering</i> on its elements.
|
||||
* The elements are ordered using their {@linkplain Comparable natural
|
||||
* ordering}, or by a {@link Comparator} typically provided at sorted
|
||||
* set creation time. The set's iterator will traverse the set in
|
||||
* ascending element order. Several additional operations are provided
|
||||
* to take advantage of the ordering. (This interface is the set
|
||||
* analogue of {@link SortedMap}.)
|
||||
*
|
||||
* <p>All elements inserted into a sorted set must implement the <tt>Comparable</tt>
|
||||
* interface (or be accepted by the specified comparator). Furthermore, all
|
||||
* such elements must be <i>mutually comparable</i>: <tt>e1.compareTo(e2)</tt>
|
||||
* (or <tt>comparator.compare(e1, e2)</tt>) must not throw a
|
||||
* <tt>ClassCastException</tt> for any elements <tt>e1</tt> and <tt>e2</tt> in
|
||||
* the sorted set. Attempts to violate this restriction will cause the
|
||||
* offending method or constructor invocation to throw a
|
||||
* <tt>ClassCastException</tt>.
|
||||
*
|
||||
* <p>Note that the ordering maintained by a sorted set (whether or not an
|
||||
* explicit comparator is provided) must be <i>consistent with equals</i> if
|
||||
* the sorted set is to correctly implement the <tt>Set</tt> interface. (See
|
||||
* the <tt>Comparable</tt> interface or <tt>Comparator</tt> interface for a
|
||||
* precise definition of <i>consistent with equals</i>.) This is so because
|
||||
* the <tt>Set</tt> interface is defined in terms of the <tt>equals</tt>
|
||||
* operation, but a sorted set performs all element comparisons using its
|
||||
* <tt>compareTo</tt> (or <tt>compare</tt>) method, so two elements that are
|
||||
* deemed equal by this method are, from the standpoint of the sorted set,
|
||||
* equal. The behavior of a sorted set <i>is</i> well-defined even if its
|
||||
* ordering is inconsistent with equals; it just fails to obey the general
|
||||
* contract of the <tt>Set</tt> interface.
|
||||
*
|
||||
* <p>All general-purpose sorted set implementation classes should
|
||||
* provide four "standard" constructors: 1) A void (no arguments)
|
||||
* constructor, which creates an empty sorted set sorted according to
|
||||
* the natural ordering of its elements. 2) A constructor with a
|
||||
* single argument of type <tt>Comparator</tt>, which creates an empty
|
||||
* sorted set sorted according to the specified comparator. 3) A
|
||||
* constructor with a single argument of type <tt>Collection</tt>,
|
||||
* which creates a new sorted set with the same elements as its
|
||||
* argument, sorted according to the natural ordering of the elements.
|
||||
* 4) A constructor with a single argument of type <tt>SortedSet</tt>,
|
||||
* which creates a new sorted set with the same elements and the same
|
||||
* ordering as the input sorted set. There is no way to enforce this
|
||||
* recommendation, as interfaces cannot contain constructors.
|
||||
*
|
||||
* <p>Note: several methods return subsets with restricted ranges.
|
||||
* Such ranges are <i>half-open</i>, that is, they include their low
|
||||
* endpoint but not their high endpoint (where applicable).
|
||||
* If you need a <i>closed range</i> (which includes both endpoints), and
|
||||
* the element type allows for calculation of the successor of a given
|
||||
* value, merely request the subrange from <tt>lowEndpoint</tt> to
|
||||
* <tt>successor(highEndpoint)</tt>. For example, suppose that <tt>s</tt>
|
||||
* is a sorted set of strings. The following idiom obtains a view
|
||||
* containing all of the strings in <tt>s</tt> from <tt>low</tt> to
|
||||
* <tt>high</tt>, inclusive:<pre>
|
||||
* SortedSet<String> sub = s.subSet(low, high+"\0");</pre>
|
||||
*
|
||||
* A similar technique can be used to generate an <i>open range</i> (which
|
||||
* contains neither endpoint). The following idiom obtains a view
|
||||
* containing all of the Strings in <tt>s</tt> from <tt>low</tt> to
|
||||
* <tt>high</tt>, exclusive:<pre>
|
||||
* SortedSet<String> sub = s.subSet(low+"\0", high);</pre>
|
||||
*
|
||||
* <p>This interface is a member of the
|
||||
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
|
||||
* Java Collections Framework</a>.
|
||||
*
|
||||
* @param <E> the type of elements maintained by this set
|
||||
*
|
||||
* @author Josh Bloch
|
||||
* @see Set
|
||||
* @see TreeSet
|
||||
* @see SortedMap
|
||||
* @see Collection
|
||||
* @see Comparable
|
||||
* @see Comparator
|
||||
* @see ClassCastException
|
||||
* @since 1.2
|
||||
*/
|
||||
|
||||
public interface SortedSet<E> extends Set<E> {
|
||||
/**
|
||||
* Returns the comparator used to order the elements in this set,
|
||||
* or <tt>null</tt> if this set uses the {@linkplain Comparable
|
||||
* natural ordering} of its elements.
|
||||
*
|
||||
* @return the comparator used to order the elements in this set,
|
||||
* or <tt>null</tt> if this set uses the natural ordering
|
||||
* of its elements
|
||||
*/
|
||||
Comparator<? super E> comparator();
|
||||
|
||||
/**
|
||||
* Returns a view of the portion of this set whose elements range
|
||||
* from <tt>fromElement</tt>, inclusive, to <tt>toElement</tt>,
|
||||
* exclusive. (If <tt>fromElement</tt> and <tt>toElement</tt> are
|
||||
* equal, the returned set is empty.) The returned set is backed
|
||||
* by this set, so changes in the returned set are reflected in
|
||||
* this set, and vice-versa. The returned set supports all
|
||||
* optional set operations that this set supports.
|
||||
*
|
||||
* <p>The returned set will throw an <tt>IllegalArgumentException</tt>
|
||||
* on an attempt to insert an element outside its range.
|
||||
*
|
||||
* @param fromElement low endpoint (inclusive) of the returned set
|
||||
* @param toElement high endpoint (exclusive) of the returned set
|
||||
* @return a view of the portion of this set whose elements range from
|
||||
* <tt>fromElement</tt>, inclusive, to <tt>toElement</tt>, exclusive
|
||||
* @throws ClassCastException if <tt>fromElement</tt> and
|
||||
* <tt>toElement</tt> cannot be compared to one another using this
|
||||
* set's comparator (or, if the set has no comparator, using
|
||||
* natural ordering). Implementations may, but are not required
|
||||
* to, throw this exception if <tt>fromElement</tt> or
|
||||
* <tt>toElement</tt> cannot be compared to elements currently in
|
||||
* the set.
|
||||
* @throws NullPointerException if <tt>fromElement</tt> or
|
||||
* <tt>toElement</tt> is null and this set does not permit null
|
||||
* elements
|
||||
* @throws IllegalArgumentException if <tt>fromElement</tt> is
|
||||
* greater than <tt>toElement</tt>; or if this set itself
|
||||
* has a restricted range, and <tt>fromElement</tt> or
|
||||
* <tt>toElement</tt> lies outside the bounds of the range
|
||||
*/
|
||||
SortedSet<E> subSet(E fromElement, E toElement);
|
||||
|
||||
/**
|
||||
* Returns a view of the portion of this set whose elements are
|
||||
* strictly less than <tt>toElement</tt>. The returned set is
|
||||
* backed by this set, so changes in the returned set are
|
||||
* reflected in this set, and vice-versa. The returned set
|
||||
* supports all optional set operations that this set supports.
|
||||
*
|
||||
* <p>The returned set will throw an <tt>IllegalArgumentException</tt>
|
||||
* on an attempt to insert an element outside its range.
|
||||
*
|
||||
* @param toElement high endpoint (exclusive) of the returned set
|
||||
* @return a view of the portion of this set whose elements are strictly
|
||||
* less than <tt>toElement</tt>
|
||||
* @throws ClassCastException if <tt>toElement</tt> is not compatible
|
||||
* with this set's comparator (or, if the set has no comparator,
|
||||
* if <tt>toElement</tt> does not implement {@link Comparable}).
|
||||
* Implementations may, but are not required to, throw this
|
||||
* exception if <tt>toElement</tt> cannot be compared to elements
|
||||
* currently in the set.
|
||||
* @throws NullPointerException if <tt>toElement</tt> is null and
|
||||
* this set does not permit null elements
|
||||
* @throws IllegalArgumentException if this set itself has a
|
||||
* restricted range, and <tt>toElement</tt> lies outside the
|
||||
* bounds of the range
|
||||
*/
|
||||
SortedSet<E> headSet(E toElement);
|
||||
|
||||
/**
|
||||
* Returns a view of the portion of this set whose elements are
|
||||
* greater than or equal to <tt>fromElement</tt>. The returned
|
||||
* set is backed by this set, so changes in the returned set are
|
||||
* reflected in this set, and vice-versa. The returned set
|
||||
* supports all optional set operations that this set supports.
|
||||
*
|
||||
* <p>The returned set will throw an <tt>IllegalArgumentException</tt>
|
||||
* on an attempt to insert an element outside its range.
|
||||
*
|
||||
* @param fromElement low endpoint (inclusive) of the returned set
|
||||
* @return a view of the portion of this set whose elements are greater
|
||||
* than or equal to <tt>fromElement</tt>
|
||||
* @throws ClassCastException if <tt>fromElement</tt> is not compatible
|
||||
* with this set's comparator (or, if the set has no comparator,
|
||||
* if <tt>fromElement</tt> does not implement {@link Comparable}).
|
||||
* Implementations may, but are not required to, throw this
|
||||
* exception if <tt>fromElement</tt> cannot be compared to elements
|
||||
* currently in the set.
|
||||
* @throws NullPointerException if <tt>fromElement</tt> is null
|
||||
* and this set does not permit null elements
|
||||
* @throws IllegalArgumentException if this set itself has a
|
||||
* restricted range, and <tt>fromElement</tt> lies outside the
|
||||
* bounds of the range
|
||||
*/
|
||||
SortedSet<E> tailSet(E fromElement);
|
||||
|
||||
/**
|
||||
* Returns the first (lowest) element currently in this set.
|
||||
*
|
||||
* @return the first (lowest) element currently in this set
|
||||
* @throws NoSuchElementException if this set is empty
|
||||
*/
|
||||
E first();
|
||||
|
||||
/**
|
||||
* Returns the last (highest) element currently in this set.
|
||||
*
|
||||
* @return the last (highest) element currently in this set
|
||||
* @throws NoSuchElementException if this set is empty
|
||||
*/
|
||||
E last();
|
||||
|
||||
/**
|
||||
* Creates a {@code Spliterator} over the elements in this sorted set.
|
||||
*
|
||||
* <p>The {@code Spliterator} reports {@link Spliterator#DISTINCT},
|
||||
* {@link Spliterator#SORTED} and {@link Spliterator#ORDERED}.
|
||||
* Implementations should document the reporting of additional
|
||||
* characteristic values.
|
||||
*
|
||||
* <p>The spliterator's comparator (see
|
||||
* {@link java.util.Spliterator#getComparator()}) must be {@code null} if
|
||||
* the sorted set's comparator (see {@link #comparator()}) is {@code null}.
|
||||
* Otherwise, the spliterator's comparator must be the same as or impose the
|
||||
* same total ordering as the sorted set's comparator.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation creates a
|
||||
* <em><a href="Spliterator.html#binding">late-binding</a></em> spliterator
|
||||
* from the sorted set's {@code Iterator}. The spliterator inherits the
|
||||
* <em>fail-fast</em> properties of the set's iterator. The
|
||||
* spliterator's comparator is the same as the sorted set's comparator.
|
||||
* <p>
|
||||
* The created {@code Spliterator} additionally reports
|
||||
* {@link Spliterator#SIZED}.
|
||||
*
|
||||
* @implNote
|
||||
* The created {@code Spliterator} additionally reports
|
||||
* {@link Spliterator#SUBSIZED}.
|
||||
*
|
||||
* @return a {@code Spliterator} over the elements in this sorted set
|
||||
* @since 1.8
|
||||
*/
|
||||
@Override
|
||||
default Spliterator<E> spliterator() {
|
||||
return new Spliterators.IteratorSpliterator<E>(
|
||||
this, Spliterator.DISTINCT | Spliterator.SORTED | Spliterator.ORDERED) {
|
||||
@Override
|
||||
public Comparator<? super E> getComparator() {
|
||||
return SortedSet.this.comparator();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
832
jdkSrc/jdk8/java/util/Spliterator.java
Normal file
832
jdkSrc/jdk8/java/util/Spliterator.java
Normal file
@@ -0,0 +1,832 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.util;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.DoubleConsumer;
|
||||
import java.util.function.IntConsumer;
|
||||
import java.util.function.LongConsumer;
|
||||
|
||||
/**
|
||||
* An object for traversing and partitioning elements of a source. The source
|
||||
* of elements covered by a Spliterator could be, for example, an array, a
|
||||
* {@link Collection}, an IO channel, or a generator function.
|
||||
*
|
||||
* <p>A Spliterator may traverse elements individually ({@link
|
||||
* #tryAdvance tryAdvance()}) or sequentially in bulk
|
||||
* ({@link #forEachRemaining forEachRemaining()}).
|
||||
*
|
||||
* <p>A Spliterator may also partition off some of its elements (using
|
||||
* {@link #trySplit}) as another Spliterator, to be used in
|
||||
* possibly-parallel operations. Operations using a Spliterator that
|
||||
* cannot split, or does so in a highly imbalanced or inefficient
|
||||
* manner, are unlikely to benefit from parallelism. Traversal
|
||||
* and splitting exhaust elements; each Spliterator is useful for only a single
|
||||
* bulk computation.
|
||||
*
|
||||
* <p>A Spliterator also reports a set of {@link #characteristics()} of its
|
||||
* structure, source, and elements from among {@link #ORDERED},
|
||||
* {@link #DISTINCT}, {@link #SORTED}, {@link #SIZED}, {@link #NONNULL},
|
||||
* {@link #IMMUTABLE}, {@link #CONCURRENT}, and {@link #SUBSIZED}. These may
|
||||
* be employed by Spliterator clients to control, specialize or simplify
|
||||
* computation. For example, a Spliterator for a {@link Collection} would
|
||||
* report {@code SIZED}, a Spliterator for a {@link Set} would report
|
||||
* {@code DISTINCT}, and a Spliterator for a {@link SortedSet} would also
|
||||
* report {@code SORTED}. Characteristics are reported as a simple unioned bit
|
||||
* set.
|
||||
*
|
||||
* Some characteristics additionally constrain method behavior; for example if
|
||||
* {@code ORDERED}, traversal methods must conform to their documented ordering.
|
||||
* New characteristics may be defined in the future, so implementors should not
|
||||
* assign meanings to unlisted values.
|
||||
*
|
||||
* <p><a name="binding">A Spliterator that does not report {@code IMMUTABLE} or
|
||||
* {@code CONCURRENT} is expected to have a documented policy concerning:
|
||||
* when the spliterator <em>binds</em> to the element source; and detection of
|
||||
* structural interference of the element source detected after binding.</a> A
|
||||
* <em>late-binding</em> Spliterator binds to the source of elements at the
|
||||
* point of first traversal, first split, or first query for estimated size,
|
||||
* rather than at the time the Spliterator is created. A Spliterator that is
|
||||
* not <em>late-binding</em> binds to the source of elements at the point of
|
||||
* construction or first invocation of any method. Modifications made to the
|
||||
* source prior to binding are reflected when the Spliterator is traversed.
|
||||
* After binding a Spliterator should, on a best-effort basis, throw
|
||||
* {@link ConcurrentModificationException} if structural interference is
|
||||
* detected. Spliterators that do this are called <em>fail-fast</em>. The
|
||||
* bulk traversal method ({@link #forEachRemaining forEachRemaining()}) of a
|
||||
* Spliterator may optimize traversal and check for structural interference
|
||||
* after all elements have been traversed, rather than checking per-element and
|
||||
* failing immediately.
|
||||
*
|
||||
* <p>Spliterators can provide an estimate of the number of remaining elements
|
||||
* via the {@link #estimateSize} method. Ideally, as reflected in characteristic
|
||||
* {@link #SIZED}, this value corresponds exactly to the number of elements
|
||||
* that would be encountered in a successful traversal. However, even when not
|
||||
* exactly known, an estimated value value may still be useful to operations
|
||||
* being performed on the source, such as helping to determine whether it is
|
||||
* preferable to split further or traverse the remaining elements sequentially.
|
||||
*
|
||||
* <p>Despite their obvious utility in parallel algorithms, spliterators are not
|
||||
* expected to be thread-safe; instead, implementations of parallel algorithms
|
||||
* using spliterators should ensure that the spliterator is only used by one
|
||||
* thread at a time. This is generally easy to attain via <em>serial
|
||||
* thread-confinement</em>, which often is a natural consequence of typical
|
||||
* parallel algorithms that work by recursive decomposition. A thread calling
|
||||
* {@link #trySplit()} may hand over the returned Spliterator to another thread,
|
||||
* which in turn may traverse or further split that Spliterator. The behaviour
|
||||
* of splitting and traversal is undefined if two or more threads operate
|
||||
* concurrently on the same spliterator. If the original thread hands a
|
||||
* spliterator off to another thread for processing, it is best if that handoff
|
||||
* occurs before any elements are consumed with {@link #tryAdvance(Consumer)
|
||||
* tryAdvance()}, as certain guarantees (such as the accuracy of
|
||||
* {@link #estimateSize()} for {@code SIZED} spliterators) are only valid before
|
||||
* traversal has begun.
|
||||
*
|
||||
* <p>Primitive subtype specializations of {@code Spliterator} are provided for
|
||||
* {@link OfInt int}, {@link OfLong long}, and {@link OfDouble double} values.
|
||||
* The subtype default implementations of
|
||||
* {@link Spliterator#tryAdvance(java.util.function.Consumer)}
|
||||
* and {@link Spliterator#forEachRemaining(java.util.function.Consumer)} box
|
||||
* primitive values to instances of their corresponding wrapper class. Such
|
||||
* boxing may undermine any performance advantages gained by using the primitive
|
||||
* specializations. To avoid boxing, the corresponding primitive-based methods
|
||||
* should be used. For example,
|
||||
* {@link Spliterator.OfInt#tryAdvance(java.util.function.IntConsumer)}
|
||||
* and {@link Spliterator.OfInt#forEachRemaining(java.util.function.IntConsumer)}
|
||||
* should be used in preference to
|
||||
* {@link Spliterator.OfInt#tryAdvance(java.util.function.Consumer)} and
|
||||
* {@link Spliterator.OfInt#forEachRemaining(java.util.function.Consumer)}.
|
||||
* Traversal of primitive values using boxing-based methods
|
||||
* {@link #tryAdvance tryAdvance()} and
|
||||
* {@link #forEachRemaining(java.util.function.Consumer) forEachRemaining()}
|
||||
* does not affect the order in which the values, transformed to boxed values,
|
||||
* are encountered.
|
||||
*
|
||||
* @apiNote
|
||||
* <p>Spliterators, like {@code Iterator}s, are for traversing the elements of
|
||||
* a source. The {@code Spliterator} API was designed to support efficient
|
||||
* parallel traversal in addition to sequential traversal, by supporting
|
||||
* decomposition as well as single-element iteration. In addition, the
|
||||
* protocol for accessing elements via a Spliterator is designed to impose
|
||||
* smaller per-element overhead than {@code Iterator}, and to avoid the inherent
|
||||
* race involved in having separate methods for {@code hasNext()} and
|
||||
* {@code next()}.
|
||||
*
|
||||
* <p>For mutable sources, arbitrary and non-deterministic behavior may occur if
|
||||
* the source is structurally interfered with (elements added, replaced, or
|
||||
* removed) between the time that the Spliterator binds to its data source and
|
||||
* the end of traversal. For example, such interference will produce arbitrary,
|
||||
* non-deterministic results when using the {@code java.util.stream} framework.
|
||||
*
|
||||
* <p>Structural interference of a source can be managed in the following ways
|
||||
* (in approximate order of decreasing desirability):
|
||||
* <ul>
|
||||
* <li>The source cannot be structurally interfered with.
|
||||
* <br>For example, an instance of
|
||||
* {@link java.util.concurrent.CopyOnWriteArrayList} is an immutable source.
|
||||
* A Spliterator created from the source reports a characteristic of
|
||||
* {@code IMMUTABLE}.</li>
|
||||
* <li>The source manages concurrent modifications.
|
||||
* <br>For example, a key set of a {@link java.util.concurrent.ConcurrentHashMap}
|
||||
* is a concurrent source. A Spliterator created from the source reports a
|
||||
* characteristic of {@code CONCURRENT}.</li>
|
||||
* <li>The mutable source provides a late-binding and fail-fast Spliterator.
|
||||
* <br>Late binding narrows the window during which interference can affect
|
||||
* the calculation; fail-fast detects, on a best-effort basis, that structural
|
||||
* interference has occurred after traversal has commenced and throws
|
||||
* {@link ConcurrentModificationException}. For example, {@link ArrayList},
|
||||
* and many other non-concurrent {@code Collection} classes in the JDK, provide
|
||||
* a late-binding, fail-fast spliterator.</li>
|
||||
* <li>The mutable source provides a non-late-binding but fail-fast Spliterator.
|
||||
* <br>The source increases the likelihood of throwing
|
||||
* {@code ConcurrentModificationException} since the window of potential
|
||||
* interference is larger.</li>
|
||||
* <li>The mutable source provides a late-binding and non-fail-fast Spliterator.
|
||||
* <br>The source risks arbitrary, non-deterministic behavior after traversal
|
||||
* has commenced since interference is not detected.
|
||||
* </li>
|
||||
* <li>The mutable source provides a non-late-binding and non-fail-fast
|
||||
* Spliterator.
|
||||
* <br>The source increases the risk of arbitrary, non-deterministic behavior
|
||||
* since non-detected interference may occur after construction.
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* <p><b>Example.</b> Here is a class (not a very useful one, except
|
||||
* for illustration) that maintains an array in which the actual data
|
||||
* are held in even locations, and unrelated tag data are held in odd
|
||||
* locations. Its Spliterator ignores the tags.
|
||||
*
|
||||
* <pre> {@code
|
||||
* class TaggedArray<T> {
|
||||
* private final Object[] elements; // immutable after construction
|
||||
* TaggedArray(T[] data, Object[] tags) {
|
||||
* int size = data.length;
|
||||
* if (tags.length != size) throw new IllegalArgumentException();
|
||||
* this.elements = new Object[2 * size];
|
||||
* for (int i = 0, j = 0; i < size; ++i) {
|
||||
* elements[j++] = data[i];
|
||||
* elements[j++] = tags[i];
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* public Spliterator<T> spliterator() {
|
||||
* return new TaggedArraySpliterator<>(elements, 0, elements.length);
|
||||
* }
|
||||
*
|
||||
* static class TaggedArraySpliterator<T> implements Spliterator<T> {
|
||||
* private final Object[] array;
|
||||
* private int origin; // current index, advanced on split or traversal
|
||||
* private final int fence; // one past the greatest index
|
||||
*
|
||||
* TaggedArraySpliterator(Object[] array, int origin, int fence) {
|
||||
* this.array = array; this.origin = origin; this.fence = fence;
|
||||
* }
|
||||
*
|
||||
* public void forEachRemaining(Consumer<? super T> action) {
|
||||
* for (; origin < fence; origin += 2)
|
||||
* action.accept((T) array[origin]);
|
||||
* }
|
||||
*
|
||||
* public boolean tryAdvance(Consumer<? super T> action) {
|
||||
* if (origin < fence) {
|
||||
* action.accept((T) array[origin]);
|
||||
* origin += 2;
|
||||
* return true;
|
||||
* }
|
||||
* else // cannot advance
|
||||
* return false;
|
||||
* }
|
||||
*
|
||||
* public Spliterator<T> trySplit() {
|
||||
* int lo = origin; // divide range in half
|
||||
* int mid = ((lo + fence) >>> 1) & ~1; // force midpoint to be even
|
||||
* if (lo < mid) { // split out left half
|
||||
* origin = mid; // reset this Spliterator's origin
|
||||
* return new TaggedArraySpliterator<>(array, lo, mid);
|
||||
* }
|
||||
* else // too small to split
|
||||
* return null;
|
||||
* }
|
||||
*
|
||||
* public long estimateSize() {
|
||||
* return (long)((fence - origin) / 2);
|
||||
* }
|
||||
*
|
||||
* public int characteristics() {
|
||||
* return ORDERED | SIZED | IMMUTABLE | SUBSIZED;
|
||||
* }
|
||||
* }
|
||||
* }}</pre>
|
||||
*
|
||||
* <p>As an example how a parallel computation framework, such as the
|
||||
* {@code java.util.stream} package, would use Spliterator in a parallel
|
||||
* computation, here is one way to implement an associated parallel forEach,
|
||||
* that illustrates the primary usage idiom of splitting off subtasks until
|
||||
* the estimated amount of work is small enough to perform
|
||||
* sequentially. Here we assume that the order of processing across
|
||||
* subtasks doesn't matter; different (forked) tasks may further split
|
||||
* and process elements concurrently in undetermined order. This
|
||||
* example uses a {@link java.util.concurrent.CountedCompleter};
|
||||
* similar usages apply to other parallel task constructions.
|
||||
*
|
||||
* <pre>{@code
|
||||
* static <T> void parEach(TaggedArray<T> a, Consumer<T> action) {
|
||||
* Spliterator<T> s = a.spliterator();
|
||||
* long targetBatchSize = s.estimateSize() / (ForkJoinPool.getCommonPoolParallelism() * 8);
|
||||
* new ParEach(null, s, action, targetBatchSize).invoke();
|
||||
* }
|
||||
*
|
||||
* static class ParEach<T> extends CountedCompleter<Void> {
|
||||
* final Spliterator<T> spliterator;
|
||||
* final Consumer<T> action;
|
||||
* final long targetBatchSize;
|
||||
*
|
||||
* ParEach(ParEach<T> parent, Spliterator<T> spliterator,
|
||||
* Consumer<T> action, long targetBatchSize) {
|
||||
* super(parent);
|
||||
* this.spliterator = spliterator; this.action = action;
|
||||
* this.targetBatchSize = targetBatchSize;
|
||||
* }
|
||||
*
|
||||
* public void compute() {
|
||||
* Spliterator<T> sub;
|
||||
* while (spliterator.estimateSize() > targetBatchSize &&
|
||||
* (sub = spliterator.trySplit()) != null) {
|
||||
* addToPendingCount(1);
|
||||
* new ParEach<>(this, sub, action, targetBatchSize).fork();
|
||||
* }
|
||||
* spliterator.forEachRemaining(action);
|
||||
* propagateCompletion();
|
||||
* }
|
||||
* }}</pre>
|
||||
*
|
||||
* @implNote
|
||||
* If the boolean system property {@code org.openjdk.java.util.stream.tripwire}
|
||||
* is set to {@code true} then diagnostic warnings are reported if boxing of
|
||||
* primitive values occur when operating on primitive subtype specializations.
|
||||
*
|
||||
* @param <T> the type of elements returned by this Spliterator
|
||||
*
|
||||
* @see Collection
|
||||
* @since 1.8
|
||||
*/
|
||||
public interface Spliterator<T> {
|
||||
/**
|
||||
* If a remaining element exists, performs the given action on it,
|
||||
* returning {@code true}; else returns {@code false}. If this
|
||||
* Spliterator is {@link #ORDERED} the action is performed on the
|
||||
* next element in encounter order. Exceptions thrown by the
|
||||
* action are relayed to the caller.
|
||||
*
|
||||
* @param action The action
|
||||
* @return {@code false} if no remaining elements existed
|
||||
* upon entry to this method, else {@code true}.
|
||||
* @throws NullPointerException if the specified action is null
|
||||
*/
|
||||
boolean tryAdvance(Consumer<? super T> action);
|
||||
|
||||
/**
|
||||
* Performs the given action for each remaining element, sequentially in
|
||||
* the current thread, until all elements have been processed or the action
|
||||
* throws an exception. If this Spliterator is {@link #ORDERED}, actions
|
||||
* are performed in encounter order. Exceptions thrown by the action
|
||||
* are relayed to the caller.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation repeatedly invokes {@link #tryAdvance} until
|
||||
* it returns {@code false}. It should be overridden whenever possible.
|
||||
*
|
||||
* @param action The action
|
||||
* @throws NullPointerException if the specified action is null
|
||||
*/
|
||||
default void forEachRemaining(Consumer<? super T> action) {
|
||||
do { } while (tryAdvance(action));
|
||||
}
|
||||
|
||||
/**
|
||||
* If this spliterator can be partitioned, returns a Spliterator
|
||||
* covering elements, that will, upon return from this method, not
|
||||
* be covered by this Spliterator.
|
||||
*
|
||||
* <p>If this Spliterator is {@link #ORDERED}, the returned Spliterator
|
||||
* must cover a strict prefix of the elements.
|
||||
*
|
||||
* <p>Unless this Spliterator covers an infinite number of elements,
|
||||
* repeated calls to {@code trySplit()} must eventually return {@code null}.
|
||||
* Upon non-null return:
|
||||
* <ul>
|
||||
* <li>the value reported for {@code estimateSize()} before splitting,
|
||||
* must, after splitting, be greater than or equal to {@code estimateSize()}
|
||||
* for this and the returned Spliterator; and</li>
|
||||
* <li>if this Spliterator is {@code SUBSIZED}, then {@code estimateSize()}
|
||||
* for this spliterator before splitting must be equal to the sum of
|
||||
* {@code estimateSize()} for this and the returned Spliterator after
|
||||
* splitting.</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>This method may return {@code null} for any reason,
|
||||
* including emptiness, inability to split after traversal has
|
||||
* commenced, data structure constraints, and efficiency
|
||||
* considerations.
|
||||
*
|
||||
* @apiNote
|
||||
* An ideal {@code trySplit} method efficiently (without
|
||||
* traversal) divides its elements exactly in half, allowing
|
||||
* balanced parallel computation. Many departures from this ideal
|
||||
* remain highly effective; for example, only approximately
|
||||
* splitting an approximately balanced tree, or for a tree in
|
||||
* which leaf nodes may contain either one or two elements,
|
||||
* failing to further split these nodes. However, large
|
||||
* deviations in balance and/or overly inefficient {@code
|
||||
* trySplit} mechanics typically result in poor parallel
|
||||
* performance.
|
||||
*
|
||||
* @return a {@code Spliterator} covering some portion of the
|
||||
* elements, or {@code null} if this spliterator cannot be split
|
||||
*/
|
||||
Spliterator<T> trySplit();
|
||||
|
||||
/**
|
||||
* Returns an estimate of the number of elements that would be
|
||||
* encountered by a {@link #forEachRemaining} traversal, or returns {@link
|
||||
* Long#MAX_VALUE} if infinite, unknown, or too expensive to compute.
|
||||
*
|
||||
* <p>If this Spliterator is {@link #SIZED} and has not yet been partially
|
||||
* traversed or split, or this Spliterator is {@link #SUBSIZED} and has
|
||||
* not yet been partially traversed, this estimate must be an accurate
|
||||
* count of elements that would be encountered by a complete traversal.
|
||||
* Otherwise, this estimate may be arbitrarily inaccurate, but must decrease
|
||||
* as specified across invocations of {@link #trySplit}.
|
||||
*
|
||||
* @apiNote
|
||||
* Even an inexact estimate is often useful and inexpensive to compute.
|
||||
* For example, a sub-spliterator of an approximately balanced binary tree
|
||||
* may return a value that estimates the number of elements to be half of
|
||||
* that of its parent; if the root Spliterator does not maintain an
|
||||
* accurate count, it could estimate size to be the power of two
|
||||
* corresponding to its maximum depth.
|
||||
*
|
||||
* @return the estimated size, or {@code Long.MAX_VALUE} if infinite,
|
||||
* unknown, or too expensive to compute.
|
||||
*/
|
||||
long estimateSize();
|
||||
|
||||
/**
|
||||
* Convenience method that returns {@link #estimateSize()} if this
|
||||
* Spliterator is {@link #SIZED}, else {@code -1}.
|
||||
* @implSpec
|
||||
* The default implementation returns the result of {@code estimateSize()}
|
||||
* if the Spliterator reports a characteristic of {@code SIZED}, and
|
||||
* {@code -1} otherwise.
|
||||
*
|
||||
* @return the exact size, if known, else {@code -1}.
|
||||
*/
|
||||
default long getExactSizeIfKnown() {
|
||||
return (characteristics() & SIZED) == 0 ? -1L : estimateSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a set of characteristics of this Spliterator and its
|
||||
* elements. The result is represented as ORed values from {@link
|
||||
* #ORDERED}, {@link #DISTINCT}, {@link #SORTED}, {@link #SIZED},
|
||||
* {@link #NONNULL}, {@link #IMMUTABLE}, {@link #CONCURRENT},
|
||||
* {@link #SUBSIZED}. Repeated calls to {@code characteristics()} on
|
||||
* a given spliterator, prior to or in-between calls to {@code trySplit},
|
||||
* should always return the same result.
|
||||
*
|
||||
* <p>If a Spliterator reports an inconsistent set of
|
||||
* characteristics (either those returned from a single invocation
|
||||
* or across multiple invocations), no guarantees can be made
|
||||
* about any computation using this Spliterator.
|
||||
*
|
||||
* @apiNote The characteristics of a given spliterator before splitting
|
||||
* may differ from the characteristics after splitting. For specific
|
||||
* examples see the characteristic values {@link #SIZED}, {@link #SUBSIZED}
|
||||
* and {@link #CONCURRENT}.
|
||||
*
|
||||
* @return a representation of characteristics
|
||||
*/
|
||||
int characteristics();
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this Spliterator's {@link
|
||||
* #characteristics} contain all of the given characteristics.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation returns true if the corresponding bits
|
||||
* of the given characteristics are set.
|
||||
*
|
||||
* @param characteristics the characteristics to check for
|
||||
* @return {@code true} if all the specified characteristics are present,
|
||||
* else {@code false}
|
||||
*/
|
||||
default boolean hasCharacteristics(int characteristics) {
|
||||
return (characteristics() & characteristics) == characteristics;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this Spliterator's source is {@link #SORTED} by a {@link Comparator},
|
||||
* returns that {@code Comparator}. If the source is {@code SORTED} in
|
||||
* {@linkplain Comparable natural order}, returns {@code null}. Otherwise,
|
||||
* if the source is not {@code SORTED}, throws {@link IllegalStateException}.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation always throws {@link IllegalStateException}.
|
||||
*
|
||||
* @return a Comparator, or {@code null} if the elements are sorted in the
|
||||
* natural order.
|
||||
* @throws IllegalStateException if the spliterator does not report
|
||||
* a characteristic of {@code SORTED}.
|
||||
*/
|
||||
default Comparator<? super T> getComparator() {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Characteristic value signifying that an encounter order is defined for
|
||||
* elements. If so, this Spliterator guarantees that method
|
||||
* {@link #trySplit} splits a strict prefix of elements, that method
|
||||
* {@link #tryAdvance} steps by one element in prefix order, and that
|
||||
* {@link #forEachRemaining} performs actions in encounter order.
|
||||
*
|
||||
* <p>A {@link Collection} has an encounter order if the corresponding
|
||||
* {@link Collection#iterator} documents an order. If so, the encounter
|
||||
* order is the same as the documented order. Otherwise, a collection does
|
||||
* not have an encounter order.
|
||||
*
|
||||
* @apiNote Encounter order is guaranteed to be ascending index order for
|
||||
* any {@link List}. But no order is guaranteed for hash-based collections
|
||||
* such as {@link HashSet}. Clients of a Spliterator that reports
|
||||
* {@code ORDERED} are expected to preserve ordering constraints in
|
||||
* non-commutative parallel computations.
|
||||
*/
|
||||
public static final int ORDERED = 0x00000010;
|
||||
|
||||
/**
|
||||
* Characteristic value signifying that, for each pair of
|
||||
* encountered elements {@code x, y}, {@code !x.equals(y)}. This
|
||||
* applies for example, to a Spliterator based on a {@link Set}.
|
||||
*/
|
||||
public static final int DISTINCT = 0x00000001;
|
||||
|
||||
/**
|
||||
* Characteristic value signifying that encounter order follows a defined
|
||||
* sort order. If so, method {@link #getComparator()} returns the associated
|
||||
* Comparator, or {@code null} if all elements are {@link Comparable} and
|
||||
* are sorted by their natural ordering.
|
||||
*
|
||||
* <p>A Spliterator that reports {@code SORTED} must also report
|
||||
* {@code ORDERED}.
|
||||
*
|
||||
* @apiNote The spliterators for {@code Collection} classes in the JDK that
|
||||
* implement {@link NavigableSet} or {@link SortedSet} report {@code SORTED}.
|
||||
*/
|
||||
public static final int SORTED = 0x00000004;
|
||||
|
||||
/**
|
||||
* Characteristic value signifying that the value returned from
|
||||
* {@code estimateSize()} prior to traversal or splitting represents a
|
||||
* finite size that, in the absence of structural source modification,
|
||||
* represents an exact count of the number of elements that would be
|
||||
* encountered by a complete traversal.
|
||||
*
|
||||
* @apiNote Most Spliterators for Collections, that cover all elements of a
|
||||
* {@code Collection} report this characteristic. Sub-spliterators, such as
|
||||
* those for {@link HashSet}, that cover a sub-set of elements and
|
||||
* approximate their reported size do not.
|
||||
*/
|
||||
public static final int SIZED = 0x00000040;
|
||||
|
||||
/**
|
||||
* Characteristic value signifying that the source guarantees that
|
||||
* encountered elements will not be {@code null}. (This applies,
|
||||
* for example, to most concurrent collections, queues, and maps.)
|
||||
*/
|
||||
public static final int NONNULL = 0x00000100;
|
||||
|
||||
/**
|
||||
* Characteristic value signifying that the element source cannot be
|
||||
* structurally modified; that is, elements cannot be added, replaced, or
|
||||
* removed, so such changes cannot occur during traversal. A Spliterator
|
||||
* that does not report {@code IMMUTABLE} or {@code CONCURRENT} is expected
|
||||
* to have a documented policy (for example throwing
|
||||
* {@link ConcurrentModificationException}) concerning structural
|
||||
* interference detected during traversal.
|
||||
*/
|
||||
public static final int IMMUTABLE = 0x00000400;
|
||||
|
||||
/**
|
||||
* Characteristic value signifying that the element source may be safely
|
||||
* concurrently modified (allowing additions, replacements, and/or removals)
|
||||
* by multiple threads without external synchronization. If so, the
|
||||
* Spliterator is expected to have a documented policy concerning the impact
|
||||
* of modifications during traversal.
|
||||
*
|
||||
* <p>A top-level Spliterator should not report both {@code CONCURRENT} and
|
||||
* {@code SIZED}, since the finite size, if known, may change if the source
|
||||
* is concurrently modified during traversal. Such a Spliterator is
|
||||
* inconsistent and no guarantees can be made about any computation using
|
||||
* that Spliterator. Sub-spliterators may report {@code SIZED} if the
|
||||
* sub-split size is known and additions or removals to the source are not
|
||||
* reflected when traversing.
|
||||
*
|
||||
* @apiNote Most concurrent collections maintain a consistency policy
|
||||
* guaranteeing accuracy with respect to elements present at the point of
|
||||
* Spliterator construction, but possibly not reflecting subsequent
|
||||
* additions or removals.
|
||||
*/
|
||||
public static final int CONCURRENT = 0x00001000;
|
||||
|
||||
/**
|
||||
* Characteristic value signifying that all Spliterators resulting from
|
||||
* {@code trySplit()} will be both {@link #SIZED} and {@link #SUBSIZED}.
|
||||
* (This means that all child Spliterators, whether direct or indirect, will
|
||||
* be {@code SIZED}.)
|
||||
*
|
||||
* <p>A Spliterator that does not report {@code SIZED} as required by
|
||||
* {@code SUBSIZED} is inconsistent and no guarantees can be made about any
|
||||
* computation using that Spliterator.
|
||||
*
|
||||
* @apiNote Some spliterators, such as the top-level spliterator for an
|
||||
* approximately balanced binary tree, will report {@code SIZED} but not
|
||||
* {@code SUBSIZED}, since it is common to know the size of the entire tree
|
||||
* but not the exact sizes of subtrees.
|
||||
*/
|
||||
public static final int SUBSIZED = 0x00004000;
|
||||
|
||||
/**
|
||||
* A Spliterator specialized for primitive values.
|
||||
*
|
||||
* @param <T> the type of elements returned by this Spliterator. The
|
||||
* type must be a wrapper type for a primitive type, such as {@code Integer}
|
||||
* for the primitive {@code int} type.
|
||||
* @param <T_CONS> the type of primitive consumer. The type must be a
|
||||
* primitive specialization of {@link java.util.function.Consumer} for
|
||||
* {@code T}, such as {@link java.util.function.IntConsumer} for
|
||||
* {@code Integer}.
|
||||
* @param <T_SPLITR> the type of primitive Spliterator. The type must be
|
||||
* a primitive specialization of Spliterator for {@code T}, such as
|
||||
* {@link Spliterator.OfInt} for {@code Integer}.
|
||||
*
|
||||
* @see Spliterator.OfInt
|
||||
* @see Spliterator.OfLong
|
||||
* @see Spliterator.OfDouble
|
||||
* @since 1.8
|
||||
*/
|
||||
public interface OfPrimitive<T, T_CONS, T_SPLITR extends Spliterator.OfPrimitive<T, T_CONS, T_SPLITR>>
|
||||
extends Spliterator<T> {
|
||||
@Override
|
||||
T_SPLITR trySplit();
|
||||
|
||||
/**
|
||||
* If a remaining element exists, performs the given action on it,
|
||||
* returning {@code true}; else returns {@code false}. If this
|
||||
* Spliterator is {@link #ORDERED} the action is performed on the
|
||||
* next element in encounter order. Exceptions thrown by the
|
||||
* action are relayed to the caller.
|
||||
*
|
||||
* @param action The action
|
||||
* @return {@code false} if no remaining elements existed
|
||||
* upon entry to this method, else {@code true}.
|
||||
* @throws NullPointerException if the specified action is null
|
||||
*/
|
||||
@SuppressWarnings("overloads")
|
||||
boolean tryAdvance(T_CONS action);
|
||||
|
||||
/**
|
||||
* Performs the given action for each remaining element, sequentially in
|
||||
* the current thread, until all elements have been processed or the
|
||||
* action throws an exception. If this Spliterator is {@link #ORDERED},
|
||||
* actions are performed in encounter order. Exceptions thrown by the
|
||||
* action are relayed to the caller.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation repeatedly invokes {@link #tryAdvance}
|
||||
* until it returns {@code false}. It should be overridden whenever
|
||||
* possible.
|
||||
*
|
||||
* @param action The action
|
||||
* @throws NullPointerException if the specified action is null
|
||||
*/
|
||||
@SuppressWarnings("overloads")
|
||||
default void forEachRemaining(T_CONS action) {
|
||||
do { } while (tryAdvance(action));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A Spliterator specialized for {@code int} values.
|
||||
* @since 1.8
|
||||
*/
|
||||
public interface OfInt extends OfPrimitive<Integer, IntConsumer, OfInt> {
|
||||
|
||||
@Override
|
||||
OfInt trySplit();
|
||||
|
||||
@Override
|
||||
boolean tryAdvance(IntConsumer action);
|
||||
|
||||
@Override
|
||||
default void forEachRemaining(IntConsumer action) {
|
||||
do { } while (tryAdvance(action));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @implSpec
|
||||
* If the action is an instance of {@code IntConsumer} then it is cast
|
||||
* to {@code IntConsumer} and passed to
|
||||
* {@link #tryAdvance(java.util.function.IntConsumer)}; otherwise
|
||||
* the action is adapted to an instance of {@code IntConsumer}, by
|
||||
* boxing the argument of {@code IntConsumer}, and then passed to
|
||||
* {@link #tryAdvance(java.util.function.IntConsumer)}.
|
||||
*/
|
||||
@Override
|
||||
default boolean tryAdvance(Consumer<? super Integer> action) {
|
||||
if (action instanceof IntConsumer) {
|
||||
return tryAdvance((IntConsumer) action);
|
||||
}
|
||||
else {
|
||||
if (Tripwire.ENABLED)
|
||||
Tripwire.trip(getClass(),
|
||||
"{0} calling Spliterator.OfInt.tryAdvance((IntConsumer) action::accept)");
|
||||
return tryAdvance((IntConsumer) action::accept);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @implSpec
|
||||
* If the action is an instance of {@code IntConsumer} then it is cast
|
||||
* to {@code IntConsumer} and passed to
|
||||
* {@link #forEachRemaining(java.util.function.IntConsumer)}; otherwise
|
||||
* the action is adapted to an instance of {@code IntConsumer}, by
|
||||
* boxing the argument of {@code IntConsumer}, and then passed to
|
||||
* {@link #forEachRemaining(java.util.function.IntConsumer)}.
|
||||
*/
|
||||
@Override
|
||||
default void forEachRemaining(Consumer<? super Integer> action) {
|
||||
if (action instanceof IntConsumer) {
|
||||
forEachRemaining((IntConsumer) action);
|
||||
}
|
||||
else {
|
||||
if (Tripwire.ENABLED)
|
||||
Tripwire.trip(getClass(),
|
||||
"{0} calling Spliterator.OfInt.forEachRemaining((IntConsumer) action::accept)");
|
||||
forEachRemaining((IntConsumer) action::accept);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A Spliterator specialized for {@code long} values.
|
||||
* @since 1.8
|
||||
*/
|
||||
public interface OfLong extends OfPrimitive<Long, LongConsumer, OfLong> {
|
||||
|
||||
@Override
|
||||
OfLong trySplit();
|
||||
|
||||
@Override
|
||||
boolean tryAdvance(LongConsumer action);
|
||||
|
||||
@Override
|
||||
default void forEachRemaining(LongConsumer action) {
|
||||
do { } while (tryAdvance(action));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @implSpec
|
||||
* If the action is an instance of {@code LongConsumer} then it is cast
|
||||
* to {@code LongConsumer} and passed to
|
||||
* {@link #tryAdvance(java.util.function.LongConsumer)}; otherwise
|
||||
* the action is adapted to an instance of {@code LongConsumer}, by
|
||||
* boxing the argument of {@code LongConsumer}, and then passed to
|
||||
* {@link #tryAdvance(java.util.function.LongConsumer)}.
|
||||
*/
|
||||
@Override
|
||||
default boolean tryAdvance(Consumer<? super Long> action) {
|
||||
if (action instanceof LongConsumer) {
|
||||
return tryAdvance((LongConsumer) action);
|
||||
}
|
||||
else {
|
||||
if (Tripwire.ENABLED)
|
||||
Tripwire.trip(getClass(),
|
||||
"{0} calling Spliterator.OfLong.tryAdvance((LongConsumer) action::accept)");
|
||||
return tryAdvance((LongConsumer) action::accept);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @implSpec
|
||||
* If the action is an instance of {@code LongConsumer} then it is cast
|
||||
* to {@code LongConsumer} and passed to
|
||||
* {@link #forEachRemaining(java.util.function.LongConsumer)}; otherwise
|
||||
* the action is adapted to an instance of {@code LongConsumer}, by
|
||||
* boxing the argument of {@code LongConsumer}, and then passed to
|
||||
* {@link #forEachRemaining(java.util.function.LongConsumer)}.
|
||||
*/
|
||||
@Override
|
||||
default void forEachRemaining(Consumer<? super Long> action) {
|
||||
if (action instanceof LongConsumer) {
|
||||
forEachRemaining((LongConsumer) action);
|
||||
}
|
||||
else {
|
||||
if (Tripwire.ENABLED)
|
||||
Tripwire.trip(getClass(),
|
||||
"{0} calling Spliterator.OfLong.forEachRemaining((LongConsumer) action::accept)");
|
||||
forEachRemaining((LongConsumer) action::accept);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A Spliterator specialized for {@code double} values.
|
||||
* @since 1.8
|
||||
*/
|
||||
public interface OfDouble extends OfPrimitive<Double, DoubleConsumer, OfDouble> {
|
||||
|
||||
@Override
|
||||
OfDouble trySplit();
|
||||
|
||||
@Override
|
||||
boolean tryAdvance(DoubleConsumer action);
|
||||
|
||||
@Override
|
||||
default void forEachRemaining(DoubleConsumer action) {
|
||||
do { } while (tryAdvance(action));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @implSpec
|
||||
* If the action is an instance of {@code DoubleConsumer} then it is
|
||||
* cast to {@code DoubleConsumer} and passed to
|
||||
* {@link #tryAdvance(java.util.function.DoubleConsumer)}; otherwise
|
||||
* the action is adapted to an instance of {@code DoubleConsumer}, by
|
||||
* boxing the argument of {@code DoubleConsumer}, and then passed to
|
||||
* {@link #tryAdvance(java.util.function.DoubleConsumer)}.
|
||||
*/
|
||||
@Override
|
||||
default boolean tryAdvance(Consumer<? super Double> action) {
|
||||
if (action instanceof DoubleConsumer) {
|
||||
return tryAdvance((DoubleConsumer) action);
|
||||
}
|
||||
else {
|
||||
if (Tripwire.ENABLED)
|
||||
Tripwire.trip(getClass(),
|
||||
"{0} calling Spliterator.OfDouble.tryAdvance((DoubleConsumer) action::accept)");
|
||||
return tryAdvance((DoubleConsumer) action::accept);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @implSpec
|
||||
* If the action is an instance of {@code DoubleConsumer} then it is
|
||||
* cast to {@code DoubleConsumer} and passed to
|
||||
* {@link #forEachRemaining(java.util.function.DoubleConsumer)};
|
||||
* otherwise the action is adapted to an instance of
|
||||
* {@code DoubleConsumer}, by boxing the argument of
|
||||
* {@code DoubleConsumer}, and then passed to
|
||||
* {@link #forEachRemaining(java.util.function.DoubleConsumer)}.
|
||||
*/
|
||||
@Override
|
||||
default void forEachRemaining(Consumer<? super Double> action) {
|
||||
if (action instanceof DoubleConsumer) {
|
||||
forEachRemaining((DoubleConsumer) action);
|
||||
}
|
||||
else {
|
||||
if (Tripwire.ENABLED)
|
||||
Tripwire.trip(getClass(),
|
||||
"{0} calling Spliterator.OfDouble.forEachRemaining((DoubleConsumer) action::accept)");
|
||||
forEachRemaining((DoubleConsumer) action::accept);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2124
jdkSrc/jdk8/java/util/Spliterators.java
Normal file
2124
jdkSrc/jdk8/java/util/Spliterators.java
Normal file
File diff suppressed because it is too large
Load Diff
991
jdkSrc/jdk8/java/util/SplittableRandom.java
Normal file
991
jdkSrc/jdk8/java/util/SplittableRandom.java
Normal file
@@ -0,0 +1,991 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.function.IntConsumer;
|
||||
import java.util.function.LongConsumer;
|
||||
import java.util.function.DoubleConsumer;
|
||||
import java.util.stream.StreamSupport;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.DoubleStream;
|
||||
|
||||
/**
|
||||
* A generator of uniform pseudorandom values applicable for use in
|
||||
* (among other contexts) isolated parallel computations that may
|
||||
* generate subtasks. Class {@code SplittableRandom} supports methods for
|
||||
* producing pseudorandom numbers of type {@code int}, {@code long},
|
||||
* and {@code double} with similar usages as for class
|
||||
* {@link java.util.Random} but differs in the following ways:
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li>Series of generated values pass the DieHarder suite testing
|
||||
* independence and uniformity properties of random number generators.
|
||||
* (Most recently validated with <a
|
||||
* href="http://www.phy.duke.edu/~rgb/General/dieharder.php"> version
|
||||
* 3.31.1</a>.) These tests validate only the methods for certain
|
||||
* types and ranges, but similar properties are expected to hold, at
|
||||
* least approximately, for others as well. The <em>period</em>
|
||||
* (length of any series of generated values before it repeats) is at
|
||||
* least 2<sup>64</sup>. </li>
|
||||
*
|
||||
* <li> Method {@link #split} constructs and returns a new
|
||||
* SplittableRandom instance that shares no mutable state with the
|
||||
* current instance. However, with very high probability, the
|
||||
* values collectively generated by the two objects have the same
|
||||
* statistical properties as if the same quantity of values were
|
||||
* generated by a single thread using a single {@code
|
||||
* SplittableRandom} object. </li>
|
||||
*
|
||||
* <li>Instances of SplittableRandom are <em>not</em> thread-safe.
|
||||
* They are designed to be split, not shared, across threads. For
|
||||
* example, a {@link java.util.concurrent.ForkJoinTask
|
||||
* fork/join-style} computation using random numbers might include a
|
||||
* construction of the form {@code new
|
||||
* Subtask(aSplittableRandom.split()).fork()}.
|
||||
*
|
||||
* <li>This class provides additional methods for generating random
|
||||
* streams, that employ the above techniques when used in {@code
|
||||
* stream.parallel()} mode.</li>
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* <p>Instances of {@code SplittableRandom} are not cryptographically
|
||||
* secure. Consider instead using {@link java.security.SecureRandom}
|
||||
* in security-sensitive applications. Additionally,
|
||||
* default-constructed instances do not use a cryptographically random
|
||||
* seed unless the {@linkplain System#getProperty system property}
|
||||
* {@code java.util.secureRandomSeed} is set to {@code true}.
|
||||
*
|
||||
* @author Guy Steele
|
||||
* @author Doug Lea
|
||||
* @since 1.8
|
||||
*/
|
||||
public final class SplittableRandom {
|
||||
|
||||
/*
|
||||
* Implementation Overview.
|
||||
*
|
||||
* This algorithm was inspired by the "DotMix" algorithm by
|
||||
* Leiserson, Schardl, and Sukha "Deterministic Parallel
|
||||
* Random-Number Generation for Dynamic-Multithreading Platforms",
|
||||
* PPoPP 2012, as well as those in "Parallel random numbers: as
|
||||
* easy as 1, 2, 3" by Salmon, Morae, Dror, and Shaw, SC 2011. It
|
||||
* differs mainly in simplifying and cheapening operations.
|
||||
*
|
||||
* The primary update step (method nextSeed()) is to add a
|
||||
* constant ("gamma") to the current (64 bit) seed, forming a
|
||||
* simple sequence. The seed and the gamma values for any two
|
||||
* SplittableRandom instances are highly likely to be different.
|
||||
*
|
||||
* Methods nextLong, nextInt, and derivatives do not return the
|
||||
* sequence (seed) values, but instead a hash-like bit-mix of
|
||||
* their bits, producing more independently distributed sequences.
|
||||
* For nextLong, the mix64 function is based on David Stafford's
|
||||
* (http://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html)
|
||||
* "Mix13" variant of the "64-bit finalizer" function in Austin
|
||||
* Appleby's MurmurHash3 algorithm (see
|
||||
* http://code.google.com/p/smhasher/wiki/MurmurHash3). The mix32
|
||||
* function is based on Stafford's Mix04 mix function, but returns
|
||||
* the upper 32 bits cast as int.
|
||||
*
|
||||
* The split operation uses the current generator to form the seed
|
||||
* and gamma for another SplittableRandom. To conservatively
|
||||
* avoid potential correlations between seed and value generation,
|
||||
* gamma selection (method mixGamma) uses different
|
||||
* (Murmurhash3's) mix constants. To avoid potential weaknesses
|
||||
* in bit-mixing transformations, we restrict gammas to odd values
|
||||
* with at least 24 0-1 or 1-0 bit transitions. Rather than
|
||||
* rejecting candidates with too few or too many bits set, method
|
||||
* mixGamma flips some bits (which has the effect of mapping at
|
||||
* most 4 to any given gamma value). This reduces the effective
|
||||
* set of 64bit odd gamma values by about 2%, and serves as an
|
||||
* automated screening for sequence constant selection that is
|
||||
* left as an empirical decision in some other hashing and crypto
|
||||
* algorithms.
|
||||
*
|
||||
* The resulting generator thus transforms a sequence in which
|
||||
* (typically) many bits change on each step, with an inexpensive
|
||||
* mixer with good (but less than cryptographically secure)
|
||||
* avalanching.
|
||||
*
|
||||
* The default (no-argument) constructor, in essence, invokes
|
||||
* split() for a common "defaultGen" SplittableRandom. Unlike
|
||||
* other cases, this split must be performed in a thread-safe
|
||||
* manner, so we use an AtomicLong to represent the seed rather
|
||||
* than use an explicit SplittableRandom. To bootstrap the
|
||||
* defaultGen, we start off using a seed based on current time
|
||||
* unless the java.util.secureRandomSeed property is set. This
|
||||
* serves as a slimmed-down (and insecure) variant of SecureRandom
|
||||
* that also avoids stalls that may occur when using /dev/random.
|
||||
*
|
||||
* It is a relatively simple matter to apply the basic design here
|
||||
* to use 128 bit seeds. However, emulating 128bit arithmetic and
|
||||
* carrying around twice the state add more overhead than appears
|
||||
* warranted for current usages.
|
||||
*
|
||||
* File organization: First the non-public methods that constitute
|
||||
* the main algorithm, then the main public methods, followed by
|
||||
* some custom spliterator classes needed for stream methods.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The golden ratio scaled to 64bits, used as the initial gamma
|
||||
* value for (unsplit) SplittableRandoms.
|
||||
*/
|
||||
private static final long GOLDEN_GAMMA = 0x9e3779b97f4a7c15L;
|
||||
|
||||
/**
|
||||
* The least non-zero value returned by nextDouble(). This value
|
||||
* is scaled by a random value of 53 bits to produce a result.
|
||||
*/
|
||||
private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0 / (1L << 53);
|
||||
|
||||
/**
|
||||
* The seed. Updated only via method nextSeed.
|
||||
*/
|
||||
private long seed;
|
||||
|
||||
/**
|
||||
* The step value.
|
||||
*/
|
||||
private final long gamma;
|
||||
|
||||
/**
|
||||
* Internal constructor used by all others except default constructor.
|
||||
*/
|
||||
private SplittableRandom(long seed, long gamma) {
|
||||
this.seed = seed;
|
||||
this.gamma = gamma;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes Stafford variant 13 of 64bit mix function.
|
||||
*/
|
||||
private static long mix64(long z) {
|
||||
z = (z ^ (z >>> 30)) * 0xbf58476d1ce4e5b9L;
|
||||
z = (z ^ (z >>> 27)) * 0x94d049bb133111ebL;
|
||||
return z ^ (z >>> 31);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the 32 high bits of Stafford variant 4 mix64 function as int.
|
||||
*/
|
||||
private static int mix32(long z) {
|
||||
z = (z ^ (z >>> 33)) * 0x62a9d9ed799705f5L;
|
||||
return (int)(((z ^ (z >>> 28)) * 0xcb24d0a5c88c35b3L) >>> 32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the gamma value to use for a new split instance.
|
||||
*/
|
||||
private static long mixGamma(long z) {
|
||||
z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL; // MurmurHash3 mix constants
|
||||
z = (z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L;
|
||||
z = (z ^ (z >>> 33)) | 1L; // force to be odd
|
||||
int n = Long.bitCount(z ^ (z >>> 1)); // ensure enough transitions
|
||||
return (n < 24) ? z ^ 0xaaaaaaaaaaaaaaaaL : z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds gamma to seed.
|
||||
*/
|
||||
private long nextSeed() {
|
||||
return seed += gamma;
|
||||
}
|
||||
|
||||
/**
|
||||
* The seed generator for default constructors.
|
||||
*/
|
||||
private static final AtomicLong defaultGen = new AtomicLong(initialSeed());
|
||||
|
||||
private static long initialSeed() {
|
||||
String pp = java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction(
|
||||
"java.util.secureRandomSeed"));
|
||||
if (pp != null && pp.equalsIgnoreCase("true")) {
|
||||
byte[] seedBytes = java.security.SecureRandom.getSeed(8);
|
||||
long s = (long)(seedBytes[0]) & 0xffL;
|
||||
for (int i = 1; i < 8; ++i)
|
||||
s = (s << 8) | ((long)(seedBytes[i]) & 0xffL);
|
||||
return s;
|
||||
}
|
||||
return (mix64(System.currentTimeMillis()) ^
|
||||
mix64(System.nanoTime()));
|
||||
}
|
||||
|
||||
// IllegalArgumentException messages
|
||||
static final String BadBound = "bound must be positive";
|
||||
static final String BadRange = "bound must be greater than origin";
|
||||
static final String BadSize = "size must be non-negative";
|
||||
|
||||
/*
|
||||
* Internal versions of nextX methods used by streams, as well as
|
||||
* the public nextX(origin, bound) methods. These exist mainly to
|
||||
* avoid the need for multiple versions of stream spliterators
|
||||
* across the different exported forms of streams.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The form of nextLong used by LongStream Spliterators. If
|
||||
* origin is greater than bound, acts as unbounded form of
|
||||
* nextLong, else as bounded form.
|
||||
*
|
||||
* @param origin the least value, unless greater than bound
|
||||
* @param bound the upper bound (exclusive), must not equal origin
|
||||
* @return a pseudorandom value
|
||||
*/
|
||||
final long internalNextLong(long origin, long bound) {
|
||||
/*
|
||||
* Four Cases:
|
||||
*
|
||||
* 1. If the arguments indicate unbounded form, act as
|
||||
* nextLong().
|
||||
*
|
||||
* 2. If the range is an exact power of two, apply the
|
||||
* associated bit mask.
|
||||
*
|
||||
* 3. If the range is positive, loop to avoid potential bias
|
||||
* when the implicit nextLong() bound (2<sup>64</sup>) is not
|
||||
* evenly divisible by the range. The loop rejects candidates
|
||||
* computed from otherwise over-represented values. The
|
||||
* expected number of iterations under an ideal generator
|
||||
* varies from 1 to 2, depending on the bound. The loop itself
|
||||
* takes an unlovable form. Because the first candidate is
|
||||
* already available, we need a break-in-the-middle
|
||||
* construction, which is concisely but cryptically performed
|
||||
* within the while-condition of a body-less for loop.
|
||||
*
|
||||
* 4. Otherwise, the range cannot be represented as a positive
|
||||
* long. The loop repeatedly generates unbounded longs until
|
||||
* obtaining a candidate meeting constraints (with an expected
|
||||
* number of iterations of less than two).
|
||||
*/
|
||||
|
||||
long r = mix64(nextSeed());
|
||||
if (origin < bound) {
|
||||
long n = bound - origin, m = n - 1;
|
||||
if ((n & m) == 0L) // power of two
|
||||
r = (r & m) + origin;
|
||||
else if (n > 0L) { // reject over-represented candidates
|
||||
for (long u = r >>> 1; // ensure nonnegative
|
||||
u + m - (r = u % n) < 0L; // rejection check
|
||||
u = mix64(nextSeed()) >>> 1) // retry
|
||||
;
|
||||
r += origin;
|
||||
}
|
||||
else { // range not representable as long
|
||||
while (r < origin || r >= bound)
|
||||
r = mix64(nextSeed());
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* The form of nextInt used by IntStream Spliterators.
|
||||
* Exactly the same as long version, except for types.
|
||||
*
|
||||
* @param origin the least value, unless greater than bound
|
||||
* @param bound the upper bound (exclusive), must not equal origin
|
||||
* @return a pseudorandom value
|
||||
*/
|
||||
final int internalNextInt(int origin, int bound) {
|
||||
int r = mix32(nextSeed());
|
||||
if (origin < bound) {
|
||||
int n = bound - origin, m = n - 1;
|
||||
if ((n & m) == 0)
|
||||
r = (r & m) + origin;
|
||||
else if (n > 0) {
|
||||
for (int u = r >>> 1;
|
||||
u + m - (r = u % n) < 0;
|
||||
u = mix32(nextSeed()) >>> 1)
|
||||
;
|
||||
r += origin;
|
||||
}
|
||||
else {
|
||||
while (r < origin || r >= bound)
|
||||
r = mix32(nextSeed());
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* The form of nextDouble used by DoubleStream Spliterators.
|
||||
*
|
||||
* @param origin the least value, unless greater than bound
|
||||
* @param bound the upper bound (exclusive), must not equal origin
|
||||
* @return a pseudorandom value
|
||||
*/
|
||||
final double internalNextDouble(double origin, double bound) {
|
||||
double r = (nextLong() >>> 11) * DOUBLE_UNIT;
|
||||
if (origin < bound) {
|
||||
r = r * (bound - origin) + origin;
|
||||
if (r >= bound) // correct for rounding
|
||||
r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/* ---------------- public methods ---------------- */
|
||||
|
||||
/**
|
||||
* Creates a new SplittableRandom instance using the specified
|
||||
* initial seed. SplittableRandom instances created with the same
|
||||
* seed in the same program generate identical sequences of values.
|
||||
*
|
||||
* @param seed the initial seed
|
||||
*/
|
||||
public SplittableRandom(long seed) {
|
||||
this(seed, GOLDEN_GAMMA);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new SplittableRandom instance that is likely to
|
||||
* generate sequences of values that are statistically independent
|
||||
* of those of any other instances in the current program; and
|
||||
* may, and typically does, vary across program invocations.
|
||||
*/
|
||||
public SplittableRandom() { // emulate defaultGen.split()
|
||||
long s = defaultGen.getAndAdd(2 * GOLDEN_GAMMA);
|
||||
this.seed = mix64(s);
|
||||
this.gamma = mixGamma(s + GOLDEN_GAMMA);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs and returns a new SplittableRandom instance that
|
||||
* shares no mutable state with this instance. However, with very
|
||||
* high probability, the set of values collectively generated by
|
||||
* the two objects has the same statistical properties as if the
|
||||
* same quantity of values were generated by a single thread using
|
||||
* a single SplittableRandom object. Either or both of the two
|
||||
* objects may be further split using the {@code split()} method,
|
||||
* and the same expected statistical properties apply to the
|
||||
* entire set of generators constructed by such recursive
|
||||
* splitting.
|
||||
*
|
||||
* @return the new SplittableRandom instance
|
||||
*/
|
||||
public SplittableRandom split() {
|
||||
return new SplittableRandom(nextLong(), mixGamma(nextSeed()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pseudorandom {@code int} value.
|
||||
*
|
||||
* @return a pseudorandom {@code int} value
|
||||
*/
|
||||
public int nextInt() {
|
||||
return mix32(nextSeed());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pseudorandom {@code int} value between zero (inclusive)
|
||||
* and the specified bound (exclusive).
|
||||
*
|
||||
* @param bound the upper bound (exclusive). Must be positive.
|
||||
* @return a pseudorandom {@code int} value between zero
|
||||
* (inclusive) and the bound (exclusive)
|
||||
* @throws IllegalArgumentException if {@code bound} is not positive
|
||||
*/
|
||||
public int nextInt(int bound) {
|
||||
if (bound <= 0)
|
||||
throw new IllegalArgumentException(BadBound);
|
||||
// Specialize internalNextInt for origin 0
|
||||
int r = mix32(nextSeed());
|
||||
int m = bound - 1;
|
||||
if ((bound & m) == 0) // power of two
|
||||
r &= m;
|
||||
else { // reject over-represented candidates
|
||||
for (int u = r >>> 1;
|
||||
u + m - (r = u % bound) < 0;
|
||||
u = mix32(nextSeed()) >>> 1)
|
||||
;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pseudorandom {@code int} value between the specified
|
||||
* origin (inclusive) and the specified bound (exclusive).
|
||||
*
|
||||
* @param origin the least value returned
|
||||
* @param bound the upper bound (exclusive)
|
||||
* @return a pseudorandom {@code int} value between the origin
|
||||
* (inclusive) and the bound (exclusive)
|
||||
* @throws IllegalArgumentException if {@code origin} is greater than
|
||||
* or equal to {@code bound}
|
||||
*/
|
||||
public int nextInt(int origin, int bound) {
|
||||
if (origin >= bound)
|
||||
throw new IllegalArgumentException(BadRange);
|
||||
return internalNextInt(origin, bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pseudorandom {@code long} value.
|
||||
*
|
||||
* @return a pseudorandom {@code long} value
|
||||
*/
|
||||
public long nextLong() {
|
||||
return mix64(nextSeed());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pseudorandom {@code long} value between zero (inclusive)
|
||||
* and the specified bound (exclusive).
|
||||
*
|
||||
* @param bound the upper bound (exclusive). Must be positive.
|
||||
* @return a pseudorandom {@code long} value between zero
|
||||
* (inclusive) and the bound (exclusive)
|
||||
* @throws IllegalArgumentException if {@code bound} is not positive
|
||||
*/
|
||||
public long nextLong(long bound) {
|
||||
if (bound <= 0)
|
||||
throw new IllegalArgumentException(BadBound);
|
||||
// Specialize internalNextLong for origin 0
|
||||
long r = mix64(nextSeed());
|
||||
long m = bound - 1;
|
||||
if ((bound & m) == 0L) // power of two
|
||||
r &= m;
|
||||
else { // reject over-represented candidates
|
||||
for (long u = r >>> 1;
|
||||
u + m - (r = u % bound) < 0L;
|
||||
u = mix64(nextSeed()) >>> 1)
|
||||
;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pseudorandom {@code long} value between the specified
|
||||
* origin (inclusive) and the specified bound (exclusive).
|
||||
*
|
||||
* @param origin the least value returned
|
||||
* @param bound the upper bound (exclusive)
|
||||
* @return a pseudorandom {@code long} value between the origin
|
||||
* (inclusive) and the bound (exclusive)
|
||||
* @throws IllegalArgumentException if {@code origin} is greater than
|
||||
* or equal to {@code bound}
|
||||
*/
|
||||
public long nextLong(long origin, long bound) {
|
||||
if (origin >= bound)
|
||||
throw new IllegalArgumentException(BadRange);
|
||||
return internalNextLong(origin, bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pseudorandom {@code double} value between zero
|
||||
* (inclusive) and one (exclusive).
|
||||
*
|
||||
* @return a pseudorandom {@code double} value between zero
|
||||
* (inclusive) and one (exclusive)
|
||||
*/
|
||||
public double nextDouble() {
|
||||
return (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pseudorandom {@code double} value between 0.0
|
||||
* (inclusive) and the specified bound (exclusive).
|
||||
*
|
||||
* @param bound the upper bound (exclusive). Must be positive.
|
||||
* @return a pseudorandom {@code double} value between zero
|
||||
* (inclusive) and the bound (exclusive)
|
||||
* @throws IllegalArgumentException if {@code bound} is not positive
|
||||
*/
|
||||
public double nextDouble(double bound) {
|
||||
if (!(bound > 0.0))
|
||||
throw new IllegalArgumentException(BadBound);
|
||||
double result = (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT * bound;
|
||||
return (result < bound) ? result : // correct for rounding
|
||||
Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pseudorandom {@code double} value between the specified
|
||||
* origin (inclusive) and bound (exclusive).
|
||||
*
|
||||
* @param origin the least value returned
|
||||
* @param bound the upper bound (exclusive)
|
||||
* @return a pseudorandom {@code double} value between the origin
|
||||
* (inclusive) and the bound (exclusive)
|
||||
* @throws IllegalArgumentException if {@code origin} is greater than
|
||||
* or equal to {@code bound}
|
||||
*/
|
||||
public double nextDouble(double origin, double bound) {
|
||||
if (!(origin < bound))
|
||||
throw new IllegalArgumentException(BadRange);
|
||||
return internalNextDouble(origin, bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pseudorandom {@code boolean} value.
|
||||
*
|
||||
* @return a pseudorandom {@code boolean} value
|
||||
*/
|
||||
public boolean nextBoolean() {
|
||||
return mix32(nextSeed()) < 0;
|
||||
}
|
||||
|
||||
// stream methods, coded in a way intended to better isolate for
|
||||
// maintenance purposes the small differences across forms.
|
||||
|
||||
/**
|
||||
* Returns a stream producing the given {@code streamSize} number
|
||||
* of pseudorandom {@code int} values from this generator and/or
|
||||
* one split from it.
|
||||
*
|
||||
* @param streamSize the number of values to generate
|
||||
* @return a stream of pseudorandom {@code int} values
|
||||
* @throws IllegalArgumentException if {@code streamSize} is
|
||||
* less than zero
|
||||
*/
|
||||
public IntStream ints(long streamSize) {
|
||||
if (streamSize < 0L)
|
||||
throw new IllegalArgumentException(BadSize);
|
||||
return StreamSupport.intStream
|
||||
(new RandomIntsSpliterator
|
||||
(this, 0L, streamSize, Integer.MAX_VALUE, 0),
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an effectively unlimited stream of pseudorandom {@code int}
|
||||
* values from this generator and/or one split from it.
|
||||
*
|
||||
* @implNote This method is implemented to be equivalent to {@code
|
||||
* ints(Long.MAX_VALUE)}.
|
||||
*
|
||||
* @return a stream of pseudorandom {@code int} values
|
||||
*/
|
||||
public IntStream ints() {
|
||||
return StreamSupport.intStream
|
||||
(new RandomIntsSpliterator
|
||||
(this, 0L, Long.MAX_VALUE, Integer.MAX_VALUE, 0),
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a stream producing the given {@code streamSize} number
|
||||
* of pseudorandom {@code int} values from this generator and/or one split
|
||||
* from it; each value conforms to the given origin (inclusive) and bound
|
||||
* (exclusive).
|
||||
*
|
||||
* @param streamSize the number of values to generate
|
||||
* @param randomNumberOrigin the origin (inclusive) of each random value
|
||||
* @param randomNumberBound the bound (exclusive) of each random value
|
||||
* @return a stream of pseudorandom {@code int} values,
|
||||
* each with the given origin (inclusive) and bound (exclusive)
|
||||
* @throws IllegalArgumentException if {@code streamSize} is
|
||||
* less than zero, or {@code randomNumberOrigin}
|
||||
* is greater than or equal to {@code randomNumberBound}
|
||||
*/
|
||||
public IntStream ints(long streamSize, int randomNumberOrigin,
|
||||
int randomNumberBound) {
|
||||
if (streamSize < 0L)
|
||||
throw new IllegalArgumentException(BadSize);
|
||||
if (randomNumberOrigin >= randomNumberBound)
|
||||
throw new IllegalArgumentException(BadRange);
|
||||
return StreamSupport.intStream
|
||||
(new RandomIntsSpliterator
|
||||
(this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an effectively unlimited stream of pseudorandom {@code
|
||||
* int} values from this generator and/or one split from it; each value
|
||||
* conforms to the given origin (inclusive) and bound (exclusive).
|
||||
*
|
||||
* @implNote This method is implemented to be equivalent to {@code
|
||||
* ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
|
||||
*
|
||||
* @param randomNumberOrigin the origin (inclusive) of each random value
|
||||
* @param randomNumberBound the bound (exclusive) of each random value
|
||||
* @return a stream of pseudorandom {@code int} values,
|
||||
* each with the given origin (inclusive) and bound (exclusive)
|
||||
* @throws IllegalArgumentException if {@code randomNumberOrigin}
|
||||
* is greater than or equal to {@code randomNumberBound}
|
||||
*/
|
||||
public IntStream ints(int randomNumberOrigin, int randomNumberBound) {
|
||||
if (randomNumberOrigin >= randomNumberBound)
|
||||
throw new IllegalArgumentException(BadRange);
|
||||
return StreamSupport.intStream
|
||||
(new RandomIntsSpliterator
|
||||
(this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a stream producing the given {@code streamSize} number
|
||||
* of pseudorandom {@code long} values from this generator and/or
|
||||
* one split from it.
|
||||
*
|
||||
* @param streamSize the number of values to generate
|
||||
* @return a stream of pseudorandom {@code long} values
|
||||
* @throws IllegalArgumentException if {@code streamSize} is
|
||||
* less than zero
|
||||
*/
|
||||
public LongStream longs(long streamSize) {
|
||||
if (streamSize < 0L)
|
||||
throw new IllegalArgumentException(BadSize);
|
||||
return StreamSupport.longStream
|
||||
(new RandomLongsSpliterator
|
||||
(this, 0L, streamSize, Long.MAX_VALUE, 0L),
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an effectively unlimited stream of pseudorandom {@code
|
||||
* long} values from this generator and/or one split from it.
|
||||
*
|
||||
* @implNote This method is implemented to be equivalent to {@code
|
||||
* longs(Long.MAX_VALUE)}.
|
||||
*
|
||||
* @return a stream of pseudorandom {@code long} values
|
||||
*/
|
||||
public LongStream longs() {
|
||||
return StreamSupport.longStream
|
||||
(new RandomLongsSpliterator
|
||||
(this, 0L, Long.MAX_VALUE, Long.MAX_VALUE, 0L),
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a stream producing the given {@code streamSize} number of
|
||||
* pseudorandom {@code long} values from this generator and/or one split
|
||||
* from it; each value conforms to the given origin (inclusive) and bound
|
||||
* (exclusive).
|
||||
*
|
||||
* @param streamSize the number of values to generate
|
||||
* @param randomNumberOrigin the origin (inclusive) of each random value
|
||||
* @param randomNumberBound the bound (exclusive) of each random value
|
||||
* @return a stream of pseudorandom {@code long} values,
|
||||
* each with the given origin (inclusive) and bound (exclusive)
|
||||
* @throws IllegalArgumentException if {@code streamSize} is
|
||||
* less than zero, or {@code randomNumberOrigin}
|
||||
* is greater than or equal to {@code randomNumberBound}
|
||||
*/
|
||||
public LongStream longs(long streamSize, long randomNumberOrigin,
|
||||
long randomNumberBound) {
|
||||
if (streamSize < 0L)
|
||||
throw new IllegalArgumentException(BadSize);
|
||||
if (randomNumberOrigin >= randomNumberBound)
|
||||
throw new IllegalArgumentException(BadRange);
|
||||
return StreamSupport.longStream
|
||||
(new RandomLongsSpliterator
|
||||
(this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an effectively unlimited stream of pseudorandom {@code
|
||||
* long} values from this generator and/or one split from it; each value
|
||||
* conforms to the given origin (inclusive) and bound (exclusive).
|
||||
*
|
||||
* @implNote This method is implemented to be equivalent to {@code
|
||||
* longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
|
||||
*
|
||||
* @param randomNumberOrigin the origin (inclusive) of each random value
|
||||
* @param randomNumberBound the bound (exclusive) of each random value
|
||||
* @return a stream of pseudorandom {@code long} values,
|
||||
* each with the given origin (inclusive) and bound (exclusive)
|
||||
* @throws IllegalArgumentException if {@code randomNumberOrigin}
|
||||
* is greater than or equal to {@code randomNumberBound}
|
||||
*/
|
||||
public LongStream longs(long randomNumberOrigin, long randomNumberBound) {
|
||||
if (randomNumberOrigin >= randomNumberBound)
|
||||
throw new IllegalArgumentException(BadRange);
|
||||
return StreamSupport.longStream
|
||||
(new RandomLongsSpliterator
|
||||
(this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a stream producing the given {@code streamSize} number of
|
||||
* pseudorandom {@code double} values from this generator and/or one split
|
||||
* from it; each value is between zero (inclusive) and one (exclusive).
|
||||
*
|
||||
* @param streamSize the number of values to generate
|
||||
* @return a stream of {@code double} values
|
||||
* @throws IllegalArgumentException if {@code streamSize} is
|
||||
* less than zero
|
||||
*/
|
||||
public DoubleStream doubles(long streamSize) {
|
||||
if (streamSize < 0L)
|
||||
throw new IllegalArgumentException(BadSize);
|
||||
return StreamSupport.doubleStream
|
||||
(new RandomDoublesSpliterator
|
||||
(this, 0L, streamSize, Double.MAX_VALUE, 0.0),
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an effectively unlimited stream of pseudorandom {@code
|
||||
* double} values from this generator and/or one split from it; each value
|
||||
* is between zero (inclusive) and one (exclusive).
|
||||
*
|
||||
* @implNote This method is implemented to be equivalent to {@code
|
||||
* doubles(Long.MAX_VALUE)}.
|
||||
*
|
||||
* @return a stream of pseudorandom {@code double} values
|
||||
*/
|
||||
public DoubleStream doubles() {
|
||||
return StreamSupport.doubleStream
|
||||
(new RandomDoublesSpliterator
|
||||
(this, 0L, Long.MAX_VALUE, Double.MAX_VALUE, 0.0),
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a stream producing the given {@code streamSize} number of
|
||||
* pseudorandom {@code double} values from this generator and/or one split
|
||||
* from it; each value conforms to the given origin (inclusive) and bound
|
||||
* (exclusive).
|
||||
*
|
||||
* @param streamSize the number of values to generate
|
||||
* @param randomNumberOrigin the origin (inclusive) of each random value
|
||||
* @param randomNumberBound the bound (exclusive) of each random value
|
||||
* @return a stream of pseudorandom {@code double} values,
|
||||
* each with the given origin (inclusive) and bound (exclusive)
|
||||
* @throws IllegalArgumentException if {@code streamSize} is
|
||||
* less than zero
|
||||
* @throws IllegalArgumentException if {@code randomNumberOrigin}
|
||||
* is greater than or equal to {@code randomNumberBound}
|
||||
*/
|
||||
public DoubleStream doubles(long streamSize, double randomNumberOrigin,
|
||||
double randomNumberBound) {
|
||||
if (streamSize < 0L)
|
||||
throw new IllegalArgumentException(BadSize);
|
||||
if (!(randomNumberOrigin < randomNumberBound))
|
||||
throw new IllegalArgumentException(BadRange);
|
||||
return StreamSupport.doubleStream
|
||||
(new RandomDoublesSpliterator
|
||||
(this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an effectively unlimited stream of pseudorandom {@code
|
||||
* double} values from this generator and/or one split from it; each value
|
||||
* conforms to the given origin (inclusive) and bound (exclusive).
|
||||
*
|
||||
* @implNote This method is implemented to be equivalent to {@code
|
||||
* doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
|
||||
*
|
||||
* @param randomNumberOrigin the origin (inclusive) of each random value
|
||||
* @param randomNumberBound the bound (exclusive) of each random value
|
||||
* @return a stream of pseudorandom {@code double} values,
|
||||
* each with the given origin (inclusive) and bound (exclusive)
|
||||
* @throws IllegalArgumentException if {@code randomNumberOrigin}
|
||||
* is greater than or equal to {@code randomNumberBound}
|
||||
*/
|
||||
public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
|
||||
if (!(randomNumberOrigin < randomNumberBound))
|
||||
throw new IllegalArgumentException(BadRange);
|
||||
return StreamSupport.doubleStream
|
||||
(new RandomDoublesSpliterator
|
||||
(this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Spliterator for int streams. We multiplex the four int
|
||||
* versions into one class by treating a bound less than origin as
|
||||
* unbounded, and also by treating "infinite" as equivalent to
|
||||
* Long.MAX_VALUE. For splits, it uses the standard divide-by-two
|
||||
* approach. The long and double versions of this class are
|
||||
* identical except for types.
|
||||
*/
|
||||
static final class RandomIntsSpliterator implements Spliterator.OfInt {
|
||||
final SplittableRandom rng;
|
||||
long index;
|
||||
final long fence;
|
||||
final int origin;
|
||||
final int bound;
|
||||
RandomIntsSpliterator(SplittableRandom rng, long index, long fence,
|
||||
int origin, int bound) {
|
||||
this.rng = rng; this.index = index; this.fence = fence;
|
||||
this.origin = origin; this.bound = bound;
|
||||
}
|
||||
|
||||
public RandomIntsSpliterator trySplit() {
|
||||
long i = index, m = (i + fence) >>> 1;
|
||||
return (m <= i) ? null :
|
||||
new RandomIntsSpliterator(rng.split(), i, index = m, origin, bound);
|
||||
}
|
||||
|
||||
public long estimateSize() {
|
||||
return fence - index;
|
||||
}
|
||||
|
||||
public int characteristics() {
|
||||
return (Spliterator.SIZED | Spliterator.SUBSIZED |
|
||||
Spliterator.NONNULL | Spliterator.IMMUTABLE);
|
||||
}
|
||||
|
||||
public boolean tryAdvance(IntConsumer consumer) {
|
||||
if (consumer == null) throw new NullPointerException();
|
||||
long i = index, f = fence;
|
||||
if (i < f) {
|
||||
consumer.accept(rng.internalNextInt(origin, bound));
|
||||
index = i + 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void forEachRemaining(IntConsumer consumer) {
|
||||
if (consumer == null) throw new NullPointerException();
|
||||
long i = index, f = fence;
|
||||
if (i < f) {
|
||||
index = f;
|
||||
SplittableRandom r = rng;
|
||||
int o = origin, b = bound;
|
||||
do {
|
||||
consumer.accept(r.internalNextInt(o, b));
|
||||
} while (++i < f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Spliterator for long streams.
|
||||
*/
|
||||
static final class RandomLongsSpliterator implements Spliterator.OfLong {
|
||||
final SplittableRandom rng;
|
||||
long index;
|
||||
final long fence;
|
||||
final long origin;
|
||||
final long bound;
|
||||
RandomLongsSpliterator(SplittableRandom rng, long index, long fence,
|
||||
long origin, long bound) {
|
||||
this.rng = rng; this.index = index; this.fence = fence;
|
||||
this.origin = origin; this.bound = bound;
|
||||
}
|
||||
|
||||
public RandomLongsSpliterator trySplit() {
|
||||
long i = index, m = (i + fence) >>> 1;
|
||||
return (m <= i) ? null :
|
||||
new RandomLongsSpliterator(rng.split(), i, index = m, origin, bound);
|
||||
}
|
||||
|
||||
public long estimateSize() {
|
||||
return fence - index;
|
||||
}
|
||||
|
||||
public int characteristics() {
|
||||
return (Spliterator.SIZED | Spliterator.SUBSIZED |
|
||||
Spliterator.NONNULL | Spliterator.IMMUTABLE);
|
||||
}
|
||||
|
||||
public boolean tryAdvance(LongConsumer consumer) {
|
||||
if (consumer == null) throw new NullPointerException();
|
||||
long i = index, f = fence;
|
||||
if (i < f) {
|
||||
consumer.accept(rng.internalNextLong(origin, bound));
|
||||
index = i + 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void forEachRemaining(LongConsumer consumer) {
|
||||
if (consumer == null) throw new NullPointerException();
|
||||
long i = index, f = fence;
|
||||
if (i < f) {
|
||||
index = f;
|
||||
SplittableRandom r = rng;
|
||||
long o = origin, b = bound;
|
||||
do {
|
||||
consumer.accept(r.internalNextLong(o, b));
|
||||
} while (++i < f);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Spliterator for double streams.
|
||||
*/
|
||||
static final class RandomDoublesSpliterator implements Spliterator.OfDouble {
|
||||
final SplittableRandom rng;
|
||||
long index;
|
||||
final long fence;
|
||||
final double origin;
|
||||
final double bound;
|
||||
RandomDoublesSpliterator(SplittableRandom rng, long index, long fence,
|
||||
double origin, double bound) {
|
||||
this.rng = rng; this.index = index; this.fence = fence;
|
||||
this.origin = origin; this.bound = bound;
|
||||
}
|
||||
|
||||
public RandomDoublesSpliterator trySplit() {
|
||||
long i = index, m = (i + fence) >>> 1;
|
||||
return (m <= i) ? null :
|
||||
new RandomDoublesSpliterator(rng.split(), i, index = m, origin, bound);
|
||||
}
|
||||
|
||||
public long estimateSize() {
|
||||
return fence - index;
|
||||
}
|
||||
|
||||
public int characteristics() {
|
||||
return (Spliterator.SIZED | Spliterator.SUBSIZED |
|
||||
Spliterator.NONNULL | Spliterator.IMMUTABLE);
|
||||
}
|
||||
|
||||
public boolean tryAdvance(DoubleConsumer consumer) {
|
||||
if (consumer == null) throw new NullPointerException();
|
||||
long i = index, f = fence;
|
||||
if (i < f) {
|
||||
consumer.accept(rng.internalNextDouble(origin, bound));
|
||||
index = i + 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void forEachRemaining(DoubleConsumer consumer) {
|
||||
if (consumer == null) throw new NullPointerException();
|
||||
long i = index, f = fence;
|
||||
if (i < f) {
|
||||
index = f;
|
||||
SplittableRandom r = rng;
|
||||
double o = origin, b = bound;
|
||||
do {
|
||||
consumer.accept(r.internalNextDouble(o, b));
|
||||
} while (++i < f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user