# HG changeset patch
# User Jaroslav Tulach
# Date 1358976825 -3600
# Node ID df92e9608039a402a083a448d0935bcaf566e44f
# Parent 9c5f89ea4c1ce09e4076d84dab375157441bf5db# Parent 5be31d9fa455fef3404bae4549bcbfec986ce951
Merging transitive closure of ServiceLoader into the emul branch
diff -r 9c5f89ea4c1c -r df92e9608039 emul/compact/src/main/java/java/io/BufferedReader.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/emul/compact/src/main/java/java/io/BufferedReader.java Wed Jan 23 22:33:45 2013 +0100
@@ -0,0 +1,522 @@
+/*
+ * Copyright (c) 1996, 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.io;
+
+
+/**
+ * Reads text from a character-input stream, buffering characters so as to
+ * provide for the efficient reading of characters, arrays, and lines.
+ *
+ *
The buffer size may be specified, or the default size may be used. The
+ * default is large enough for most purposes.
+ *
+ *
In general, each read request made of a Reader causes a corresponding
+ * read request to be made of the underlying character or byte stream. It is
+ * therefore advisable to wrap a BufferedReader around any Reader whose read()
+ * operations may be costly, such as FileReaders and InputStreamReaders. For
+ * example,
+ *
+ *
+ * BufferedReader in
+ * = new BufferedReader(new FileReader("foo.in"));
+ *
+ *
+ * will buffer the input from the specified file. Without buffering, each
+ * invocation of read() or readLine() could cause bytes to be read from the
+ * file, converted into characters, and then returned, which can be very
+ * inefficient.
+ *
+ *
Programs that use DataInputStreams for textual input can be localized by
+ * replacing each DataInputStream with an appropriate BufferedReader.
+ *
+ * @see FileReader
+ * @see InputStreamReader
+ * @see java.nio.file.Files#newBufferedReader
+ *
+ * @author Mark Reinhold
+ * @since JDK1.1
+ */
+
+public class BufferedReader extends Reader {
+
+ private Reader in;
+
+ private char cb[];
+ private int nChars, nextChar;
+
+ private static final int INVALIDATED = -2;
+ private static final int UNMARKED = -1;
+ private int markedChar = UNMARKED;
+ private int readAheadLimit = 0; /* Valid only when markedChar > 0 */
+
+ /** If the next character is a line feed, skip it */
+ private boolean skipLF = false;
+
+ /** The skipLF flag when the mark was set */
+ private boolean markedSkipLF = false;
+
+ private static int defaultCharBufferSize = 8192;
+ private static int defaultExpectedLineLength = 80;
+
+ /**
+ * Creates a buffering character-input stream that uses an input buffer of
+ * the specified size.
+ *
+ * @param in A Reader
+ * @param sz Input-buffer size
+ *
+ * @exception IllegalArgumentException If sz is <= 0
+ */
+ public BufferedReader(Reader in, int sz) {
+ super(in);
+ if (sz <= 0)
+ throw new IllegalArgumentException("Buffer size <= 0");
+ this.in = in;
+ cb = new char[sz];
+ nextChar = nChars = 0;
+ }
+
+ /**
+ * Creates a buffering character-input stream that uses a default-sized
+ * input buffer.
+ *
+ * @param in A Reader
+ */
+ public BufferedReader(Reader in) {
+ this(in, defaultCharBufferSize);
+ }
+
+ /** Checks to make sure that the stream has not been closed */
+ private void ensureOpen() throws IOException {
+ if (in == null)
+ throw new IOException("Stream closed");
+ }
+
+ /**
+ * Fills the input buffer, taking the mark into account if it is valid.
+ */
+ private void fill() throws IOException {
+ int dst;
+ if (markedChar <= UNMARKED) {
+ /* No mark */
+ dst = 0;
+ } else {
+ /* Marked */
+ int delta = nextChar - markedChar;
+ if (delta >= readAheadLimit) {
+ /* Gone past read-ahead limit: Invalidate mark */
+ markedChar = INVALIDATED;
+ readAheadLimit = 0;
+ dst = 0;
+ } else {
+ if (readAheadLimit <= cb.length) {
+ /* Shuffle in the current buffer */
+ System.arraycopy(cb, markedChar, cb, 0, delta);
+ markedChar = 0;
+ dst = delta;
+ } else {
+ /* Reallocate buffer to accommodate read-ahead limit */
+ char ncb[] = new char[readAheadLimit];
+ System.arraycopy(cb, markedChar, ncb, 0, delta);
+ cb = ncb;
+ markedChar = 0;
+ dst = delta;
+ }
+ nextChar = nChars = delta;
+ }
+ }
+
+ int n;
+ do {
+ n = in.read(cb, dst, cb.length - dst);
+ } while (n == 0);
+ if (n > 0) {
+ nChars = dst + n;
+ nextChar = dst;
+ }
+ }
+
+ /**
+ * Reads a single character.
+ *
+ * @return The character read, as an integer in the range
+ * 0 to 65535 (0x00-0xffff), or -1 if the
+ * end of the stream has been reached
+ * @exception IOException If an I/O error occurs
+ */
+ public int read() throws IOException {
+ synchronized (lock) {
+ ensureOpen();
+ for (;;) {
+ if (nextChar >= nChars) {
+ fill();
+ if (nextChar >= nChars)
+ return -1;
+ }
+ if (skipLF) {
+ skipLF = false;
+ if (cb[nextChar] == '\n') {
+ nextChar++;
+ continue;
+ }
+ }
+ return cb[nextChar++];
+ }
+ }
+ }
+
+ /**
+ * Reads characters into a portion of an array, reading from the underlying
+ * stream if necessary.
+ */
+ private int read1(char[] cbuf, int off, int len) throws IOException {
+ if (nextChar >= nChars) {
+ /* If the requested length is at least as large as the buffer, and
+ if there is no mark/reset activity, and if line feeds are not
+ being skipped, do not bother to copy the characters into the
+ local buffer. In this way buffered streams will cascade
+ harmlessly. */
+ if (len >= cb.length && markedChar <= UNMARKED && !skipLF) {
+ return in.read(cbuf, off, len);
+ }
+ fill();
+ }
+ if (nextChar >= nChars) return -1;
+ if (skipLF) {
+ skipLF = false;
+ if (cb[nextChar] == '\n') {
+ nextChar++;
+ if (nextChar >= nChars)
+ fill();
+ if (nextChar >= nChars)
+ return -1;
+ }
+ }
+ int n = Math.min(len, nChars - nextChar);
+ System.arraycopy(cb, nextChar, cbuf, off, n);
+ nextChar += n;
+ return n;
+ }
+
+ /**
+ * Reads characters into a portion of an array.
+ *
+ *
This method implements the general contract of the corresponding
+ * {@link Reader#read(char[], int, int) read} method of the
+ * {@link Reader} class. As an additional convenience, it
+ * attempts to read as many characters as possible by repeatedly invoking
+ * the read method of the underlying stream. This iterated
+ * read continues until one of the following conditions becomes
+ * true:
+ *
+ *
The specified number of characters have been read,
+ *
+ *
The read method of the underlying stream returns
+ * -1, indicating end-of-file, or
+ *
+ *
The ready method of the underlying stream
+ * returns false, indicating that further input requests
+ * would block.
+ *
+ *
If the first read on the underlying stream returns
+ * -1 to indicate end-of-file then this method returns
+ * -1. Otherwise this method returns the number of characters
+ * actually read.
+ *
+ *
Subclasses of this class are encouraged, but not required, to
+ * attempt to read as many characters as possible in the same fashion.
+ *
+ *
Ordinarily this method takes characters from this stream's character
+ * buffer, filling it from the underlying stream as necessary. If,
+ * however, the buffer is empty, the mark is not valid, and the requested
+ * length is at least as large as the buffer, then this method will read
+ * characters directly from the underlying stream into the given array.
+ * Thus redundant BufferedReaders will not copy data
+ * unnecessarily.
+ *
+ * @param cbuf Destination buffer
+ * @param off Offset at which to start storing characters
+ * @param len Maximum number of characters to read
+ *
+ * @return The number of characters read, or -1 if the end of the
+ * stream has been reached
+ *
+ * @exception IOException If an I/O error occurs
+ */
+ public int read(char cbuf[], int off, int len) throws IOException {
+ synchronized (lock) {
+ ensureOpen();
+ if ((off < 0) || (off > cbuf.length) || (len < 0) ||
+ ((off + len) > cbuf.length) || ((off + len) < 0)) {
+ throw new IndexOutOfBoundsException();
+ } else if (len == 0) {
+ return 0;
+ }
+
+ int n = read1(cbuf, off, len);
+ if (n <= 0) return n;
+ while ((n < len) && in.ready()) {
+ int n1 = read1(cbuf, off + n, len - n);
+ if (n1 <= 0) break;
+ n += n1;
+ }
+ return n;
+ }
+ }
+
+ /**
+ * Reads a line of text. A line is considered to be terminated by any one
+ * of a line feed ('\n'), a carriage return ('\r'), or a carriage return
+ * followed immediately by a linefeed.
+ *
+ * @param ignoreLF If true, the next '\n' will be skipped
+ *
+ * @return A String containing the contents of the line, not including
+ * any line-termination characters, or null if the end of the
+ * stream has been reached
+ *
+ * @see java.io.LineNumberReader#readLine()
+ *
+ * @exception IOException If an I/O error occurs
+ */
+ String readLine(boolean ignoreLF) throws IOException {
+ StringBuffer s = null;
+ int startChar;
+
+ synchronized (lock) {
+ ensureOpen();
+ boolean omitLF = ignoreLF || skipLF;
+
+ bufferLoop:
+ for (;;) {
+
+ if (nextChar >= nChars)
+ fill();
+ if (nextChar >= nChars) { /* EOF */
+ if (s != null && s.length() > 0)
+ return s.toString();
+ else
+ return null;
+ }
+ boolean eol = false;
+ char c = 0;
+ int i;
+
+ /* Skip a leftover '\n', if necessary */
+ if (omitLF && (cb[nextChar] == '\n'))
+ nextChar++;
+ skipLF = false;
+ omitLF = false;
+
+ charLoop:
+ for (i = nextChar; i < nChars; i++) {
+ c = cb[i];
+ if ((c == '\n') || (c == '\r')) {
+ eol = true;
+ break charLoop;
+ }
+ }
+
+ startChar = nextChar;
+ nextChar = i;
+
+ if (eol) {
+ String str;
+ if (s == null) {
+ str = new String(cb, startChar, i - startChar);
+ } else {
+ s.append(cb, startChar, i - startChar);
+ str = s.toString();
+ }
+ nextChar++;
+ if (c == '\r') {
+ skipLF = true;
+ }
+ return str;
+ }
+
+ if (s == null)
+ s = new StringBuffer(defaultExpectedLineLength);
+ s.append(cb, startChar, i - startChar);
+ }
+ }
+ }
+
+ /**
+ * Reads a line of text. A line is considered to be terminated by any one
+ * of a line feed ('\n'), a carriage return ('\r'), or a carriage return
+ * followed immediately by a linefeed.
+ *
+ * @return A String containing the contents of the line, not including
+ * any line-termination characters, or null if the end of the
+ * stream has been reached
+ *
+ * @exception IOException If an I/O error occurs
+ *
+ * @see java.nio.file.Files#readAllLines
+ */
+ public String readLine() throws IOException {
+ return readLine(false);
+ }
+
+ /**
+ * Skips characters.
+ *
+ * @param n The number of characters to skip
+ *
+ * @return The number of characters actually skipped
+ *
+ * @exception IllegalArgumentException If n is negative.
+ * @exception IOException If an I/O error occurs
+ */
+ public long skip(long n) throws IOException {
+ if (n < 0L) {
+ throw new IllegalArgumentException("skip value is negative");
+ }
+ synchronized (lock) {
+ ensureOpen();
+ long r = n;
+ while (r > 0) {
+ if (nextChar >= nChars)
+ fill();
+ if (nextChar >= nChars) /* EOF */
+ break;
+ if (skipLF) {
+ skipLF = false;
+ if (cb[nextChar] == '\n') {
+ nextChar++;
+ }
+ }
+ long d = nChars - nextChar;
+ if (r <= d) {
+ nextChar += r;
+ r = 0;
+ break;
+ }
+ else {
+ r -= d;
+ nextChar = nChars;
+ }
+ }
+ return n - r;
+ }
+ }
+
+ /**
+ * Tells whether this stream is ready to be read. A buffered character
+ * stream is ready if the buffer is not empty, or if the underlying
+ * character stream is ready.
+ *
+ * @exception IOException If an I/O error occurs
+ */
+ public boolean ready() throws IOException {
+ synchronized (lock) {
+ ensureOpen();
+
+ /*
+ * If newline needs to be skipped and the next char to be read
+ * is a newline character, then just skip it right away.
+ */
+ if (skipLF) {
+ /* Note that in.ready() will return true if and only if the next
+ * read on the stream will not block.
+ */
+ if (nextChar >= nChars && in.ready()) {
+ fill();
+ }
+ if (nextChar < nChars) {
+ if (cb[nextChar] == '\n')
+ nextChar++;
+ skipLF = false;
+ }
+ }
+ return (nextChar < nChars) || in.ready();
+ }
+ }
+
+ /**
+ * Tells whether this stream supports the mark() operation, which it does.
+ */
+ public boolean markSupported() {
+ return true;
+ }
+
+ /**
+ * Marks the present position in the stream. Subsequent calls to reset()
+ * will attempt to reposition the stream to this point.
+ *
+ * @param readAheadLimit Limit on the number of characters that may be
+ * read while still preserving the mark. An attempt
+ * to reset the stream after reading characters
+ * up to this limit or beyond may fail.
+ * A limit value larger than the size of the input
+ * buffer will cause a new buffer to be allocated
+ * whose size is no smaller than limit.
+ * Therefore large values should be used with care.
+ *
+ * @exception IllegalArgumentException If readAheadLimit is < 0
+ * @exception IOException If an I/O error occurs
+ */
+ public void mark(int readAheadLimit) throws IOException {
+ if (readAheadLimit < 0) {
+ throw new IllegalArgumentException("Read-ahead limit < 0");
+ }
+ synchronized (lock) {
+ ensureOpen();
+ this.readAheadLimit = readAheadLimit;
+ markedChar = nextChar;
+ markedSkipLF = skipLF;
+ }
+ }
+
+ /**
+ * Resets the stream to the most recent mark.
+ *
+ * @exception IOException If the stream has never been marked,
+ * or if the mark has been invalidated
+ */
+ public void reset() throws IOException {
+ synchronized (lock) {
+ ensureOpen();
+ if (markedChar < 0)
+ throw new IOException((markedChar == INVALIDATED)
+ ? "Mark invalid"
+ : "Stream not marked");
+ nextChar = markedChar;
+ skipLF = markedSkipLF;
+ }
+ }
+
+ public void close() throws IOException {
+ synchronized (lock) {
+ if (in == null)
+ return;
+ in.close();
+ in = null;
+ cb = null;
+ }
+ }
+}
diff -r 9c5f89ea4c1c -r df92e9608039 emul/compact/src/main/java/java/io/InputStreamReader.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/emul/compact/src/main/java/java/io/InputStreamReader.java Wed Jan 23 22:33:45 2013 +0100
@@ -0,0 +1,201 @@
+/*
+ * 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.
+ */
+
+package java.io;
+
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import sun.nio.cs.StreamDecoder;
+
+
+/**
+ * An InputStreamReader is a bridge from byte streams to character streams: It
+ * reads bytes and decodes them into characters using a specified {@link
+ * java.nio.charset.Charset charset}. The charset that it uses
+ * may be specified by name or may be given explicitly, or the platform's
+ * default charset may be accepted.
+ *
+ *
Each invocation of one of an InputStreamReader's read() methods may
+ * cause one or more bytes to be read from the underlying byte-input stream.
+ * To enable the efficient conversion of bytes to characters, more bytes may
+ * be read ahead from the underlying stream than are necessary to satisfy the
+ * current read operation.
+ *
+ *
For top efficiency, consider wrapping an InputStreamReader within a
+ * BufferedReader. For example:
+ *
+ *
+ * BufferedReader in
+ * = new BufferedReader(new InputStreamReader(System.in));
+ *
+ *
+ * @see BufferedReader
+ * @see InputStream
+ * @see java.nio.charset.Charset
+ *
+ * @author Mark Reinhold
+ * @since JDK1.1
+ */
+
+public class InputStreamReader extends Reader {
+
+ private final StreamDecoder sd;
+
+ /**
+ * Creates an InputStreamReader that uses the default charset.
+ *
+ * @param in An InputStream
+ */
+ public InputStreamReader(InputStream in) {
+ super(in);
+ try {
+ sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object
+ } catch (UnsupportedEncodingException e) {
+ // The default encoding should always be available
+ throw new Error(e);
+ }
+ }
+
+ /**
+ * Creates an InputStreamReader that uses the named charset.
+ *
+ * @param in
+ * An InputStream
+ *
+ * @param charsetName
+ * The name of a supported
+ * {@link java.nio.charset.Charset charset}
+ *
+ * @exception UnsupportedEncodingException
+ * If the named charset is not supported
+ */
+ public InputStreamReader(InputStream in, String charsetName)
+ throws UnsupportedEncodingException
+ {
+ super(in);
+ if (charsetName == null)
+ throw new NullPointerException("charsetName");
+ sd = StreamDecoder.forInputStreamReader(in, this, charsetName);
+ }
+
+ /**
+ * Creates an InputStreamReader that uses the given charset.
+ *
+ * @param in An InputStream
+ * @param cs A charset
+ *
+ * @since 1.4
+ * @spec JSR-51
+ */
+ public InputStreamReader(InputStream in, Charset cs) {
+ super(in);
+ if (cs == null)
+ throw new NullPointerException("charset");
+ sd = StreamDecoder.forInputStreamReader(in, this, cs);
+ }
+
+ /**
+ * Creates an InputStreamReader that uses the given charset decoder.
+ *
+ * @param in An InputStream
+ * @param dec A charset decoder
+ *
+ * @since 1.4
+ * @spec JSR-51
+ */
+ public InputStreamReader(InputStream in, CharsetDecoder dec) {
+ super(in);
+ if (dec == null)
+ throw new NullPointerException("charset decoder");
+ sd = StreamDecoder.forInputStreamReader(in, this, dec);
+ }
+
+ /**
+ * Returns the name of the character encoding being used by this stream.
+ *
+ *
If the encoding has an historical name then that name is returned;
+ * otherwise the encoding's canonical name is returned.
+ *
+ *
If this instance was created with the {@link
+ * #InputStreamReader(InputStream, String)} constructor then the returned
+ * name, being unique for the encoding, may differ from the name passed to
+ * the constructor. This method will return null if the
+ * stream has been closed.
+ *
+ * @return The historical name of this encoding, or
+ * null if the stream has been closed
+ *
+ * @see java.nio.charset.Charset
+ *
+ * @revised 1.4
+ * @spec JSR-51
+ */
+ public String getEncoding() {
+ return sd.getEncoding();
+ }
+
+ /**
+ * Reads a single character.
+ *
+ * @return The character read, or -1 if the end of the stream has been
+ * reached
+ *
+ * @exception IOException If an I/O error occurs
+ */
+ public int read() throws IOException {
+ return sd.read();
+ }
+
+ /**
+ * Reads characters into a portion of an array.
+ *
+ * @param cbuf Destination buffer
+ * @param offset Offset at which to start storing characters
+ * @param length Maximum number of characters to read
+ *
+ * @return The number of characters read, or -1 if the end of the
+ * stream has been reached
+ *
+ * @exception IOException If an I/O error occurs
+ */
+ public int read(char cbuf[], int offset, int length) throws IOException {
+ return sd.read(cbuf, offset, length);
+ }
+
+ /**
+ * Tells whether this stream is ready to be read. An InputStreamReader is
+ * ready if its input buffer is not empty, or if bytes are available to be
+ * read from the underlying byte stream.
+ *
+ * @exception IOException If an I/O error occurs
+ */
+ public boolean ready() throws IOException {
+ return sd.ready();
+ }
+
+ public void close() throws IOException {
+ sd.close();
+ }
+}
diff -r 9c5f89ea4c1c -r df92e9608039 emul/compact/src/main/java/java/io/Reader.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/emul/compact/src/main/java/java/io/Reader.java Wed Jan 23 22:33:45 2013 +0100
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 1996, 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.io;
+
+
+/**
+ * Abstract class for reading character streams. The only methods that a
+ * subclass must implement are read(char[], int, int) and close(). Most
+ * subclasses, however, will override some of the methods defined here in order
+ * to provide higher efficiency, additional functionality, or both.
+ *
+ *
+ * @see BufferedReader
+ * @see LineNumberReader
+ * @see CharArrayReader
+ * @see InputStreamReader
+ * @see FileReader
+ * @see FilterReader
+ * @see PushbackReader
+ * @see PipedReader
+ * @see StringReader
+ * @see Writer
+ *
+ * @author Mark Reinhold
+ * @since JDK1.1
+ */
+
+public abstract class Reader implements Readable, Closeable {
+
+ /**
+ * The object used to synchronize operations on this stream. For
+ * efficiency, a character-stream object may use an object other than
+ * itself to protect critical sections. A subclass should therefore use
+ * the object in this field rather than this or a synchronized
+ * method.
+ */
+ protected Object lock;
+
+ /**
+ * Creates a new character-stream reader whose critical sections will
+ * synchronize on the reader itself.
+ */
+ protected Reader() {
+ this.lock = this;
+ }
+
+ /**
+ * Creates a new character-stream reader whose critical sections will
+ * synchronize on the given object.
+ *
+ * @param lock The Object to synchronize on.
+ */
+ protected Reader(Object lock) {
+ if (lock == null) {
+ throw new NullPointerException();
+ }
+ this.lock = lock;
+ }
+
+ /**
+ * Attempts to read characters into the specified character buffer.
+ * The buffer is used as a repository of characters as-is: the only
+ * changes made are the results of a put operation. No flipping or
+ * rewinding of the buffer is performed.
+ *
+ * @param target the buffer to read characters into
+ * @return The number of characters added to the buffer, or
+ * -1 if this source of characters is at its end
+ * @throws IOException if an I/O error occurs
+ * @throws NullPointerException if target is null
+ * @throws ReadOnlyBufferException if target is a read only buffer
+ * @since 1.5
+ */
+ public int read(java.nio.CharBuffer target) throws IOException {
+ int len = target.remaining();
+ char[] cbuf = new char[len];
+ int n = read(cbuf, 0, len);
+ if (n > 0)
+ target.put(cbuf, 0, n);
+ return n;
+ }
+
+ /**
+ * Reads a single character. This method will block until a character is
+ * available, an I/O error occurs, or the end of the stream is reached.
+ *
+ *
Subclasses that intend to support efficient single-character input
+ * should override this method.
+ *
+ * @return The character read, as an integer in the range 0 to 65535
+ * (0x00-0xffff), or -1 if the end of the stream has
+ * been reached
+ *
+ * @exception IOException If an I/O error occurs
+ */
+ public int read() throws IOException {
+ char cb[] = new char[1];
+ if (read(cb, 0, 1) == -1)
+ return -1;
+ else
+ return cb[0];
+ }
+
+ /**
+ * Reads characters into an array. This method will block until some input
+ * is available, an I/O error occurs, or the end of the stream is reached.
+ *
+ * @param cbuf Destination buffer
+ *
+ * @return The number of characters read, or -1
+ * if the end of the stream
+ * has been reached
+ *
+ * @exception IOException If an I/O error occurs
+ */
+ public int read(char cbuf[]) throws IOException {
+ return read(cbuf, 0, cbuf.length);
+ }
+
+ /**
+ * Reads characters into a portion of an array. This method will block
+ * until some input is available, an I/O error occurs, or the end of the
+ * stream is reached.
+ *
+ * @param cbuf Destination buffer
+ * @param off Offset at which to start storing characters
+ * @param len Maximum number of characters to read
+ *
+ * @return The number of characters read, or -1 if the end of the
+ * stream has been reached
+ *
+ * @exception IOException If an I/O error occurs
+ */
+ abstract public int read(char cbuf[], int off, int len) throws IOException;
+
+ /** Maximum skip-buffer size */
+ private static final int maxSkipBufferSize = 8192;
+
+ /** Skip buffer, null until allocated */
+ private char skipBuffer[] = null;
+
+ /**
+ * Skips characters. This method will block until some characters are
+ * available, an I/O error occurs, or the end of the stream is reached.
+ *
+ * @param n The number of characters to skip
+ *
+ * @return The number of characters actually skipped
+ *
+ * @exception IllegalArgumentException If n is negative.
+ * @exception IOException If an I/O error occurs
+ */
+ public long skip(long n) throws IOException {
+ if (n < 0L)
+ throw new IllegalArgumentException("skip value is negative");
+ int nn = (int) Math.min(n, maxSkipBufferSize);
+ synchronized (lock) {
+ if ((skipBuffer == null) || (skipBuffer.length < nn))
+ skipBuffer = new char[nn];
+ long r = n;
+ while (r > 0) {
+ int nc = read(skipBuffer, 0, (int)Math.min(r, nn));
+ if (nc == -1)
+ break;
+ r -= nc;
+ }
+ return n - r;
+ }
+ }
+
+ /**
+ * Tells whether this stream is ready to be read.
+ *
+ * @return True if the next read() is guaranteed not to block for input,
+ * false otherwise. Note that returning false does not guarantee that the
+ * next read will block.
+ *
+ * @exception IOException If an I/O error occurs
+ */
+ public boolean ready() throws IOException {
+ return false;
+ }
+
+ /**
+ * Tells whether this stream supports the mark() operation. The default
+ * implementation always returns false. Subclasses should override this
+ * method.
+ *
+ * @return true if and only if this stream supports the mark operation.
+ */
+ public boolean markSupported() {
+ return false;
+ }
+
+ /**
+ * Marks the present position in the stream. Subsequent calls to reset()
+ * will attempt to reposition the stream to this point. Not all
+ * character-input streams support the mark() operation.
+ *
+ * @param readAheadLimit Limit on the number of characters that may be
+ * read while still preserving the mark. After
+ * reading this many characters, attempting to
+ * reset the stream may fail.
+ *
+ * @exception IOException If the stream does not support mark(),
+ * or if some other I/O error occurs
+ */
+ public void mark(int readAheadLimit) throws IOException {
+ throw new IOException("mark() not supported");
+ }
+
+ /**
+ * Resets the stream. If the stream has been marked, then attempt to
+ * reposition it at the mark. If the stream has not been marked, then
+ * attempt to reset it in some way appropriate to the particular stream,
+ * for example by repositioning it to its starting point. Not all
+ * character-input streams support the reset() operation, and some support
+ * reset() without supporting mark().
+ *
+ * @exception IOException If the stream has not been marked,
+ * or if the mark has been invalidated,
+ * or if the stream does not support reset(),
+ * or if some other I/O error occurs
+ */
+ public void reset() throws IOException {
+ throw new IOException("reset() not supported");
+ }
+
+ /**
+ * Closes the stream and releases any system resources associated with
+ * it. Once the stream has been closed, further read(), ready(),
+ * mark(), reset(), or skip() invocations will throw an IOException.
+ * Closing a previously closed stream has no effect.
+ *
+ * @exception IOException If an I/O error occurs
+ */
+ abstract public void close() throws IOException;
+
+}
diff -r 9c5f89ea4c1c -r df92e9608039 emul/compact/src/main/java/java/lang/Cloneable.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/emul/compact/src/main/java/java/lang/Cloneable.java Wed Jan 23 22:33:45 2013 +0100
@@ -0,0 +1,54 @@
+/*
+ * 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.lang;
+
+/**
+ * A class implements the Cloneable interface to
+ * indicate to the {@link java.lang.Object#clone()} method that it
+ * is legal for that method to make a
+ * field-for-field copy of instances of that class.
+ *
+ * Invoking Object's clone method on an instance that does not implement the
+ * Cloneable interface results in the exception
+ * CloneNotSupportedException being thrown.
+ *
+ * By convention, classes that implement this interface should override
+ * Object.clone (which is protected) with a public method.
+ * See {@link java.lang.Object#clone()} for details on overriding this
+ * method.
+ *
+ * Note that this interface does not contain the clone method.
+ * Therefore, it is not possible to clone an object merely by virtue of the
+ * fact that it implements this interface. Even if the clone method is invoked
+ * reflectively, there is no guarantee that it will succeed.
+ *
+ * @author unascribed
+ * @see java.lang.CloneNotSupportedException
+ * @see java.lang.Object#clone()
+ * @since JDK1.0
+ */
+public interface Cloneable {
+}
diff -r 9c5f89ea4c1c -r df92e9608039 emul/compact/src/main/java/java/lang/InternalError.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/emul/compact/src/main/java/java/lang/InternalError.java Wed Jan 23 22:33:45 2013 +0100
@@ -0,0 +1,55 @@
+/*
+ * 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.lang;
+
+/**
+ * Thrown to indicate some unexpected internal error has occurred in
+ * the Java Virtual Machine.
+ *
+ * @author unascribed
+ * @since JDK1.0
+ */
+public
+class InternalError extends VirtualMachineError {
+ private static final long serialVersionUID = -9062593416125562365L;
+
+ /**
+ * Constructs an InternalError with no detail message.
+ */
+ public InternalError() {
+ super();
+ }
+
+ /**
+ * Constructs an InternalError with the specified
+ * detail message.
+ *
+ * @param s the detail message.
+ */
+ public InternalError(String s) {
+ super(s);
+ }
+}
diff -r 9c5f89ea4c1c -r df92e9608039 emul/compact/src/main/java/java/lang/Iterable.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/emul/compact/src/main/java/java/lang/Iterable.java Wed Jan 23 22:33:45 2013 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2003, 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.lang;
+
+import java.util.Iterator;
+
+/**
+ * Implementing this interface allows an object to be the target of
+ * the "foreach" statement.
+ *
+ * @param the type of elements returned by the iterator
+ *
+ * @since 1.5
+ */
+public interface Iterable {
+
+ /**
+ * Returns an iterator over a set of elements of type T.
+ *
+ * @return an Iterator.
+ */
+ Iterator iterator();
+}
diff -r 9c5f89ea4c1c -r df92e9608039 emul/compact/src/main/java/java/lang/Readable.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/emul/compact/src/main/java/java/lang/Readable.java Wed Jan 23 22:33:45 2013 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2003, 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.lang;
+
+import java.io.IOException;
+
+/**
+ * A Readable is a source of characters. Characters from
+ * a Readable are made available to callers of the read
+ * method via a {@link java.nio.CharBuffer CharBuffer}.
+ *
+ * @since 1.5
+ */
+
+public interface Readable {
+
+ /**
+ * Attempts to read characters into the specified character buffer.
+ * The buffer is used as a repository of characters as-is: the only
+ * changes made are the results of a put operation. No flipping or
+ * rewinding of the buffer is performed.
+ *
+ * @param cb the buffer to read characters into
+ * @return The number of {@code char} values added to the buffer,
+ * or -1 if this source of characters is at its end
+ * @throws IOException if an I/O error occurs
+ * @throws NullPointerException if cb is null
+ * @throws java.nio.ReadOnlyBufferException if cb is a read only buffer
+ */
+ public int read(java.nio.CharBuffer cb) throws IOException;
+
+}
diff -r 9c5f89ea4c1c -r df92e9608039 emul/compact/src/main/java/java/lang/SuppressWarnings.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/emul/compact/src/main/java/java/lang/SuppressWarnings.java Wed Jan 23 22:33:45 2013 +0100
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2004, 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.lang;
+
+import java.lang.annotation.*;
+import static java.lang.annotation.ElementType.*;
+
+/**
+ * Indicates that the named compiler warnings should be suppressed in the
+ * annotated element (and in all program elements contained in the annotated
+ * element). Note that the set of warnings suppressed in a given element is
+ * a superset of the warnings suppressed in all containing elements. For
+ * example, if you annotate a class to suppress one warning and annotate a
+ * method to suppress another, both warnings will be suppressed in the method.
+ *
+ *
As a matter of style, programmers should always use this annotation
+ * on the most deeply nested element where it is effective. If you want to
+ * suppress a warning in a particular method, you should annotate that
+ * method rather than its class.
+ *
+ * @since 1.5
+ * @author Josh Bloch
+ */
+@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
+@Retention(RetentionPolicy.SOURCE)
+public @interface SuppressWarnings {
+ /**
+ * The set of warnings that are to be suppressed by the compiler in the
+ * annotated element. Duplicate names are permitted. The second and
+ * successive occurrences of a name are ignored. The presence of
+ * unrecognized warning names is not an error: Compilers must
+ * ignore any warning names they do not recognize. They are, however,
+ * free to emit a warning if an annotation contains an unrecognized
+ * warning name.
+ *
+ *
Compiler vendors should document the warning names they support in
+ * conjunction with this annotation type. They are encouraged to cooperate
+ * to ensure that the same names work across multiple compilers.
+ */
+ String[] value();
+}
diff -r 9c5f89ea4c1c -r df92e9608039 emul/compact/src/main/java/java/util/AbstractCollection.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/emul/compact/src/main/java/java/util/AbstractCollection.java Wed Jan 23 22:33:45 2013 +0100
@@ -0,0 +1,457 @@
+/*
+ * Copyright (c) 1997, 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;
+
+/**
+ * This class provides a skeletal implementation of the Collection
+ * interface, to minimize the effort required to implement this interface.
+ *
+ * To implement an unmodifiable collection, the programmer needs only to
+ * extend this class and provide implementations for the iterator and
+ * size methods. (The iterator returned by the iterator
+ * method must implement hasNext and next.)
+ *
+ * To implement a modifiable collection, the programmer must additionally
+ * override this class's add method (which otherwise throws an
+ * UnsupportedOperationException), and the iterator returned by the
+ * iterator method must additionally implement its remove
+ * method.
+ *
+ * The programmer should generally provide a void (no argument) and
+ * Collection constructor, as per the recommendation in the
+ * Collection interface specification.
+ *
+ * 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.
+ *
+ * This class is a member of the
+ *
+ * Java Collections Framework.
+ *
+ * @author Josh Bloch
+ * @author Neal Gafter
+ * @see Collection
+ * @since 1.2
+ */
+
+public abstract class AbstractCollection implements Collection {
+ /**
+ * 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 iterator();
+
+ public abstract int size();
+
+ /**
+ * {@inheritDoc}
+ *
+ *
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 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}
+ *
+ *
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.
+ *
+ *
This method is equivalent to:
+ *
+ *
{@code
+ * List list = new ArrayList(size());
+ * for (E e : this)
+ * list.add(e);
+ * return list.toArray();
+ * }
+ */
+ public Object[] toArray() {
+ // Estimate size of array; be prepared to see more or fewer elements
+ Object[] r = new Object[size()];
+ Iterator 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}
+ *
+ *
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.
+ *
+ *
This method is equivalent to:
+ *
+ *
{@code
+ * List list = new ArrayList(size());
+ * for (E e : this)
+ * list.add(e);
+ * return list.toArray(a);
+ * }
+ *
+ * @throws ArrayStoreException {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ */
+ public 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 it = iterator();
+
+ for (int i = 0; i < r.length; i++) {
+ if (! it.hasNext()) { // fewer elements than expected
+ if (a != r)
+ return Arrays.copyOf(r, i);
+ r[i] = null; // null-terminate
+ return r;
+ }
+ r[i] = (T)it.next();
+ }
+ 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
+ */
+ private static 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}
+ *
+ *
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.
+ *
+ *
Note that this implementation throws an
+ * UnsupportedOperationException if the iterator returned by this
+ * collection's iterator method does not implement the remove
+ * method and this collection contains the specified object.
+ *
+ * @throws UnsupportedOperationException {@inheritDoc}
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ */
+ public boolean remove(Object o) {
+ Iterator 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}
+ *
+ *
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 true is returned, otherwise false.
+ *
+ * @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}
+ *
+ *
This implementation iterates over the specified collection, and adds
+ * each object returned by the iterator to this collection, in turn.
+ *
+ *
Note that this implementation will throw an
+ * UnsupportedOperationException unless add 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}
+ *
+ *
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 remove method.
+ *
+ *
Note that this implementation will throw an
+ * UnsupportedOperationException if the iterator returned by the
+ * iterator method does not implement the remove 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) {
+ boolean modified = false;
+ Iterator> it = iterator();
+ while (it.hasNext()) {
+ if (c.contains(it.next())) {
+ it.remove();
+ modified = true;
+ }
+ }
+ return modified;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ *
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 remove method.
+ *
+ *
Note that this implementation will throw an
+ * UnsupportedOperationException if the iterator returned by the
+ * iterator method does not implement the remove 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) {
+ boolean modified = false;
+ Iterator it = iterator();
+ while (it.hasNext()) {
+ if (!c.contains(it.next())) {
+ it.remove();
+ modified = true;
+ }
+ }
+ return modified;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ *
This implementation iterates over this collection, removing each
+ * element using the Iterator.remove operation. Most
+ * implementations will probably choose to override this method for
+ * efficiency.
+ *
+ *
Note that this implementation will throw an
+ * UnsupportedOperationException if the iterator returned by this
+ * collection's iterator method does not implement the
+ * remove method and this collection is non-empty.
+ *
+ * @throws UnsupportedOperationException {@inheritDoc}
+ */
+ public void clear() {
+ Iterator 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
+ * ("[]"). Adjacent elements are separated by the characters
+ * ", " (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 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(' ');
+ }
+ }
+
+}
diff -r 9c5f89ea4c1c -r df92e9608039 emul/compact/src/main/java/java/util/AbstractList.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/emul/compact/src/main/java/java/util/AbstractList.java Wed Jan 23 22:33:45 2013 +0100
@@ -0,0 +1,781 @@
+/*
+ * Copyright (c) 1997, 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;
+
+/**
+ * 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.
+ *
+ *
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.
+ *
+ *
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.
+ *
+ *
The programmer should generally provide a void (no argument) and collection
+ * constructor, as per the recommendation in the {@link Collection} interface
+ * specification.
+ *
+ *
Unlike the other abstract collection implementations, the programmer does
+ * not 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)}.
+ *
+ *
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.
+ *
+ *
This class is a member of the
+ *
+ * Java Collections Framework.
+ *
+ * @author Josh Bloch
+ * @author Neal Gafter
+ * @since 1.2
+ */
+
+public abstract class AbstractList extends AbstractCollection implements List {
+ /**
+ * Sole constructor. (For invocation by subclass constructors, typically
+ * implicit.)
+ */
+ protected AbstractList() {
+ }
+
+ /**
+ * Appends the specified element to the end of this list (optional
+ * operation).
+ *
+ *
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.
+ *
+ *
This implementation calls {@code add(size(), e)}.
+ *
+ *
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}
+ *
+ *
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 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}
+ *
+ *
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 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.
+ *
+ *
This implementation calls {@code removeRange(0, size())}.
+ *
+ *
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}
+ *
+ *
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.
+ *
+ *
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.
+ *
+ *
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.
+ *
+ *
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.
+ *
+ *
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 iterator() {
+ return new Itr();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ *
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.
+ *
+ *
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.
+ *
+ *
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 listIterator(final int index) {
+ rangeCheckForAdd(index);
+
+ return new ListItr(index);
+ }
+
+ private class Itr implements Iterator {
+ /**
+ * 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 {
+ 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}
+ *
+ *
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}.
+ *
+ *
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)}.
+ *
+ *
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.
+ *
+ *
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 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 equal. (Two elements {@code e1} and
+ * {@code e2} are equal 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.
+ *
+ * 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 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.
+ *
+ *
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.)
+ *
+ *
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 substantially
+ * improve the performance of the {@code clear} operation on this list
+ * and its subLists.
+ *
+ *
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. Note: if {@code ListIterator.remove} requires linear
+ * time, this implementation requires quadratic time.
+ *
+ * @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 it = listIterator(fromIndex);
+ for (int i=0, n=toIndex-fromIndex; istructurally modified.
+ * 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.
+ *
+ *
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
+ * fail-fast behavior, rather than non-deterministic behavior in
+ * the face of concurrent modification during iteration.
+ *
+ *
Use of this field by subclasses is optional. 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 extends AbstractList {
+ private final AbstractList l;
+ private final int offset;
+ private int size;
+
+ SubList(AbstractList 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 iterator() {
+ return listIterator();
+ }
+
+ public ListIterator listIterator(final int index) {
+ checkForComodification();
+ rangeCheckForAdd(index);
+
+ return new ListIterator() {
+ private final ListIterator 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 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 extends SubList implements RandomAccess {
+ RandomAccessSubList(AbstractList list, int fromIndex, int toIndex) {
+ super(list, fromIndex, toIndex);
+ }
+
+ public List subList(int fromIndex, int toIndex) {
+ return new RandomAccessSubList<>(this, fromIndex, toIndex);
+ }
+}
diff -r 9c5f89ea4c1c -r df92e9608039 emul/compact/src/main/java/java/util/AbstractMap.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/emul/compact/src/main/java/java/util/AbstractMap.java Wed Jan 23 22:33:45 2013 +0100
@@ -0,0 +1,822 @@
+/*
+ * Copyright (c) 1997, 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;
+import java.util.Map.Entry;
+
+/**
+ * This class provides a skeletal implementation of the Map
+ * interface, to minimize the effort required to implement this interface.
+ *
+ *
To implement an unmodifiable map, the programmer needs only to extend this
+ * class and provide an implementation for the entrySet method, which
+ * returns a set-view of the map's mappings. Typically, the returned set
+ * will, in turn, be implemented atop AbstractSet. This set should
+ * not support the add or remove methods, and its iterator
+ * should not support the remove method.
+ *
+ *
To implement a modifiable map, the programmer must additionally override
+ * this class's put method (which otherwise throws an
+ * UnsupportedOperationException), and the iterator returned by
+ * entrySet().iterator() must additionally implement its
+ * remove method.
+ *
+ *
The programmer should generally provide a void (no argument) and map
+ * constructor, as per the recommendation in the Map interface
+ * specification.
+ *
+ *
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.
+ *
+ *
This class is a member of the
+ *
+ * Java Collections Framework.
+ *
+ * @param the type of keys maintained by this map
+ * @param the type of mapped values
+ *
+ * @author Josh Bloch
+ * @author Neal Gafter
+ * @see Map
+ * @see Collection
+ * @since 1.2
+ */
+
+public abstract class AbstractMap implements Map {
+ /**
+ * Sole constructor. (For invocation by subclass constructors, typically
+ * implicit.)
+ */
+ protected AbstractMap() {
+ }
+
+ // Query Operations
+
+ /**
+ * {@inheritDoc}
+ *
+ *
This implementation returns entrySet().size().
+ */
+ public int size() {
+ return entrySet().size();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ *
This implementation iterates over entrySet() searching
+ * for an entry with the specified value. If such an entry is found,
+ * true is returned. If the iteration terminates without
+ * finding such an entry, false 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> i = entrySet().iterator();
+ if (value==null) {
+ while (i.hasNext()) {
+ Entry e = i.next();
+ if (e.getValue()==null)
+ return true;
+ }
+ } else {
+ while (i.hasNext()) {
+ Entry e = i.next();
+ if (value.equals(e.getValue()))
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ *
This implementation iterates over entrySet() searching
+ * for an entry with the specified key. If such an entry is found,
+ * true is returned. If the iteration terminates without
+ * finding such an entry, false 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> i = entrySet().iterator();
+ if (key==null) {
+ while (i.hasNext()) {
+ Entry e = i.next();
+ if (e.getKey()==null)
+ return true;
+ }
+ } else {
+ while (i.hasNext()) {
+ Entry e = i.next();
+ if (key.equals(e.getKey()))
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ *
This implementation iterates over entrySet() 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, null 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> i = entrySet().iterator();
+ if (key==null) {
+ while (i.hasNext()) {
+ Entry e = i.next();
+ if (e.getKey()==null)
+ return e.getValue();
+ }
+ } else {
+ while (i.hasNext()) {
+ Entry e = i.next();
+ if (key.equals(e.getKey()))
+ return e.getValue();
+ }
+ }
+ return null;
+ }
+
+
+ // Modification Operations
+
+ /**
+ * {@inheritDoc}
+ *
+ *
This implementation always throws an
+ * UnsupportedOperationException.
+ *
+ * @throws UnsupportedOperationException {@inheritDoc}
+ * @throws ClassCastException {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @throws IllegalArgumentException {@inheritDoc}
+ */
+ public V put(K key, V value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ *
This implementation iterates over entrySet() searching for an
+ * entry with the specified key. If such an entry is found, its value is
+ * obtained with its getValue operation, the entry is removed
+ * from the collection (and the backing map) with the iterator's
+ * remove operation, and the saved value is returned. If the
+ * iteration terminates without finding such an entry, null is
+ * returned. Note that this implementation requires linear time in the
+ * size of the map; many implementations will override this method.
+ *
+ *
Note that this implementation throws an
+ * UnsupportedOperationException if the entrySet
+ * iterator does not support the remove 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> i = entrySet().iterator();
+ Entry correctEntry = null;
+ if (key==null) {
+ while (correctEntry==null && i.hasNext()) {
+ Entry e = i.next();
+ if (e.getKey()==null)
+ correctEntry = e;
+ }
+ } else {
+ while (correctEntry==null && i.hasNext()) {
+ Entry 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}
+ *
+ *
This implementation iterates over the specified map's
+ * entrySet() collection, and calls this map's put
+ * operation once for each entry returned by the iteration.
+ *
+ *
Note that this implementation throws an
+ * UnsupportedOperationException if this map does not support
+ * the put 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}
+ *
+ *
This implementation calls entrySet().clear().
+ *
+ *
Note that this implementation throws an
+ * UnsupportedOperationException if the entrySet
+ * does not support the clear 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.
+ */
+ transient volatile Set keySet = null;
+ transient volatile Collection values = null;
+
+ /**
+ * {@inheritDoc}
+ *
+ *
This implementation returns a set that subclasses {@link AbstractSet}.
+ * The subclass's iterator method returns a "wrapper object" over this
+ * map's entrySet() iterator. The size method
+ * delegates to this map's size method and the
+ * contains method delegates to this map's
+ * containsKey method.
+ *
+ *
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 keySet() {
+ if (keySet == null) {
+ keySet = new AbstractSet() {
+ public Iterator iterator() {
+ return new Iterator() {
+ private Iterator> 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);
+ }
+ };
+ }
+ return keySet;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ *
This implementation returns a collection that subclasses {@link
+ * AbstractCollection}. The subclass's iterator method returns a
+ * "wrapper object" over this map's entrySet() iterator.
+ * The size method delegates to this map's size
+ * method and the contains method delegates to this map's
+ * containsValue method.
+ *
+ *
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 values() {
+ if (values == null) {
+ values = new AbstractCollection() {
+ public Iterator iterator() {
+ return new Iterator() {
+ private Iterator> 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);
+ }
+ };
+ }
+ return values;
+ }
+
+ public abstract Set> entrySet();
+
+
+ // Comparison and hashing
+
+ /**
+ * Compares the specified object with this map for equality. Returns
+ * true if the given object is also a map and the two maps
+ * represent the same mappings. More formally, two maps m1 and
+ * m2 represent the same mappings if
+ * m1.entrySet().equals(m2.entrySet()). This ensures that the
+ * equals method works properly across different implementations
+ * of the Map interface.
+ *
+ *
This implementation first checks if the specified object is this map;
+ * if so it returns true. Then, it checks if the specified
+ * object is a map whose size is identical to the size of this map; if
+ * not, it returns false. If so, it iterates over this map's
+ * entrySet collection, and checks that the specified map
+ * contains each mapping that this map contains. If the specified map
+ * fails to contain such a mapping, false is returned. If the
+ * iteration completes, true is returned.
+ *
+ * @param o object to be compared for equality with this map
+ * @return true 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> i = entrySet().iterator();
+ while (i.hasNext()) {
+ Entry 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
+ * entrySet() view. This ensures that m1.equals(m2)
+ * implies that m1.hashCode()==m2.hashCode() for any two maps
+ * m1 and m2, as required by the general contract of
+ * {@link Object#hashCode}.
+ *
+ *
This implementation iterates over entrySet(), 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> 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 entrySet view's iterator, enclosed in braces
+ * ("{}"). Adjacent mappings are separated by the characters
+ * ", " (comma and space). Each key-value mapping is rendered as
+ * the key followed by an equals sign ("=") 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> i = entrySet().iterator();
+ if (! i.hasNext())
+ return "{}";
+
+ StringBuilder sb = new StringBuilder();
+ sb.append('{');
+ for (;;) {
+ Entry 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 AbstractMap 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.
+ */
+ 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 setValue method. This class
+ * facilitates the process of building custom map
+ * implementations. For example, it may be convenient to return
+ * arrays of SimpleEntry instances in method
+ * Map.entrySet().toArray.
+ *
+ * @since 1.6
+ */
+ public static class SimpleEntry
+ implements Entry, 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
+ * 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:
+ * 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 ("=")
+ * 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 setValue. This class may be
+ * convenient in methods that return thread-safe snapshots of
+ * key-value mappings.
+ *
+ * @since 1.6
+ */
+ public static class SimpleImmutableEntry
+ implements Entry, 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
+ * UnsupportedOperationException, as this class implements
+ * an immutable 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
+ * 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:
+ * 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 ("=")
+ * followed by the string representation of this entry's value.
+ *
+ * @return a String representation of this map entry
+ */
+ public String toString() {
+ return key + "=" + value;
+ }
+
+ }
+
+}
diff -r 9c5f89ea4c1c -r df92e9608039 emul/compact/src/main/java/java/util/AbstractSet.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/emul/compact/src/main/java/java/util/AbstractSet.java Wed Jan 23 22:33:45 2013 +0100
@@ -0,0 +1,185 @@
+/*
+ * 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 Set
+ * interface to minimize the effort required to implement this
+ * interface.
+ *
+ * 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 Set
+ * interface (for instance, the add method must not permit addition of
+ * multiple instances of an object to a set).
+ *
+ * Note that this class does not override any of the implementations from
+ * the AbstractCollection class. It merely adds implementations
+ * for equals and hashCode.
+ *
+ * This class is a member of the
+ *
+ * Java Collections Framework.
+ *
+ * @param 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 extends AbstractCollection implements Set {
+ /**
+ * Sole constructor. (For invocation by subclass constructors, typically
+ * implicit.)
+ */
+ protected AbstractSet() {
+ }
+
+ // Comparison and hashing
+
+ /**
+ * Compares the specified object with this set for equality. Returns
+ * true 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 equals method works
+ * properly across different implementations of the Set
+ * interface.
+ *
+ * This implementation first checks if the specified object is this
+ * set; if so it returns true. 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
+ * containsAll((Collection) o).
+ *
+ * @param o object to be compared for equality with this set
+ * @return true 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 null element is defined to be zero.
+ * This ensures that s1.equals(s2) implies that
+ * s1.hashCode()==s2.hashCode() for any two sets s1
+ * and s2, as required by the general contract of
+ * {@link Object#hashCode}.
+ *
+ *
This implementation iterates over the set, calling the
+ * hashCode 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 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 asymmetric set difference of
+ * the two sets.
+ *
+ *
This implementation determines which is the smaller of this set
+ * and the specified collection, by invoking the size
+ * 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 remove 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 remove method.
+ *
+ *
Note that this implementation will throw an
+ * UnsupportedOperationException if the iterator returned by the
+ * iterator method does not implement the remove method.
+ *
+ * @param c collection containing elements to be removed from this set
+ * @return true if this set changed as a result of the call
+ * @throws UnsupportedOperationException if the removeAll operation
+ * is not supported by this set
+ * @throws ClassCastException if the class of an element of this set
+ * is incompatible with the specified collection
+ * (optional)
+ * @throws NullPointerException if this set contains a null element and the
+ * specified collection does not permit null elements
+ * (optional),
+ * or if the specified collection is null
+ * @see #remove(Object)
+ * @see #contains(Object)
+ */
+ public boolean removeAll(Collection> 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;
+ }
+
+}
diff -r 9c5f89ea4c1c -r df92e9608039 emul/compact/src/main/java/java/util/ArrayList.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/emul/compact/src/main/java/java/util/ArrayList.java Wed Jan 23 22:33:45 2013 +0100
@@ -0,0 +1,1132 @@
+/*
+ * Copyright (c) 1997, 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;
+
+/**
+ * Resizable-array implementation of the List interface. Implements
+ * all optional list operations, and permits all elements, including
+ * null. In addition to implementing the List interface,
+ * this class provides methods to manipulate the size of the array that is
+ * used internally to store the list. (This class is roughly equivalent to
+ * Vector, except that it is unsynchronized.)
+ *
+ *
The size, isEmpty, get, set,
+ * iterator, and listIterator operations run in constant
+ * time. The add operation runs in amortized constant time,
+ * that is, adding n elements requires O(n) time. All of the other operations
+ * run in linear time (roughly speaking). The constant factor is low compared
+ * to that for the LinkedList implementation.
+ *
+ *
Each ArrayList instance has a capacity. The capacity is
+ * the size of the array used to store the elements in the list. It is always
+ * at least as large as the list size. As elements are added to an ArrayList,
+ * its capacity grows automatically. The details of the growth policy are not
+ * specified beyond the fact that adding an element has constant amortized
+ * time cost.
+ *
+ *
An application can increase the capacity of an ArrayList instance
+ * before adding a large number of elements using the ensureCapacity
+ * operation. This may reduce the amount of incremental reallocation.
+ *
+ *
Note that this implementation is not synchronized.
+ * If multiple threads access an ArrayList instance concurrently,
+ * and at least one of the threads modifies the list structurally, it
+ * must be synchronized externally. (A structural modification is
+ * any operation that adds or deletes one or more elements, or explicitly
+ * resizes the backing array; merely setting the value of an element is not
+ * a structural modification.) This is typically accomplished by
+ * synchronizing on some object that naturally encapsulates the list.
+ *
+ * If no such object exists, the list should be "wrapped" using the
+ * {@link Collections#synchronizedList Collections.synchronizedList}
+ * method. This is best done at creation time, to prevent accidental
+ * unsynchronized access to the list:
+ * List list = Collections.synchronizedList(new ArrayList(...));
+ *
+ *
+ * The iterators returned by this class's {@link #iterator() iterator} and
+ * {@link #listIterator(int) listIterator} methods are fail-fast:
+ * if the list is structurally modified at any time after the iterator is
+ * created, in any way except through the iterator's own
+ * {@link ListIterator#remove() remove} or
+ * {@link ListIterator#add(Object) add} methods, 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.
+ *
+ *
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: the fail-fast behavior of iterators
+ * should be used only to detect bugs.
+ *
+ *
This class is a member of the
+ *
+ * Java Collections Framework.
+ *
+ * @author Josh Bloch
+ * @author Neal Gafter
+ * @see Collection
+ * @see List
+ * @see LinkedList
+ * @see Vector
+ * @since 1.2
+ */
+
+public class ArrayList extends AbstractList
+ implements List, RandomAccess, Cloneable, java.io.Serializable
+{
+ private static final long serialVersionUID = 8683452581122892189L;
+
+ /**
+ * The array buffer into which the elements of the ArrayList are stored.
+ * The capacity of the ArrayList is the length of this array buffer.
+ */
+ private transient Object[] elementData;
+
+ /**
+ * The size of the ArrayList (the number of elements it contains).
+ *
+ * @serial
+ */
+ private int size;
+
+ /**
+ * Constructs an empty list with the specified initial capacity.
+ *
+ * @param initialCapacity the initial capacity of the list
+ * @throws IllegalArgumentException if the specified initial capacity
+ * is negative
+ */
+ public ArrayList(int initialCapacity) {
+ super();
+ if (initialCapacity < 0)
+ throw new IllegalArgumentException("Illegal Capacity: "+
+ initialCapacity);
+ this.elementData = new Object[initialCapacity];
+ }
+
+ /**
+ * Constructs an empty list with an initial capacity of ten.
+ */
+ public ArrayList() {
+ this(10);
+ }
+
+ /**
+ * Constructs a list containing the elements of the specified
+ * collection, in the order they are returned by the collection's
+ * iterator.
+ *
+ * @param c the collection whose elements are to be placed into this list
+ * @throws NullPointerException if the specified collection is null
+ */
+ public ArrayList(Collection extends E> c) {
+ elementData = c.toArray();
+ size = elementData.length;
+ // c.toArray might (incorrectly) not return Object[] (see 6260652)
+ if (elementData.getClass() != Object[].class)
+ elementData = Arrays.copyOf(elementData, size, Object[].class);
+ }
+
+ /**
+ * Trims the capacity of this ArrayList instance to be the
+ * list's current size. An application can use this operation to minimize
+ * the storage of an ArrayList instance.
+ */
+ public void trimToSize() {
+ modCount++;
+ int oldCapacity = elementData.length;
+ if (size < oldCapacity) {
+ elementData = Arrays.copyOf(elementData, size);
+ }
+ }
+
+ /**
+ * Increases the capacity of this ArrayList instance, if
+ * necessary, to ensure that it can hold at least the number of elements
+ * specified by the minimum capacity argument.
+ *
+ * @param minCapacity the desired minimum capacity
+ */
+ public void ensureCapacity(int minCapacity) {
+ if (minCapacity > 0)
+ ensureCapacityInternal(minCapacity);
+ }
+
+ private void ensureCapacityInternal(int minCapacity) {
+ modCount++;
+ // overflow-conscious code
+ if (minCapacity - elementData.length > 0)
+ grow(minCapacity);
+ }
+
+ /**
+ * 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 to ensure that it can hold at least the
+ * number of elements specified by the minimum capacity argument.
+ *
+ * @param minCapacity the desired minimum capacity
+ */
+ private void grow(int minCapacity) {
+ // overflow-conscious code
+ int oldCapacity = elementData.length;
+ int newCapacity = oldCapacity + (oldCapacity >> 1);
+ if (newCapacity - minCapacity < 0)
+ newCapacity = minCapacity;
+ if (newCapacity - MAX_ARRAY_SIZE > 0)
+ newCapacity = hugeCapacity(minCapacity);
+ // minCapacity is usually close to size, so this is a win:
+ elementData = Arrays.copyOf(elementData, 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;
+ }
+
+ /**
+ * Returns the number of elements in this list.
+ *
+ * @return the number of elements in this list
+ */
+ public int size() {
+ return size;
+ }
+
+ /**
+ * Returns true if this list contains no elements.
+ *
+ * @return true if this list contains no elements
+ */
+ public boolean isEmpty() {
+ return size == 0;
+ }
+
+ /**
+ * Returns true if this list contains the specified element.
+ * More formally, returns true if and only if this list contains
+ * at least one element e such that
+ * (o==null ? e==null : o.equals(e)).
+ *
+ * @param o element whose presence in this list is to be tested
+ * @return true if this list contains the specified element
+ */
+ public boolean contains(Object o) {
+ return indexOf(o) >= 0;
+ }
+
+ /**
+ * 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 i such that
+ * (o==null ? get(i)==null : o.equals(get(i))),
+ * or -1 if there is no such index.
+ */
+ public int indexOf(Object o) {
+ if (o == null) {
+ for (int i = 0; i < size; i++)
+ if (elementData[i]==null)
+ return i;
+ } else {
+ for (int i = 0; i < size; i++)
+ if (o.equals(elementData[i]))
+ return i;
+ }
+ return -1;
+ }
+
+ /**
+ * 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 i such that
+ * (o==null ? get(i)==null : o.equals(get(i))),
+ * or -1 if there is no such index.
+ */
+ public int lastIndexOf(Object o) {
+ if (o == null) {
+ for (int i = size-1; i >= 0; i--)
+ if (elementData[i]==null)
+ return i;
+ } else {
+ for (int i = size-1; i >= 0; i--)
+ if (o.equals(elementData[i]))
+ return i;
+ }
+ return -1;
+ }
+
+ /**
+ * Returns a shallow copy of this ArrayList instance. (The
+ * elements themselves are not copied.)
+ *
+ * @return a clone of this ArrayList instance
+ */
+ public Object clone() {
+ try {
+ @SuppressWarnings("unchecked")
+ ArrayList v = (ArrayList) super.clone();
+ v.elementData = Arrays.copyOf(elementData, size);
+ v.modCount = 0;
+ return v;
+ } catch (CloneNotSupportedException e) {
+ // this shouldn't happen, since we are Cloneable
+ throw new InternalError();
+ }
+ }
+
+ /**
+ * Returns an array containing all of the elements in this list
+ * in proper sequence (from first to last element).
+ *
+ *
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). The caller is thus free to modify the returned array.
+ *
+ *
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
+ */
+ public Object[] toArray() {
+ return Arrays.copyOf(elementData, size);
+ }
+
+ /**
+ * 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.
+ *
+ *
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 collection is set to
+ * null. (This is useful in determining the length of the
+ * list only if the caller knows that the list does not contain
+ * any null elements.)
+ *
+ * @param a the array into which the elements of the 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 the 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
+ */
+ @SuppressWarnings("unchecked")
+ public T[] toArray(T[] a) {
+ if (a.length < size)
+ // Make a new array of a's runtime type, but my contents:
+ return (T[]) Arrays.copyOf(elementData, size, a.getClass());
+ System.arraycopy(elementData, 0, a, 0, size);
+ if (a.length > size)
+ a[size] = null;
+ return a;
+ }
+
+ // Positional Access Operations
+
+ @SuppressWarnings("unchecked")
+ E elementData(int index) {
+ return (E) elementData[index];
+ }
+
+ /**
+ * 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 {@inheritDoc}
+ */
+ public E get(int index) {
+ rangeCheck(index);
+
+ return elementData(index);
+ }
+
+ /**
+ * Replaces the element at the specified position in this list with
+ * the specified element.
+ *
+ * @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 IndexOutOfBoundsException {@inheritDoc}
+ */
+ public E set(int index, E element) {
+ rangeCheck(index);
+
+ E oldValue = elementData(index);
+ elementData[index] = element;
+ return oldValue;
+ }
+
+ /**
+ * Appends the specified element to the end of this list.
+ *
+ * @param e element to be appended to this list
+ * @return true (as specified by {@link Collection#add})
+ */
+ public boolean add(E e) {
+ ensureCapacityInternal(size + 1); // Increments modCount!!
+ elementData[size++] = e;
+ return true;
+ }
+
+ /**
+ * Inserts the specified element at the specified position in this
+ * list. 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 IndexOutOfBoundsException {@inheritDoc}
+ */
+ public void add(int index, E element) {
+ rangeCheckForAdd(index);
+
+ ensureCapacityInternal(size + 1); // Increments modCount!!
+ System.arraycopy(elementData, index, elementData, index + 1,
+ size - index);
+ elementData[index] = element;
+ size++;
+ }
+
+ /**
+ * Removes the element at the specified position in this list.
+ * Shifts any subsequent elements to the left (subtracts one from their
+ * indices).
+ *
+ * @param index the index of the element to be removed
+ * @return the element that was removed from the list
+ * @throws IndexOutOfBoundsException {@inheritDoc}
+ */
+ public E remove(int index) {
+ rangeCheck(index);
+
+ modCount++;
+ E oldValue = elementData(index);
+
+ int numMoved = size - index - 1;
+ if (numMoved > 0)
+ System.arraycopy(elementData, index+1, elementData, index,
+ numMoved);
+ elementData[--size] = null; // Let gc do its work
+
+ return oldValue;
+ }
+
+ /**
+ * Removes the first occurrence of the specified element from this list,
+ * if it is present. If the list does not contain the element, it is
+ * unchanged. More formally, removes the element with the lowest index
+ * i such that
+ * (o==null ? get(i)==null : o.equals(get(i)))
+ * (if such an element exists). Returns true 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 true if this list contained the specified element
+ */
+ public boolean remove(Object o) {
+ if (o == null) {
+ for (int index = 0; index < size; index++)
+ if (elementData[index] == null) {
+ fastRemove(index);
+ return true;
+ }
+ } else {
+ for (int index = 0; index < size; index++)
+ if (o.equals(elementData[index])) {
+ fastRemove(index);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /*
+ * Private remove method that skips bounds checking and does not
+ * return the value removed.
+ */
+ private void fastRemove(int index) {
+ modCount++;
+ int numMoved = size - index - 1;
+ if (numMoved > 0)
+ System.arraycopy(elementData, index+1, elementData, index,
+ numMoved);
+ elementData[--size] = null; // Let gc do its work
+ }
+
+ /**
+ * Removes all of the elements from this list. The list will
+ * be empty after this call returns.
+ */
+ public void clear() {
+ modCount++;
+
+ // Let gc do its work
+ for (int i = 0; i < size; i++)
+ elementData[i] = null;
+
+ size = 0;
+ }
+
+ /**
+ * 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. 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 list, and this
+ * list is nonempty.)
+ *
+ * @param c collection containing elements to be added to this list
+ * @return true if this list changed as a result of the call
+ * @throws NullPointerException if the specified collection is null
+ */
+ public boolean addAll(Collection extends E> c) {
+ Object[] a = c.toArray();
+ int numNew = a.length;
+ ensureCapacityInternal(size + numNew); // Increments modCount
+ System.arraycopy(a, 0, elementData, size, numNew);
+ size += numNew;
+ return numNew != 0;
+ }
+
+ /**
+ * Inserts all of the elements in the specified collection into this
+ * list, starting at the specified position. 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 the list in the order that they are returned by the
+ * specified collection's iterator.
+ *
+ * @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 true if this list changed as a result of the call
+ * @throws IndexOutOfBoundsException {@inheritDoc}
+ * @throws NullPointerException if the specified collection is null
+ */
+ public boolean addAll(int index, Collection extends E> c) {
+ rangeCheckForAdd(index);
+
+ Object[] a = c.toArray();
+ int numNew = a.length;
+ ensureCapacityInternal(size + numNew); // Increments modCount
+
+ int numMoved = size - index;
+ if (numMoved > 0)
+ System.arraycopy(elementData, index, elementData, index + numNew,
+ numMoved);
+
+ System.arraycopy(a, 0, elementData, index, numNew);
+ size += numNew;
+ return numNew != 0;
+ }
+
+ /**
+ * 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.)
+ *
+ * @throws IndexOutOfBoundsException if {@code fromIndex} or
+ * {@code toIndex} is out of range
+ * ({@code fromIndex < 0 ||
+ * fromIndex >= size() ||
+ * toIndex > size() ||
+ * toIndex < fromIndex})
+ */
+ protected void removeRange(int fromIndex, int toIndex) {
+ modCount++;
+ int numMoved = size - toIndex;
+ System.arraycopy(elementData, toIndex, elementData, fromIndex,
+ numMoved);
+
+ // Let gc do its work
+ int newSize = size - (toIndex-fromIndex);
+ while (size != newSize)
+ elementData[--size] = null;
+ }
+
+ /**
+ * Checks if the given index is in range. If not, throws an appropriate
+ * runtime exception. This method does *not* check if the index is
+ * negative: It is always used immediately prior to an array access,
+ * which throws an ArrayIndexOutOfBoundsException if index is negative.
+ */
+ private void rangeCheck(int index) {
+ if (index >= size)
+ throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
+ }
+
+ /**
+ * A version of rangeCheck used by add and addAll.
+ */
+ private void rangeCheckForAdd(int index) {
+ if (index > size || index < 0)
+ throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
+ }
+
+ /**
+ * Constructs an IndexOutOfBoundsException detail message.
+ * Of the many possible refactorings of the error handling code,
+ * this "outlining" performs best with both server and client VMs.
+ */
+ private String outOfBoundsMsg(int index) {
+ return "Index: "+index+", Size: "+size;
+ }
+
+ /**
+ * Removes from this list all of its elements that are contained in the
+ * specified collection.
+ *
+ * @param c collection containing elements to be removed from this list
+ * @return {@code true} if this list changed as a result of the call
+ * @throws ClassCastException if the class of an element of this list
+ * is incompatible with the specified collection
+ * (optional)
+ * @throws NullPointerException if this list contains a null element and the
+ * specified collection does not permit null elements
+ * (optional),
+ * or if the specified collection is null
+ * @see Collection#contains(Object)
+ */
+ public boolean removeAll(Collection> c) {
+ return batchRemove(c, false);
+ }
+
+ /**
+ * Retains only the elements in this list that are contained in the
+ * specified collection. 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 {@code true} if this list changed as a result of the call
+ * @throws ClassCastException if the class of an element of this list
+ * is incompatible with the specified collection
+ * (optional)
+ * @throws NullPointerException if this list contains a null element and the
+ * specified collection does not permit null elements
+ * (optional),
+ * or if the specified collection is null
+ * @see Collection#contains(Object)
+ */
+ public boolean retainAll(Collection> c) {
+ return batchRemove(c, true);
+ }
+
+ private boolean batchRemove(Collection> c, boolean complement) {
+ final Object[] elementData = this.elementData;
+ int r = 0, w = 0;
+ boolean modified = false;
+ try {
+ for (; r < size; r++)
+ if (c.contains(elementData[r]) == complement)
+ elementData[w++] = elementData[r];
+ } finally {
+ // Preserve behavioral compatibility with AbstractCollection,
+ // even if c.contains() throws.
+ if (r != size) {
+ System.arraycopy(elementData, r,
+ elementData, w,
+ size - r);
+ w += size - r;
+ }
+ if (w != size) {
+ for (int i = w; i < size; i++)
+ elementData[i] = null;
+ modCount += size - w;
+ size = w;
+ modified = true;
+ }
+ }
+ return modified;
+ }
+
+ /**
+ * Save the state of the ArrayList instance to a stream (that
+ * is, serialize it).
+ *
+ * @serialData The length of the array backing the ArrayList
+ * instance is emitted (int), followed by all of its elements
+ * (each an Object) in the proper order.
+ */
+ private void writeObject(java.io.ObjectOutputStream s)
+ throws java.io.IOException{
+ // Write out element count, and any hidden stuff
+ int expectedModCount = modCount;
+ s.defaultWriteObject();
+
+ // Write out array length
+ s.writeInt(elementData.length);
+
+ // Write out all elements in the proper order.
+ for (int i=0; iArrayList instance from a stream (that is,
+ * deserialize it).
+ */
+ private void readObject(java.io.ObjectInputStream s)
+ throws java.io.IOException, ClassNotFoundException {
+ // Read in size, and any hidden stuff
+ s.defaultReadObject();
+
+ // Read in array length and allocate array
+ int arrayLength = s.readInt();
+ Object[] a = elementData = new Object[arrayLength];
+
+ // Read in all elements in the proper order.
+ for (int i=0; iThe returned list iterator is fail-fast.
+ *
+ * @throws IndexOutOfBoundsException {@inheritDoc}
+ */
+ public ListIterator listIterator(int index) {
+ if (index < 0 || index > size)
+ throw new IndexOutOfBoundsException("Index: "+index);
+ return new ListItr(index);
+ }
+
+ /**
+ * Returns a list iterator over the elements in this list (in proper
+ * sequence).
+ *
+ *
The returned list iterator is fail-fast.
+ *
+ * @see #listIterator(int)
+ */
+ public ListIterator listIterator() {
+ return new ListItr(0);
+ }
+
+ /**
+ * Returns an iterator over the elements in this list in proper sequence.
+ *
+ *
The returned iterator is fail-fast.
+ *
+ * @return an iterator over the elements in this list in proper sequence
+ */
+ public Iterator iterator() {
+ return new Itr();
+ }
+
+ /**
+ * An optimized version of AbstractList.Itr
+ */
+ private class Itr implements Iterator {
+ int cursor; // index of next element to return
+ int lastRet = -1; // index of last element returned; -1 if no such
+ int expectedModCount = modCount;
+
+ public boolean hasNext() {
+ return cursor != size;
+ }
+
+ @SuppressWarnings("unchecked")
+ public E next() {
+ checkForComodification();
+ int i = cursor;
+ if (i >= size)
+ throw new NoSuchElementException();
+ Object[] elementData = ArrayList.this.elementData;
+ if (i >= elementData.length)
+ throw new ConcurrentModificationException();
+ cursor = i + 1;
+ return (E) elementData[lastRet = i];
+ }
+
+ public void remove() {
+ if (lastRet < 0)
+ throw new IllegalStateException();
+ checkForComodification();
+
+ try {
+ ArrayList.this.remove(lastRet);
+ cursor = lastRet;
+ lastRet = -1;
+ expectedModCount = modCount;
+ } catch (IndexOutOfBoundsException ex) {
+ throw new ConcurrentModificationException();
+ }
+ }
+
+ final void checkForComodification() {
+ if (modCount != expectedModCount)
+ throw new ConcurrentModificationException();
+ }
+ }
+
+ /**
+ * An optimized version of AbstractList.ListItr
+ */
+ private class ListItr extends Itr implements ListIterator {
+ ListItr(int index) {
+ super();
+ cursor = index;
+ }
+
+ public boolean hasPrevious() {
+ return cursor != 0;
+ }
+
+ public int nextIndex() {
+ return cursor;
+ }
+
+ public int previousIndex() {
+ return cursor - 1;
+ }
+
+ @SuppressWarnings("unchecked")
+ public E previous() {
+ checkForComodification();
+ int i = cursor - 1;
+ if (i < 0)
+ throw new NoSuchElementException();
+ Object[] elementData = ArrayList.this.elementData;
+ if (i >= elementData.length)
+ throw new ConcurrentModificationException();
+ cursor = i;
+ return (E) elementData[lastRet = i];
+ }
+
+ public void set(E e) {
+ if (lastRet < 0)
+ throw new IllegalStateException();
+ checkForComodification();
+
+ try {
+ ArrayList.this.set(lastRet, e);
+ } catch (IndexOutOfBoundsException ex) {
+ throw new ConcurrentModificationException();
+ }
+ }
+
+ public void add(E e) {
+ checkForComodification();
+
+ try {
+ int i = cursor;
+ ArrayList.this.add(i, e);
+ cursor = i + 1;
+ lastRet = -1;
+ expectedModCount = modCount;
+ } catch (IndexOutOfBoundsException ex) {
+ throw new ConcurrentModificationException();
+ }
+ }
+ }
+
+ /**
+ * Returns a view of the portion of this list between the specified
+ * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive. (If
+ * {@code fromIndex} and {@code toIndex} 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.
+ *
+ *
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:
+ *
+ * list.subList(from, to).clear();
+ *
+ * Similar idioms may be constructed for {@link #indexOf(Object)} and
+ * {@link #lastIndexOf(Object)}, and all of the algorithms in the
+ * {@link Collections} class can be applied to a subList.
+ *
+ *
The semantics of the list returned by this method become undefined if
+ * the backing list (i.e., this list) is structurally modified 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.)
+ *
+ * @throws IndexOutOfBoundsException {@inheritDoc}
+ * @throws IllegalArgumentException {@inheritDoc}
+ */
+ public List subList(int fromIndex, int toIndex) {
+ subListRangeCheck(fromIndex, toIndex, size);
+ return new SubList(this, 0, fromIndex, toIndex);
+ }
+
+ static void subListRangeCheck(int fromIndex, int toIndex, int size) {
+ if (fromIndex < 0)
+ throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
+ if (toIndex > size)
+ throw new IndexOutOfBoundsException("toIndex = " + toIndex);
+ if (fromIndex > toIndex)
+ throw new IllegalArgumentException("fromIndex(" + fromIndex +
+ ") > toIndex(" + toIndex + ")");
+ }
+
+ private class SubList extends AbstractList implements RandomAccess {
+ private final AbstractList parent;
+ private final int parentOffset;
+ private final int offset;
+ int size;
+
+ SubList(AbstractList parent,
+ int offset, int fromIndex, int toIndex) {
+ this.parent = parent;
+ this.parentOffset = fromIndex;
+ this.offset = offset + fromIndex;
+ this.size = toIndex - fromIndex;
+ this.modCount = ArrayList.this.modCount;
+ }
+
+ public E set(int index, E e) {
+ rangeCheck(index);
+ checkForComodification();
+ E oldValue = ArrayList.this.elementData(offset + index);
+ ArrayList.this.elementData[offset + index] = e;
+ return oldValue;
+ }
+
+ public E get(int index) {
+ rangeCheck(index);
+ checkForComodification();
+ return ArrayList.this.elementData(offset + index);
+ }
+
+ public int size() {
+ checkForComodification();
+ return this.size;
+ }
+
+ public void add(int index, E e) {
+ rangeCheckForAdd(index);
+ checkForComodification();
+ parent.add(parentOffset + index, e);
+ this.modCount = parent.modCount;
+ this.size++;
+ }
+
+ public E remove(int index) {
+ rangeCheck(index);
+ checkForComodification();
+ E result = parent.remove(parentOffset + index);
+ this.modCount = parent.modCount;
+ this.size--;
+ return result;
+ }
+
+ protected void removeRange(int fromIndex, int toIndex) {
+ checkForComodification();
+ parent.removeRange(parentOffset + fromIndex,
+ parentOffset + toIndex);
+ this.modCount = parent.modCount;
+ this.size -= toIndex - fromIndex;
+ }
+
+ public boolean addAll(Collection extends E> c) {
+ return addAll(this.size, c);
+ }
+
+ public boolean addAll(int index, Collection extends E> c) {
+ rangeCheckForAdd(index);
+ int cSize = c.size();
+ if (cSize==0)
+ return false;
+
+ checkForComodification();
+ parent.addAll(parentOffset + index, c);
+ this.modCount = parent.modCount;
+ this.size += cSize;
+ return true;
+ }
+
+ public Iterator iterator() {
+ return listIterator();
+ }
+
+ public ListIterator listIterator(final int index) {
+ checkForComodification();
+ rangeCheckForAdd(index);
+ final int offset = this.offset;
+
+ return new ListIterator() {
+ int cursor = index;
+ int lastRet = -1;
+ int expectedModCount = ArrayList.this.modCount;
+
+ public boolean hasNext() {
+ return cursor != SubList.this.size;
+ }
+
+ @SuppressWarnings("unchecked")
+ public E next() {
+ checkForComodification();
+ int i = cursor;
+ if (i >= SubList.this.size)
+ throw new NoSuchElementException();
+ Object[] elementData = ArrayList.this.elementData;
+ if (offset + i >= elementData.length)
+ throw new ConcurrentModificationException();
+ cursor = i + 1;
+ return (E) elementData[offset + (lastRet = i)];
+ }
+
+ public boolean hasPrevious() {
+ return cursor != 0;
+ }
+
+ @SuppressWarnings("unchecked")
+ public E previous() {
+ checkForComodification();
+ int i = cursor - 1;
+ if (i < 0)
+ throw new NoSuchElementException();
+ Object[] elementData = ArrayList.this.elementData;
+ if (offset + i >= elementData.length)
+ throw new ConcurrentModificationException();
+ cursor = i;
+ return (E) elementData[offset + (lastRet = i)];
+ }
+
+ public int nextIndex() {
+ return cursor;
+ }
+
+ public int previousIndex() {
+ return cursor - 1;
+ }
+
+ public void remove() {
+ if (lastRet < 0)
+ throw new IllegalStateException();
+ checkForComodification();
+
+ try {
+ SubList.this.remove(lastRet);
+ cursor = lastRet;
+ lastRet = -1;
+ expectedModCount = ArrayList.this.modCount;
+ } catch (IndexOutOfBoundsException ex) {
+ throw new ConcurrentModificationException();
+ }
+ }
+
+ public void set(E e) {
+ if (lastRet < 0)
+ throw new IllegalStateException();
+ checkForComodification();
+
+ try {
+ ArrayList.this.set(offset + lastRet, e);
+ } catch (IndexOutOfBoundsException ex) {
+ throw new ConcurrentModificationException();
+ }
+ }
+
+ public void add(E e) {
+ checkForComodification();
+
+ try {
+ int i = cursor;
+ SubList.this.add(i, e);
+ cursor = i + 1;
+ lastRet = -1;
+ expectedModCount = ArrayList.this.modCount;
+ } catch (IndexOutOfBoundsException ex) {
+ throw new ConcurrentModificationException();
+ }
+ }
+
+ final void checkForComodification() {
+ if (expectedModCount != ArrayList.this.modCount)
+ throw new ConcurrentModificationException();
+ }
+ };
+ }
+
+ public List subList(int fromIndex, int toIndex) {
+ subListRangeCheck(fromIndex, toIndex, size);
+ return new SubList(this, offset, fromIndex, toIndex);
+ }
+
+ private void rangeCheck(int index) {
+ if (index < 0 || index >= this.size)
+ throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
+ }
+
+ private void rangeCheckForAdd(int index) {
+ if (index < 0 || index > this.size)
+ throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
+ }
+
+ private String outOfBoundsMsg(int index) {
+ return "Index: "+index+", Size: "+this.size;
+ }
+
+ private void checkForComodification() {
+ if (ArrayList.this.modCount != this.modCount)
+ throw new ConcurrentModificationException();
+ }
+ }
+}
diff -r 9c5f89ea4c1c -r df92e9608039 emul/compact/src/main/java/java/util/Arrays.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/emul/compact/src/main/java/java/util/Arrays.java Wed Jan 23 22:33:45 2013 +0100
@@ -0,0 +1,3673 @@
+/*
+ * 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;
+
+import java.lang.reflect.*;
+
+/**
+ * This class contains various methods for manipulating arrays (such as
+ * sorting and searching). This class also contains a static factory
+ * that allows arrays to be viewed as lists.
+ *
+ *
The methods in this class all throw a {@code NullPointerException},
+ * if the specified array reference is null, except where noted.
+ *
+ *
The documentation for the methods contained in this class includes
+ * briefs description of the implementations. Such descriptions should
+ * be regarded as implementation notes, rather than parts of the
+ * specification. Implementors should feel free to substitute other
+ * algorithms, so long as the specification itself is adhered to. (For
+ * example, the algorithm used by {@code sort(Object[])} does not have to be
+ * a MergeSort, but it does have to be stable.)
+ *
+ *
This class is a member of the
+ *
+ * Java Collections Framework.
+ *
+ * @author Josh Bloch
+ * @author Neal Gafter
+ * @author John Rose
+ * @since 1.2
+ */
+public class Arrays {
+
+ // Suppresses default constructor, ensuring non-instantiability.
+ private Arrays() {}
+
+ /*
+ * Sorting of primitive type arrays.
+ */
+
+ /**
+ * Sorts the specified array into ascending numerical order.
+ *
+ *
Implementation note: The sorting algorithm is a Dual-Pivot Quicksort
+ * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm
+ * offers O(n log(n)) performance on many data sets that cause other
+ * quicksorts to degrade to quadratic performance, and is typically
+ * faster than traditional (one-pivot) Quicksort implementations.
+ *
+ * @param a the array to be sorted
+ */
+ public static void sort(int[] a) {
+ DualPivotQuicksort.sort(a);
+ }
+
+ /**
+ * Sorts the specified range of the array into ascending order. The range
+ * to be sorted extends from the index {@code fromIndex}, inclusive, to
+ * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex},
+ * the range to be sorted is empty.
+ *
+ *
Implementation note: The sorting algorithm is a Dual-Pivot Quicksort
+ * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm
+ * offers O(n log(n)) performance on many data sets that cause other
+ * quicksorts to degrade to quadratic performance, and is typically
+ * faster than traditional (one-pivot) Quicksort implementations.
+ *
+ * @param a the array to be sorted
+ * @param fromIndex the index of the first element, inclusive, to be sorted
+ * @param toIndex the index of the last element, exclusive, to be sorted
+ *
+ * @throws IllegalArgumentException if {@code fromIndex > toIndex}
+ * @throws ArrayIndexOutOfBoundsException
+ * if {@code fromIndex < 0} or {@code toIndex > a.length}
+ */
+ public static void sort(int[] a, int fromIndex, int toIndex) {
+ rangeCheck(a.length, fromIndex, toIndex);
+ DualPivotQuicksort.sort(a, fromIndex, toIndex - 1);
+ }
+
+ /**
+ * Sorts the specified array into ascending numerical order.
+ *
+ *
Implementation note: The sorting algorithm is a Dual-Pivot Quicksort
+ * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm
+ * offers O(n log(n)) performance on many data sets that cause other
+ * quicksorts to degrade to quadratic performance, and is typically
+ * faster than traditional (one-pivot) Quicksort implementations.
+ *
+ * @param a the array to be sorted
+ */
+ public static void sort(long[] a) {
+ DualPivotQuicksort.sort(a);
+ }
+
+ /**
+ * Sorts the specified range of the array into ascending order. The range
+ * to be sorted extends from the index {@code fromIndex}, inclusive, to
+ * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex},
+ * the range to be sorted is empty.
+ *
+ *
Implementation note: The sorting algorithm is a Dual-Pivot Quicksort
+ * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm
+ * offers O(n log(n)) performance on many data sets that cause other
+ * quicksorts to degrade to quadratic performance, and is typically
+ * faster than traditional (one-pivot) Quicksort implementations.
+ *
+ * @param a the array to be sorted
+ * @param fromIndex the index of the first element, inclusive, to be sorted
+ * @param toIndex the index of the last element, exclusive, to be sorted
+ *
+ * @throws IllegalArgumentException if {@code fromIndex > toIndex}
+ * @throws ArrayIndexOutOfBoundsException
+ * if {@code fromIndex < 0} or {@code toIndex > a.length}
+ */
+ public static void sort(long[] a, int fromIndex, int toIndex) {
+ rangeCheck(a.length, fromIndex, toIndex);
+ DualPivotQuicksort.sort(a, fromIndex, toIndex - 1);
+ }
+
+ /**
+ * Sorts the specified array into ascending numerical order.
+ *
+ *
Implementation note: The sorting algorithm is a Dual-Pivot Quicksort
+ * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm
+ * offers O(n log(n)) performance on many data sets that cause other
+ * quicksorts to degrade to quadratic performance, and is typically
+ * faster than traditional (one-pivot) Quicksort implementations.
+ *
+ * @param a the array to be sorted
+ */
+ public static void sort(short[] a) {
+ DualPivotQuicksort.sort(a);
+ }
+
+ /**
+ * Sorts the specified range of the array into ascending order. The range
+ * to be sorted extends from the index {@code fromIndex}, inclusive, to
+ * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex},
+ * the range to be sorted is empty.
+ *
+ *
Implementation note: The sorting algorithm is a Dual-Pivot Quicksort
+ * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm
+ * offers O(n log(n)) performance on many data sets that cause other
+ * quicksorts to degrade to quadratic performance, and is typically
+ * faster than traditional (one-pivot) Quicksort implementations.
+ *
+ * @param a the array to be sorted
+ * @param fromIndex the index of the first element, inclusive, to be sorted
+ * @param toIndex the index of the last element, exclusive, to be sorted
+ *
+ * @throws IllegalArgumentException if {@code fromIndex > toIndex}
+ * @throws ArrayIndexOutOfBoundsException
+ * if {@code fromIndex < 0} or {@code toIndex > a.length}
+ */
+ public static void sort(short[] a, int fromIndex, int toIndex) {
+ rangeCheck(a.length, fromIndex, toIndex);
+ DualPivotQuicksort.sort(a, fromIndex, toIndex - 1);
+ }
+
+ /**
+ * Sorts the specified array into ascending numerical order.
+ *
+ *
Implementation note: The sorting algorithm is a Dual-Pivot Quicksort
+ * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm
+ * offers O(n log(n)) performance on many data sets that cause other
+ * quicksorts to degrade to quadratic performance, and is typically
+ * faster than traditional (one-pivot) Quicksort implementations.
+ *
+ * @param a the array to be sorted
+ */
+ public static void sort(char[] a) {
+ DualPivotQuicksort.sort(a);
+ }
+
+ /**
+ * Sorts the specified range of the array into ascending order. The range
+ * to be sorted extends from the index {@code fromIndex}, inclusive, to
+ * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex},
+ * the range to be sorted is empty.
+ *
+ *
Implementation note: The sorting algorithm is a Dual-Pivot Quicksort
+ * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm
+ * offers O(n log(n)) performance on many data sets that cause other
+ * quicksorts to degrade to quadratic performance, and is typically
+ * faster than traditional (one-pivot) Quicksort implementations.
+ *
+ * @param a the array to be sorted
+ * @param fromIndex the index of the first element, inclusive, to be sorted
+ * @param toIndex the index of the last element, exclusive, to be sorted
+ *
+ * @throws IllegalArgumentException if {@code fromIndex > toIndex}
+ * @throws ArrayIndexOutOfBoundsException
+ * if {@code fromIndex < 0} or {@code toIndex > a.length}
+ */
+ public static void sort(char[] a, int fromIndex, int toIndex) {
+ rangeCheck(a.length, fromIndex, toIndex);
+ DualPivotQuicksort.sort(a, fromIndex, toIndex - 1);
+ }
+
+ /**
+ * Sorts the specified array into ascending numerical order.
+ *
+ *
Implementation note: The sorting algorithm is a Dual-Pivot Quicksort
+ * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm
+ * offers O(n log(n)) performance on many data sets that cause other
+ * quicksorts to degrade to quadratic performance, and is typically
+ * faster than traditional (one-pivot) Quicksort implementations.
+ *
+ * @param a the array to be sorted
+ */
+ public static void sort(byte[] a) {
+ DualPivotQuicksort.sort(a);
+ }
+
+ /**
+ * Sorts the specified range of the array into ascending order. The range
+ * to be sorted extends from the index {@code fromIndex}, inclusive, to
+ * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex},
+ * the range to be sorted is empty.
+ *
+ *
Implementation note: The sorting algorithm is a Dual-Pivot Quicksort
+ * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm
+ * offers O(n log(n)) performance on many data sets that cause other
+ * quicksorts to degrade to quadratic performance, and is typically
+ * faster than traditional (one-pivot) Quicksort implementations.
+ *
+ * @param a the array to be sorted
+ * @param fromIndex the index of the first element, inclusive, to be sorted
+ * @param toIndex the index of the last element, exclusive, to be sorted
+ *
+ * @throws IllegalArgumentException if {@code fromIndex > toIndex}
+ * @throws ArrayIndexOutOfBoundsException
+ * if {@code fromIndex < 0} or {@code toIndex > a.length}
+ */
+ public static void sort(byte[] a, int fromIndex, int toIndex) {
+ rangeCheck(a.length, fromIndex, toIndex);
+ DualPivotQuicksort.sort(a, fromIndex, toIndex - 1);
+ }
+
+ /**
+ * Sorts the specified array into ascending numerical order.
+ *
+ *
The {@code <} relation does not provide a total order on all float
+ * values: {@code -0.0f == 0.0f} is {@code true} and a {@code Float.NaN}
+ * value compares neither less than, greater than, nor equal to any value,
+ * even itself. This method uses the total order imposed by the method
+ * {@link Float#compareTo}: {@code -0.0f} is treated as less than value
+ * {@code 0.0f} and {@code Float.NaN} is considered greater than any
+ * other value and all {@code Float.NaN} values are considered equal.
+ *
+ *
Implementation note: The sorting algorithm is a Dual-Pivot Quicksort
+ * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm
+ * offers O(n log(n)) performance on many data sets that cause other
+ * quicksorts to degrade to quadratic performance, and is typically
+ * faster than traditional (one-pivot) Quicksort implementations.
+ *
+ * @param a the array to be sorted
+ */
+ public static void sort(float[] a) {
+ DualPivotQuicksort.sort(a);
+ }
+
+ /**
+ * Sorts the specified range of the array into ascending order. The range
+ * to be sorted extends from the index {@code fromIndex}, inclusive, to
+ * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex},
+ * the range to be sorted is empty.
+ *
+ *
The {@code <} relation does not provide a total order on all float
+ * values: {@code -0.0f == 0.0f} is {@code true} and a {@code Float.NaN}
+ * value compares neither less than, greater than, nor equal to any value,
+ * even itself. This method uses the total order imposed by the method
+ * {@link Float#compareTo}: {@code -0.0f} is treated as less than value
+ * {@code 0.0f} and {@code Float.NaN} is considered greater than any
+ * other value and all {@code Float.NaN} values are considered equal.
+ *
+ *
Implementation note: The sorting algorithm is a Dual-Pivot Quicksort
+ * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm
+ * offers O(n log(n)) performance on many data sets that cause other
+ * quicksorts to degrade to quadratic performance, and is typically
+ * faster than traditional (one-pivot) Quicksort implementations.
+ *
+ * @param a the array to be sorted
+ * @param fromIndex the index of the first element, inclusive, to be sorted
+ * @param toIndex the index of the last element, exclusive, to be sorted
+ *
+ * @throws IllegalArgumentException if {@code fromIndex > toIndex}
+ * @throws ArrayIndexOutOfBoundsException
+ * if {@code fromIndex < 0} or {@code toIndex > a.length}
+ */
+ public static void sort(float[] a, int fromIndex, int toIndex) {
+ rangeCheck(a.length, fromIndex, toIndex);
+ DualPivotQuicksort.sort(a, fromIndex, toIndex - 1);
+ }
+
+ /**
+ * Sorts the specified array into ascending numerical order.
+ *
+ *
The {@code <} relation does not provide a total order on all double
+ * values: {@code -0.0d == 0.0d} is {@code true} and a {@code Double.NaN}
+ * value compares neither less than, greater than, nor equal to any value,
+ * even itself. This method uses the total order imposed by the method
+ * {@link Double#compareTo}: {@code -0.0d} is treated as less than value
+ * {@code 0.0d} and {@code Double.NaN} is considered greater than any
+ * other value and all {@code Double.NaN} values are considered equal.
+ *
+ *
Implementation note: The sorting algorithm is a Dual-Pivot Quicksort
+ * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm
+ * offers O(n log(n)) performance on many data sets that cause other
+ * quicksorts to degrade to quadratic performance, and is typically
+ * faster than traditional (one-pivot) Quicksort implementations.
+ *
+ * @param a the array to be sorted
+ */
+ public static void sort(double[] a) {
+ DualPivotQuicksort.sort(a);
+ }
+
+ /**
+ * Sorts the specified range of the array into ascending order. The range
+ * to be sorted extends from the index {@code fromIndex}, inclusive, to
+ * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex},
+ * the range to be sorted is empty.
+ *
+ *
The {@code <} relation does not provide a total order on all double
+ * values: {@code -0.0d == 0.0d} is {@code true} and a {@code Double.NaN}
+ * value compares neither less than, greater than, nor equal to any value,
+ * even itself. This method uses the total order imposed by the method
+ * {@link Double#compareTo}: {@code -0.0d} is treated as less than value
+ * {@code 0.0d} and {@code Double.NaN} is considered greater than any
+ * other value and all {@code Double.NaN} values are considered equal.
+ *
+ *
Implementation note: The sorting algorithm is a Dual-Pivot Quicksort
+ * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm
+ * offers O(n log(n)) performance on many data sets that cause other
+ * quicksorts to degrade to quadratic performance, and is typically
+ * faster than traditional (one-pivot) Quicksort implementations.
+ *
+ * @param a the array to be sorted
+ * @param fromIndex the index of the first element, inclusive, to be sorted
+ * @param toIndex the index of the last element, exclusive, to be sorted
+ *
+ * @throws IllegalArgumentException if {@code fromIndex > toIndex}
+ * @throws ArrayIndexOutOfBoundsException
+ * if {@code fromIndex < 0} or {@code toIndex > a.length}
+ */
+ public static void sort(double[] a, int fromIndex, int toIndex) {
+ rangeCheck(a.length, fromIndex, toIndex);
+ DualPivotQuicksort.sort(a, fromIndex, toIndex - 1);
+ }
+
+ /*
+ * Sorting of complex type arrays.
+ */
+
+ /**
+ * Old merge sort implementation can be selected (for
+ * compatibility with broken comparators) using a system property.
+ * Cannot be a static boolean in the enclosing class due to
+ * circular dependencies. To be removed in a future release.
+ */
+ static final class LegacyMergeSort {
+ private static final boolean userRequested =
+ java.security.AccessController.doPrivileged(
+ new sun.security.action.GetBooleanAction(
+ "java.util.Arrays.useLegacyMergeSort")).booleanValue();
+ }
+
+ /*
+ * If this platform has an optimizing VM, check whether ComparableTimSort
+ * offers any performance benefit over TimSort in conjunction with a
+ * comparator that returns:
+ * {@code ((Comparable)first).compareTo(Second)}.
+ * If not, you are better off deleting ComparableTimSort to
+ * eliminate the code duplication. In other words, the commented
+ * out code below is the preferable implementation for sorting
+ * arrays of Comparables if it offers sufficient performance.
+ */
+
+// /**
+// * A comparator that implements the natural ordering of a group of
+// * mutually comparable elements. Using this comparator saves us
+// * from duplicating most of the code in this file (one version for
+// * Comparables, one for explicit Comparators).
+// */
+// private static final Comparator