Showing the changes to java/pkg/java/util (990 of 18352 files). Show all
Unified · Split
Binary file not shown.
| @@ -0,0 +1,457 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package java.util; | ||
| 27 | |||
| 28 | /** | ||
| 29 | * This class provides a skeletal implementation of the <tt>Collection</tt> | ||
| 30 | * interface, to minimize the effort required to implement this interface. <p> | ||
| 31 | * | ||
| 32 | * To implement an unmodifiable collection, the programmer needs only to | ||
| 33 | * extend this class and provide implementations for the <tt>iterator</tt> and | ||
| 34 | * <tt>size</tt> methods. (The iterator returned by the <tt>iterator</tt> | ||
| 35 | * method must implement <tt>hasNext</tt> and <tt>next</tt>.)<p> | ||
| 36 | * | ||
| 37 | * To implement a modifiable collection, the programmer must additionally | ||
| 38 | * override this class's <tt>add</tt> method (which otherwise throws an | ||
| 39 | * <tt>UnsupportedOperationException</tt>), and the iterator returned by the | ||
| 40 | * <tt>iterator</tt> method must additionally implement its <tt>remove</tt> | ||
| 41 | * method.<p> | ||
| 42 | * | ||
| 43 | * The programmer should generally provide a void (no argument) and | ||
| 44 | * <tt>Collection</tt> constructor, as per the recommendation in the | ||
| 45 | * <tt>Collection</tt> interface specification.<p> | ||
| 46 | * | ||
| 47 | * The documentation for each non-abstract method in this class describes its | ||
| 48 | * implementation in detail. Each of these methods may be overridden if | ||
| 49 | * the collection being implemented admits a more efficient implementation.<p> | ||
| 50 | * | ||
| 51 | * This class is a member of the | ||
| 52 | * <a href="{@docRoot}/../technotes/guides/collections/index.html"> | ||
| 53 | * Java Collections Framework</a>. | ||
| 54 | * | ||
| 55 | * @author Josh Bloch | ||
| 56 | * @author Neal Gafter | ||
| 57 | * @see Collection | ||
| 58 | * @since 1.2 | ||
| 59 | */ | ||
| 60 | |||
| 61 | public abstract class AbstractCollection<E> implements Collection<E> { | ||
| 62 | /** | ||
| 63 | * Sole constructor. (For invocation by subclass constructors, typically | ||
| 64 | * implicit.) | ||
| 65 | */ | ||
| 66 | protected AbstractCollection() { | ||
| 67 | } | ||
| 68 | |||
| 69 | // Query Operations | ||
| 70 | |||
| 71 | /** | ||
| 72 | * Returns an iterator over the elements contained in this collection. | ||
| 73 | * | ||
| 74 | * @return an iterator over the elements contained in this collection | ||
| 75 | */ | ||
| 76 | public abstract Iterator<E> iterator(); | ||
| 77 | |||
| 78 | public abstract int size(); | ||
| 79 | |||
| 80 | /** | ||
| 81 | * {@inheritDoc} | ||
| 82 | * | ||
| 83 | * <p>This implementation returns <tt>size() == 0</tt>. | ||
| 84 | */ | ||
| 85 | public boolean isEmpty() { | ||
| 86 | return size() == 0; | ||
| 87 | } | ||
| 88 | |||
| 89 | /** | ||
| 90 | * {@inheritDoc} | ||
| 91 | * | ||
| 92 | * <p>This implementation iterates over the elements in the collection, | ||
| 93 | * checking each element in turn for equality with the specified element. | ||
| 94 | * | ||
| 95 | * @throws ClassCastException {@inheritDoc} | ||
| 96 | * @throws NullPointerException {@inheritDoc} | ||
| 97 | */ | ||
| 98 | public boolean contains(Object o) { | ||
| 99 | Iterator<E> it = iterator(); | ||
| 100 | if (o==null) { | ||
| 101 | while (it.hasNext()) | ||
| 102 | if (it.next()==null) | ||
| 103 | return true; | ||
| 104 | } else { | ||
| 105 | while (it.hasNext()) | ||
| 106 | if (o.equals(it.next())) | ||
| 107 | return true; | ||
| 108 | } | ||
| 109 | return false; | ||
| 110 | } | ||
| 111 | |||
| 112 | /** | ||
| 113 | * {@inheritDoc} | ||
| 114 | * | ||
| 115 | * <p>This implementation returns an array containing all the elements | ||
| 116 | * returned by this collection's iterator, in the same order, stored in | ||
| 117 | * consecutive elements of the array, starting with index {@code 0}. | ||
| 118 | * The length of the returned array is equal to the number of elements | ||
| 119 | * returned by the iterator, even if the size of this collection changes | ||
| 120 | * during iteration, as might happen if the collection permits | ||
| 121 | * concurrent modification during iteration. The {@code size} method is | ||
| 122 | * called only as an optimization hint; the correct result is returned | ||
| 123 | * even if the iterator returns a different number of elements. | ||
| 124 | * | ||
| 125 | * <p>This method is equivalent to: | ||
| 126 | * | ||
| 127 | * <pre> {@code | ||
| 128 | * List<E> list = new ArrayList<E>(size()); | ||
| 129 | * for (E e : this) | ||
| 130 | * list.add(e); | ||
| 131 | * return list.toArray(); | ||
| 132 | * }</pre> | ||
| 133 | */ | ||
| 134 | public Object[] toArray() { | ||
| 135 | // Estimate size of array; be prepared to see more or fewer elements | ||
| 136 | Object[] r = new Object[size()]; | ||
| 137 | Iterator<E> it = iterator(); | ||
| 138 | for (int i = 0; i < r.length; i++) { | ||
| 139 | if (! it.hasNext()) // fewer elements than expected | ||
| 140 | return Arrays.copyOf(r, i); | ||
| 141 | r[i] = it.next(); | ||
| 142 | } | ||
| 143 | return it.hasNext() ? finishToArray(r, it) : r; | ||
| 144 | } | ||
| 145 | |||
| 146 | /** | ||
| 147 | * {@inheritDoc} | ||
| 148 | * | ||
| 149 | * <p>This implementation returns an array containing all the elements | ||
| 150 | * returned by this collection's iterator in the same order, stored in | ||
| 151 | * consecutive elements of the array, starting with index {@code 0}. | ||
| 152 | * If the number of elements returned by the iterator is too large to | ||
| 153 | * fit into the specified array, then the elements are returned in a | ||
| 154 | * newly allocated array with length equal to the number of elements | ||
| 155 | * returned by the iterator, even if the size of this collection | ||
| 156 | * changes during iteration, as might happen if the collection permits | ||
| 157 | * concurrent modification during iteration. The {@code size} method is | ||
| 158 | * called only as an optimization hint; the correct result is returned | ||
| 159 | * even if the iterator returns a different number of elements. | ||
| 160 | * | ||
| 161 | * <p>This method is equivalent to: | ||
| 162 | * | ||
| 163 | * <pre> {@code | ||
| 164 | * List<E> list = new ArrayList<E>(size()); | ||
| 165 | * for (E e : this) | ||
| 166 | * list.add(e); | ||
| 167 | * return list.toArray(a); | ||
| 168 | * }</pre> | ||
| 169 | * | ||
| 170 | * @throws ArrayStoreException {@inheritDoc} | ||
| 171 | * @throws NullPointerException {@inheritDoc} | ||
| 172 | */ | ||
| 173 | public <T> T[] toArray(T[] a) { | ||
| 174 | // Estimate size of array; be prepared to see more or fewer elements | ||
| 175 | int size = size(); | ||
| 176 | T[] r = a.length >= size ? a : | ||
| 177 | (T[])java.lang.reflect.Array | ||
| 178 | .newInstance(a.getClass().getComponentType(), size); | ||
| 179 | Iterator<E> it = iterator(); | ||
| 180 | |||
| 181 | for (int i = 0; i < r.length; i++) { | ||
| 182 | if (! it.hasNext()) { // fewer elements than expected | ||
| 183 | if (a != r) | ||
| 184 | return Arrays.copyOf(r, i); | ||
| 185 | r[i] = null; // null-terminate | ||
| 186 | return r; | ||
| 187 | } | ||
| 188 | r[i] = (T)it.next(); | ||
| 189 | } | ||
| 190 | return it.hasNext() ? finishToArray(r, it) : r; | ||
| 191 | } | ||
| 192 | |||
| 193 | /** | ||
| 194 | * The maximum size of array to allocate. | ||
| 195 | * Some VMs reserve some header words in an array. | ||
| 196 | * Attempts to allocate larger arrays may result in | ||
| 197 | * OutOfMemoryError: Requested array size exceeds VM limit | ||
| 198 | */ | ||
| 199 | private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; | ||
| 200 | |||
| 201 | /** | ||
| 202 | * Reallocates the array being used within toArray when the iterator | ||
| 203 | * returned more elements than expected, and finishes filling it from | ||
| 204 | * the iterator. | ||
| 205 | * | ||
| 206 | * @param r the array, replete with previously stored elements | ||
| 207 | * @param it the in-progress iterator over this collection | ||
| 208 | * @return array containing the elements in the given array, plus any | ||
| 209 | * further elements returned by the iterator, trimmed to size | ||
| 210 | */ | ||
| 211 | private static <T> T[] finishToArray(T[] r, Iterator<?> it) { | ||
| 212 | int i = r.length; | ||
| 213 | while (it.hasNext()) { | ||
| 214 | int cap = r.length; | ||
| 215 | if (i == cap) { | ||
| 216 | int newCap = cap + (cap >> 1) + 1; | ||
| 217 | // overflow-conscious code | ||
| 218 | if (newCap - MAX_ARRAY_SIZE > 0) | ||
| 219 | newCap = hugeCapacity(cap + 1); | ||
| 220 | r = Arrays.copyOf(r, newCap); | ||
| 221 | } | ||
| 222 | r[i++] = (T)it.next(); | ||
| 223 | } | ||
| 224 | // trim if overallocated | ||
| 225 | return (i == r.length) ? r : Arrays.copyOf(r, i); | ||
| 226 | } | ||
| 227 | |||
| 228 | private static int hugeCapacity(int minCapacity) { | ||
| 229 | if (minCapacity < 0) // overflow | ||
| 230 | throw new OutOfMemoryError | ||
| 231 | ("Required array size too large"); | ||
| 232 | return (minCapacity > MAX_ARRAY_SIZE) ? | ||
| 233 | Integer.MAX_VALUE : | ||
| 234 | MAX_ARRAY_SIZE; | ||
| 235 | } | ||
| 236 | |||
| 237 | // Modification Operations | ||
| 238 | |||
| 239 | /** | ||
| 240 | * {@inheritDoc} | ||
| 241 | * | ||
| 242 | * <p>This implementation always throws an | ||
| 243 | * <tt>UnsupportedOperationException</tt>. | ||
| 244 | * | ||
| 245 | * @throws UnsupportedOperationException {@inheritDoc} | ||
| 246 | * @throws ClassCastException {@inheritDoc} | ||
| 247 | * @throws NullPointerException {@inheritDoc} | ||
| 248 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 249 | * @throws IllegalStateException {@inheritDoc} | ||
| 250 | */ | ||
| 251 | public boolean add(E e) { | ||
| 252 | throw new UnsupportedOperationException(); | ||
| 253 | } | ||
| 254 | |||
| 255 | /** | ||
| 256 | * {@inheritDoc} | ||
| 257 | * | ||
| 258 | * <p>This implementation iterates over the collection looking for the | ||
| 259 | * specified element. If it finds the element, it removes the element | ||
| 260 | * from the collection using the iterator's remove method. | ||
| 261 | * | ||
| 262 | * <p>Note that this implementation throws an | ||
| 263 | * <tt>UnsupportedOperationException</tt> if the iterator returned by this | ||
| 264 | * collection's iterator method does not implement the <tt>remove</tt> | ||
| 265 | * method and this collection contains the specified object. | ||
| 266 | * | ||
| 267 | * @throws UnsupportedOperationException {@inheritDoc} | ||
| 268 | * @throws ClassCastException {@inheritDoc} | ||
| 269 | * @throws NullPointerException {@inheritDoc} | ||
| 270 | */ | ||
| 271 | public boolean remove(Object o) { | ||
| 272 | Iterator<E> it = iterator(); | ||
| 273 | if (o==null) { | ||
| 274 | while (it.hasNext()) { | ||
| 275 | if (it.next()==null) { | ||
| 276 | it.remove(); | ||
| 277 | return true; | ||
| 278 | } | ||
| 279 | } | ||
| 280 | } else { | ||
| 281 | while (it.hasNext()) { | ||
| 282 | if (o.equals(it.next())) { | ||
| 283 | it.remove(); | ||
| 284 | return true; | ||
| 285 | } | ||
| 286 | } | ||
| 287 | } | ||
| 288 | return false; | ||
| 289 | } | ||
| 290 | |||
| 291 | |||
| 292 | // Bulk Operations | ||
| 293 | |||
| 294 | /** | ||
| 295 | * {@inheritDoc} | ||
| 296 | * | ||
| 297 | * <p>This implementation iterates over the specified collection, | ||
| 298 | * checking each element returned by the iterator in turn to see | ||
| 299 | * if it's contained in this collection. If all elements are so | ||
| 300 | * contained <tt>true</tt> is returned, otherwise <tt>false</tt>. | ||
| 301 | * | ||
| 302 | * @throws ClassCastException {@inheritDoc} | ||
| 303 | * @throws NullPointerException {@inheritDoc} | ||
| 304 | * @see #contains(Object) | ||
| 305 | */ | ||
| 306 | public boolean containsAll(Collection<?> c) { | ||
| 307 | for (Object e : c) | ||
| 308 | if (!contains(e)) | ||
| 309 | return false; | ||
| 310 | return true; | ||
| 311 | } | ||
| 312 | |||
| 313 | /** | ||
| 314 | * {@inheritDoc} | ||
| 315 | * | ||
| 316 | * <p>This implementation iterates over the specified collection, and adds | ||
| 317 | * each object returned by the iterator to this collection, in turn. | ||
| 318 | * | ||
| 319 | * <p>Note that this implementation will throw an | ||
| 320 | * <tt>UnsupportedOperationException</tt> unless <tt>add</tt> is | ||
| 321 | * overridden (assuming the specified collection is non-empty). | ||
| 322 | * | ||
| 323 | * @throws UnsupportedOperationException {@inheritDoc} | ||
| 324 | * @throws ClassCastException {@inheritDoc} | ||
| 325 | * @throws NullPointerException {@inheritDoc} | ||
| 326 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 327 | * @throws IllegalStateException {@inheritDoc} | ||
| 328 | * | ||
| 329 | * @see #add(Object) | ||
| 330 | */ | ||
| 331 | public boolean addAll(Collection<? extends E> c) { | ||
| 332 | boolean modified = false; | ||
| 333 | for (E e : c) | ||
| 334 | if (add(e)) | ||
| 335 | modified = true; | ||
| 336 | return modified; | ||
| 337 | } | ||
| 338 | |||
| 339 | /** | ||
| 340 | * {@inheritDoc} | ||
| 341 | * | ||
| 342 | * <p>This implementation iterates over this collection, checking each | ||
| 343 | * element returned by the iterator in turn to see if it's contained | ||
| 344 | * in the specified collection. If it's so contained, it's removed from | ||
| 345 | * this collection with the iterator's <tt>remove</tt> method. | ||
| 346 | * | ||
| 347 | * <p>Note that this implementation will throw an | ||
| 348 | * <tt>UnsupportedOperationException</tt> if the iterator returned by the | ||
| 349 | * <tt>iterator</tt> method does not implement the <tt>remove</tt> method | ||
| 350 | * and this collection contains one or more elements in common with the | ||
| 351 | * specified collection. | ||
| 352 | * | ||
| 353 | * @throws UnsupportedOperationException {@inheritDoc} | ||
| 354 | * @throws ClassCastException {@inheritDoc} | ||
| 355 | * @throws NullPointerException {@inheritDoc} | ||
| 356 | * | ||
| 357 | * @see #remove(Object) | ||
| 358 | * @see #contains(Object) | ||
| 359 | */ | ||
| 360 | public boolean removeAll(Collection<?> c) { | ||
| 361 | boolean modified = false; | ||
| 362 | Iterator<?> it = iterator(); | ||
| 363 | while (it.hasNext()) { | ||
| 364 | if (c.contains(it.next())) { | ||
| 365 | it.remove(); | ||
| 366 | modified = true; | ||
| 367 | } | ||
| 368 | } | ||
| 369 | return modified; | ||
| 370 | } | ||
| 371 | |||
| 372 | /** | ||
| 373 | * {@inheritDoc} | ||
| 374 | * | ||
| 375 | * <p>This implementation iterates over this collection, checking each | ||
| 376 | * element returned by the iterator in turn to see if it's contained | ||
| 377 | * in the specified collection. If it's not so contained, it's removed | ||
| 378 | * from this collection with the iterator's <tt>remove</tt> method. | ||
| 379 | * | ||
| 380 | * <p>Note that this implementation will throw an | ||
| 381 | * <tt>UnsupportedOperationException</tt> if the iterator returned by the | ||
| 382 | * <tt>iterator</tt> method does not implement the <tt>remove</tt> method | ||
| 383 | * and this collection contains one or more elements not present in the | ||
| 384 | * specified collection. | ||
| 385 | * | ||
| 386 | * @throws UnsupportedOperationException {@inheritDoc} | ||
| 387 | * @throws ClassCastException {@inheritDoc} | ||
| 388 | * @throws NullPointerException {@inheritDoc} | ||
| 389 | * | ||
| 390 | * @see #remove(Object) | ||
| 391 | * @see #contains(Object) | ||
| 392 | */ | ||
| 393 | public boolean retainAll(Collection<?> c) { | ||
| 394 | boolean modified = false; | ||
| 395 | Iterator<E> it = iterator(); | ||
| 396 | while (it.hasNext()) { | ||
| 397 | if (!c.contains(it.next())) { | ||
| 398 | it.remove(); | ||
| 399 | modified = true; | ||
| 400 | } | ||
| 401 | } | ||
| 402 | return modified; | ||
| 403 | } | ||
| 404 | |||
| 405 | /** | ||
| 406 | * {@inheritDoc} | ||
| 407 | * | ||
| 408 | * <p>This implementation iterates over this collection, removing each | ||
| 409 | * element using the <tt>Iterator.remove</tt> operation. Most | ||
| 410 | * implementations will probably choose to override this method for | ||
| 411 | * efficiency. | ||
| 412 | * | ||
| 413 | * <p>Note that this implementation will throw an | ||
| 414 | * <tt>UnsupportedOperationException</tt> if the iterator returned by this | ||
| 415 | * collection's <tt>iterator</tt> method does not implement the | ||
| 416 | * <tt>remove</tt> method and this collection is non-empty. | ||
| 417 | * | ||
| 418 | * @throws UnsupportedOperationException {@inheritDoc} | ||
| 419 | */ | ||
| 420 | public void clear() { | ||
| 421 | Iterator<E> it = iterator(); | ||
| 422 | while (it.hasNext()) { | ||
| 423 | it.next(); | ||
| 424 | it.remove(); | ||
| 425 | } | ||
| 426 | } | ||
| 427 | |||
| 428 | |||
| 429 | // String conversion | ||
| 430 | |||
| 431 | /** | ||
| 432 | * Returns a string representation of this collection. The string | ||
| 433 | * representation consists of a list of the collection's elements in the | ||
| 434 | * order they are returned by its iterator, enclosed in square brackets | ||
| 435 | * (<tt>"[]"</tt>). Adjacent elements are separated by the characters | ||
| 436 | * <tt>", "</tt> (comma and space). Elements are converted to strings as | ||
| 437 | * by {@link String#valueOf(Object)}. | ||
| 438 | * | ||
| 439 | * @return a string representation of this collection | ||
| 440 | */ | ||
| 441 | public String toString() { | ||
| 442 | Iterator<E> it = iterator(); | ||
| 443 | if (! it.hasNext()) | ||
| 444 | return "[]"; | ||
| 445 | |||
| 446 | StringBuilder sb = new StringBuilder(); | ||
| 447 | sb.append('['); | ||
| 448 | for (;;) { | ||
| 449 | E e = it.next(); | ||
| 450 | sb.append(e == this ? "(this Collection)" : e); | ||
| 451 | if (! it.hasNext()) | ||
| 452 | return sb.append(']').toString(); | ||
| 453 | sb.append(',').append(' '); | ||
| 454 | } | ||
| 455 | } | ||
| 456 | |||
| 457 | } | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,781 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package java.util; | ||
| 27 | |||
| 28 | /** | ||
| 29 | * This class provides a skeletal implementation of the {@link List} | ||
| 30 | * interface to minimize the effort required to implement this interface | ||
| 31 | * backed by a "random access" data store (such as an array). For sequential | ||
| 32 | * access data (such as a linked list), {@link AbstractSequentialList} should | ||
| 33 | * be used in preference to this class. | ||
| 34 | * | ||
| 35 | * <p>To implement an unmodifiable list, the programmer needs only to extend | ||
| 36 | * this class and provide implementations for the {@link #get(int)} and | ||
| 37 | * {@link List#size() size()} methods. | ||
| 38 | * | ||
| 39 | * <p>To implement a modifiable list, the programmer must additionally | ||
| 40 | * override the {@link #set(int, Object) set(int, E)} method (which otherwise | ||
| 41 | * throws an {@code UnsupportedOperationException}). If the list is | ||
| 42 | * variable-size the programmer must additionally override the | ||
| 43 | * {@link #add(int, Object) add(int, E)} and {@link #remove(int)} methods. | ||
| 44 | * | ||
| 45 | * <p>The programmer should generally provide a void (no argument) and collection | ||
| 46 | * constructor, as per the recommendation in the {@link Collection} interface | ||
| 47 | * specification. | ||
| 48 | * | ||
| 49 | * <p>Unlike the other abstract collection implementations, the programmer does | ||
| 50 | * <i>not</i> have to provide an iterator implementation; the iterator and | ||
| 51 | * list iterator are implemented by this class, on top of the "random access" | ||
| 52 | * methods: | ||
| 53 | * {@link #get(int)}, | ||
| 54 | * {@link #set(int, Object) set(int, E)}, | ||
| 55 | * {@link #add(int, Object) add(int, E)} and | ||
| 56 | * {@link #remove(int)}. | ||
| 57 | * | ||
| 58 | * <p>The documentation for each non-abstract method in this class describes its | ||
| 59 | * implementation in detail. Each of these methods may be overridden if the | ||
| 60 | * collection being implemented admits a more efficient implementation. | ||
| 61 | * | ||
| 62 | * <p>This class is a member of the | ||
| 63 | * <a href="{@docRoot}/../technotes/guides/collections/index.html"> | ||
| 64 | * Java Collections Framework</a>. | ||
| 65 | * | ||
| 66 | * @author Josh Bloch | ||
| 67 | * @author Neal Gafter | ||
| 68 | * @since 1.2 | ||
| 69 | */ | ||
| 70 | |||
| 71 | public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> { | ||
| 72 | /** | ||
| 73 | * Sole constructor. (For invocation by subclass constructors, typically | ||
| 74 | * implicit.) | ||
| 75 | */ | ||
| 76 | protected AbstractList() { | ||
| 77 | } | ||
| 78 | |||
| 79 | /** | ||
| 80 | * Appends the specified element to the end of this list (optional | ||
| 81 | * operation). | ||
| 82 | * | ||
| 83 | * <p>Lists that support this operation may place limitations on what | ||
| 84 | * elements may be added to this list. In particular, some | ||
| 85 | * lists will refuse to add null elements, and others will impose | ||
| 86 | * restrictions on the type of elements that may be added. List | ||
| 87 | * classes should clearly specify in their documentation any restrictions | ||
| 88 | * on what elements may be added. | ||
| 89 | * | ||
| 90 | * <p>This implementation calls {@code add(size(), e)}. | ||
| 91 | * | ||
| 92 | * <p>Note that this implementation throws an | ||
| 93 | * {@code UnsupportedOperationException} unless | ||
| 94 | * {@link #add(int, Object) add(int, E)} is overridden. | ||
| 95 | * | ||
| 96 | * @param e element to be appended to this list | ||
| 97 | * @return {@code true} (as specified by {@link Collection#add}) | ||
| 98 | * @throws UnsupportedOperationException if the {@code add} operation | ||
| 99 | * is not supported by this list | ||
| 100 | * @throws ClassCastException if the class of the specified element | ||
| 101 | * prevents it from being added to this list | ||
| 102 | * @throws NullPointerException if the specified element is null and this | ||
| 103 | * list does not permit null elements | ||
| 104 | * @throws IllegalArgumentException if some property of this element | ||
| 105 | * prevents it from being added to this list | ||
| 106 | */ | ||
| 107 | public boolean add(E e) { | ||
| 108 | add(size(), e); | ||
| 109 | return true; | ||
| 110 | } | ||
| 111 | |||
| 112 | /** | ||
| 113 | * {@inheritDoc} | ||
| 114 | * | ||
| 115 | * @throws IndexOutOfBoundsException {@inheritDoc} | ||
| 116 | */ | ||
| 117 | abstract public E get(int index); | ||
| 118 | |||
| 119 | /** | ||
| 120 | * {@inheritDoc} | ||
| 121 | * | ||
| 122 | * <p>This implementation always throws an | ||
| 123 | * {@code UnsupportedOperationException}. | ||
| 124 | * | ||
| 125 | * @throws UnsupportedOperationException {@inheritDoc} | ||
| 126 | * @throws ClassCastException {@inheritDoc} | ||
| 127 | * @throws NullPointerException {@inheritDoc} | ||
| 128 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 129 | * @throws IndexOutOfBoundsException {@inheritDoc} | ||
| 130 | */ | ||
| 131 | public E set(int index, E element) { | ||
| 132 | throw new UnsupportedOperationException(); | ||
| 133 | } | ||
| 134 | |||
| 135 | /** | ||
| 136 | * {@inheritDoc} | ||
| 137 | * | ||
| 138 | * <p>This implementation always throws an | ||
| 139 | * {@code UnsupportedOperationException}. | ||
| 140 | * | ||
| 141 | * @throws UnsupportedOperationException {@inheritDoc} | ||
| 142 | * @throws ClassCastException {@inheritDoc} | ||
| 143 | * @throws NullPointerException {@inheritDoc} | ||
| 144 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 145 | * @throws IndexOutOfBoundsException {@inheritDoc} | ||
| 146 | */ | ||
| 147 | public void add(int index, E element) { | ||
| 148 | throw new UnsupportedOperationException(); | ||
| 149 | } | ||
| 150 | |||
| 151 | /** | ||
| 152 | * {@inheritDoc} | ||
| 153 | * | ||
| 154 | * <p>This implementation always throws an | ||
| 155 | * {@code UnsupportedOperationException}. | ||
| 156 | * | ||
| 157 | * @throws UnsupportedOperationException {@inheritDoc} | ||
| 158 | * @throws IndexOutOfBoundsException {@inheritDoc} | ||
| 159 | */ | ||
| 160 | public E remove(int index) { | ||
| 161 | throw new UnsupportedOperationException(); | ||
| 162 | } | ||
| 163 | |||
| 164 | |||
| 165 | // Search Operations | ||
| 166 | |||
| 167 | /** | ||
| 168 | * {@inheritDoc} | ||
| 169 | * | ||
| 170 | * <p>This implementation first gets a list iterator (with | ||
| 171 | * {@code listIterator()}). Then, it iterates over the list until the | ||
| 172 | * specified element is found or the end of the list is reached. | ||
| 173 | * | ||
| 174 | * @throws ClassCastException {@inheritDoc} | ||
| 175 | * @throws NullPointerException {@inheritDoc} | ||
| 176 | */ | ||
| 177 | public int indexOf(Object o) { | ||
| 178 | ListIterator<E> it = listIterator(); | ||
| 179 | if (o==null) { | ||
| 180 | while (it.hasNext()) | ||
| 181 | if (it.next()==null) | ||
| 182 | return it.previousIndex(); | ||
| 183 | } else { | ||
| 184 | while (it.hasNext()) | ||
| 185 | if (o.equals(it.next())) | ||
| 186 | return it.previousIndex(); | ||
| 187 | } | ||
| 188 | return -1; | ||
| 189 | } | ||
| 190 | |||
| 191 | /** | ||
| 192 | * {@inheritDoc} | ||
| 193 | * | ||
| 194 | * <p>This implementation first gets a list iterator that points to the end | ||
| 195 | * of the list (with {@code listIterator(size())}). Then, it iterates | ||
| 196 | * backwards over the list until the specified element is found, or the | ||
| 197 | * beginning of the list is reached. | ||
| 198 | * | ||
| 199 | * @throws ClassCastException {@inheritDoc} | ||
| 200 | * @throws NullPointerException {@inheritDoc} | ||
| 201 | */ | ||
| 202 | public int lastIndexOf(Object o) { | ||
| 203 | ListIterator<E> it = listIterator(size()); | ||
| 204 | if (o==null) { | ||
| 205 | while (it.hasPrevious()) | ||
| 206 | if (it.previous()==null) | ||
| 207 | return it.nextIndex(); | ||
| 208 | } else { | ||
| 209 | while (it.hasPrevious()) | ||
| 210 | if (o.equals(it.previous())) | ||
| 211 | return it.nextIndex(); | ||
| 212 | } | ||
| 213 | return -1; | ||
| 214 | } | ||
| 215 | |||
| 216 | |||
| 217 | // Bulk Operations | ||
| 218 | |||
| 219 | /** | ||
| 220 | * Removes all of the elements from this list (optional operation). | ||
| 221 | * The list will be empty after this call returns. | ||
| 222 | * | ||
| 223 | * <p>This implementation calls {@code removeRange(0, size())}. | ||
| 224 | * | ||
| 225 | * <p>Note that this implementation throws an | ||
| 226 | * {@code UnsupportedOperationException} unless {@code remove(int | ||
| 227 | * index)} or {@code removeRange(int fromIndex, int toIndex)} is | ||
| 228 | * overridden. | ||
| 229 | * | ||
| 230 | * @throws UnsupportedOperationException if the {@code clear} operation | ||
| 231 | * is not supported by this list | ||
| 232 | */ | ||
| 233 | public void clear() { | ||
| 234 | removeRange(0, size()); | ||
| 235 | } | ||
| 236 | |||
| 237 | /** | ||
| 238 | * {@inheritDoc} | ||
| 239 | * | ||
| 240 | * <p>This implementation gets an iterator over the specified collection | ||
| 241 | * and iterates over it, inserting the elements obtained from the | ||
| 242 | * iterator into this list at the appropriate position, one at a time, | ||
| 243 | * using {@code add(int, E)}. | ||
| 244 | * Many implementations will override this method for efficiency. | ||
| 245 | * | ||
| 246 | * <p>Note that this implementation throws an | ||
| 247 | * {@code UnsupportedOperationException} unless | ||
| 248 | * {@link #add(int, Object) add(int, E)} is overridden. | ||
| 249 | * | ||
| 250 | * @throws UnsupportedOperationException {@inheritDoc} | ||
| 251 | * @throws ClassCastException {@inheritDoc} | ||
| 252 | * @throws NullPointerException {@inheritDoc} | ||
| 253 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 254 | * @throws IndexOutOfBoundsException {@inheritDoc} | ||
| 255 | */ | ||
| 256 | public boolean addAll(int index, Collection<? extends E> c) { | ||
| 257 | rangeCheckForAdd(index); | ||
| 258 | boolean modified = false; | ||
| 259 | for (E e : c) { | ||
| 260 | add(index++, e); | ||
| 261 | modified = true; | ||
| 262 | } | ||
| 263 | return modified; | ||
| 264 | } | ||
| 265 | |||
| 266 | |||
| 267 | // Iterators | ||
| 268 | |||
| 269 | /** | ||
| 270 | * Returns an iterator over the elements in this list in proper sequence. | ||
| 271 | * | ||
| 272 | * <p>This implementation returns a straightforward implementation of the | ||
| 273 | * iterator interface, relying on the backing list's {@code size()}, | ||
| 274 | * {@code get(int)}, and {@code remove(int)} methods. | ||
| 275 | * | ||
| 276 | * <p>Note that the iterator returned by this method will throw an | ||
| 277 | * {@link UnsupportedOperationException} in response to its | ||
| 278 | * {@code remove} method unless the list's {@code remove(int)} method is | ||
| 279 | * overridden. | ||
| 280 | * | ||
| 281 | * <p>This implementation can be made to throw runtime exceptions in the | ||
| 282 | * face of concurrent modification, as described in the specification | ||
| 283 | * for the (protected) {@link #modCount} field. | ||
| 284 | * | ||
| 285 | * @return an iterator over the elements in this list in proper sequence | ||
| 286 | */ | ||
| 287 | public Iterator<E> iterator() { | ||
| 288 | return new Itr(); | ||
| 289 | } | ||
| 290 | |||
| 291 | /** | ||
| 292 | * {@inheritDoc} | ||
| 293 | * | ||
| 294 | * <p>This implementation returns {@code listIterator(0)}. | ||
| 295 | * | ||
| 296 | * @see #listIterator(int) | ||
| 297 | */ | ||
| 298 | public ListIterator<E> listIterator() { | ||
| 299 | return listIterator(0); | ||
| 300 | } | ||
| 301 | |||
| 302 | /** | ||
| 303 | * {@inheritDoc} | ||
| 304 | * | ||
| 305 | * <p>This implementation returns a straightforward implementation of the | ||
| 306 | * {@code ListIterator} interface that extends the implementation of the | ||
| 307 | * {@code Iterator} interface returned by the {@code iterator()} method. | ||
| 308 | * The {@code ListIterator} implementation relies on the backing list's | ||
| 309 | * {@code get(int)}, {@code set(int, E)}, {@code add(int, E)} | ||
| 310 | * and {@code remove(int)} methods. | ||
| 311 | * | ||
| 312 | * <p>Note that the list iterator returned by this implementation will | ||
| 313 | * throw an {@link UnsupportedOperationException} in response to its | ||
| 314 | * {@code remove}, {@code set} and {@code add} methods unless the | ||
| 315 | * list's {@code remove(int)}, {@code set(int, E)}, and | ||
| 316 | * {@code add(int, E)} methods are overridden. | ||
| 317 | * | ||
| 318 | * <p>This implementation can be made to throw runtime exceptions in the | ||
| 319 | * face of concurrent modification, as described in the specification for | ||
| 320 | * the (protected) {@link #modCount} field. | ||
| 321 | * | ||
| 322 | * @throws IndexOutOfBoundsException {@inheritDoc} | ||
| 323 | */ | ||
| 324 | public ListIterator<E> listIterator(final int index) { | ||
| 325 | rangeCheckForAdd(index); | ||
| 326 | |||
| 327 | return new ListItr(index); | ||
| 328 | } | ||
| 329 | |||
| 330 | private class Itr implements Iterator<E> { | ||
| 331 | /** | ||
| 332 | * Index of element to be returned by subsequent call to next. | ||
| 333 | */ | ||
| 334 | int cursor = 0; | ||
| 335 | |||
| 336 | /** | ||
| 337 | * Index of element returned by most recent call to next or | ||
| 338 | * previous. Reset to -1 if this element is deleted by a call | ||
| 339 | * to remove. | ||
| 340 | */ | ||
| 341 | int lastRet = -1; | ||
| 342 | |||
| 343 | /** | ||
| 344 | * The modCount value that the iterator believes that the backing | ||
| 345 | * List should have. If this expectation is violated, the iterator | ||
| 346 | * has detected concurrent modification. | ||
| 347 | */ | ||
| 348 | int expectedModCount = modCount; | ||
| 349 | |||
| 350 | public boolean hasNext() { | ||
| 351 | return cursor != size(); | ||
| 352 | } | ||
| 353 | |||
| 354 | public E next() { | ||
| 355 | checkForComodification(); | ||
| 356 | try { | ||
| 357 | int i = cursor; | ||
| 358 | E next = get(i); | ||
| 359 | lastRet = i; | ||
| 360 | cursor = i + 1; | ||
| 361 | return next; | ||
| 362 | } catch (IndexOutOfBoundsException e) { | ||
| 363 | checkForComodification(); | ||
| 364 | throw new NoSuchElementException(); | ||
| 365 | } | ||
| 366 | } | ||
| 367 | |||
| 368 | public void remove() { | ||
| 369 | if (lastRet < 0) | ||
| 370 | throw new IllegalStateException(); | ||
| 371 | checkForComodification(); | ||
| 372 | |||
| 373 | try { | ||
| 374 | AbstractList.this.remove(lastRet); | ||
| 375 | if (lastRet < cursor) | ||
| 376 | cursor--; | ||
| 377 | lastRet = -1; | ||
| 378 | expectedModCount = modCount; | ||
| 379 | } catch (IndexOutOfBoundsException e) { | ||
| 380 | throw new ConcurrentModificationException(); | ||
| 381 | } | ||
| 382 | } | ||
| 383 | |||
| 384 | final void checkForComodification() { | ||
| 385 | if (modCount != expectedModCount) | ||
| 386 | throw new ConcurrentModificationException(); | ||
| 387 | } | ||
| 388 | } | ||
| 389 | |||
| 390 | private class ListItr extends Itr implements ListIterator<E> { | ||
| 391 | ListItr(int index) { | ||
| 392 | cursor = index; | ||
| 393 | } | ||
| 394 | |||
| 395 | public boolean hasPrevious() { | ||
| 396 | return cursor != 0; | ||
| 397 | } | ||
| 398 | |||
| 399 | public E previous() { | ||
| 400 | checkForComodification(); | ||
| 401 | try { | ||
| 402 | int i = cursor - 1; | ||
| 403 | E previous = get(i); | ||
| 404 | lastRet = cursor = i; | ||
| 405 | return previous; | ||
| 406 | } catch (IndexOutOfBoundsException e) { | ||
| 407 | checkForComodification(); | ||
| 408 | throw new NoSuchElementException(); | ||
| 409 | } | ||
| 410 | } | ||
| 411 | |||
| 412 | public int nextIndex() { | ||
| 413 | return cursor; | ||
| 414 | } | ||
| 415 | |||
| 416 | public int previousIndex() { | ||
| 417 | return cursor-1; | ||
| 418 | } | ||
| 419 | |||
| 420 | public void set(E e) { | ||
| 421 | if (lastRet < 0) | ||
| 422 | throw new IllegalStateException(); | ||
| 423 | checkForComodification(); | ||
| 424 | |||
| 425 | try { | ||
| 426 | AbstractList.this.set(lastRet, e); | ||
| 427 | expectedModCount = modCount; | ||
| 428 | } catch (IndexOutOfBoundsException ex) { | ||
| 429 | throw new ConcurrentModificationException(); | ||
| 430 | } | ||
| 431 | } | ||
| 432 | |||
| 433 | public void add(E e) { | ||
| 434 | checkForComodification(); | ||
| 435 | |||
| 436 | try { | ||
| 437 | int i = cursor; | ||
| 438 | AbstractList.this.add(i, e); | ||
| 439 | lastRet = -1; | ||
| 440 | cursor = i + 1; | ||
| 441 | expectedModCount = modCount; | ||
| 442 | } catch (IndexOutOfBoundsException ex) { | ||
| 443 | throw new ConcurrentModificationException(); | ||
| 444 | } | ||
| 445 | } | ||
| 446 | } | ||
| 447 | |||
| 448 | /** | ||
| 449 | * {@inheritDoc} | ||
| 450 | * | ||
| 451 | * <p>This implementation returns a list that subclasses | ||
| 452 | * {@code AbstractList}. The subclass stores, in private fields, the | ||
| 453 | * offset of the subList within the backing list, the size of the subList | ||
| 454 | * (which can change over its lifetime), and the expected | ||
| 455 | * {@code modCount} value of the backing list. There are two variants | ||
| 456 | * of the subclass, one of which implements {@code RandomAccess}. | ||
| 457 | * If this list implements {@code RandomAccess} the returned list will | ||
| 458 | * be an instance of the subclass that implements {@code RandomAccess}. | ||
| 459 | * | ||
| 460 | * <p>The subclass's {@code set(int, E)}, {@code get(int)}, | ||
| 461 | * {@code add(int, E)}, {@code remove(int)}, {@code addAll(int, | ||
| 462 | * Collection)} and {@code removeRange(int, int)} methods all | ||
| 463 | * delegate to the corresponding methods on the backing abstract list, | ||
| 464 | * after bounds-checking the index and adjusting for the offset. The | ||
| 465 | * {@code addAll(Collection c)} method merely returns {@code addAll(size, | ||
| 466 | * c)}. | ||
| 467 | * | ||
| 468 | * <p>The {@code listIterator(int)} method returns a "wrapper object" | ||
| 469 | * over a list iterator on the backing list, which is created with the | ||
| 470 | * corresponding method on the backing list. The {@code iterator} method | ||
| 471 | * merely returns {@code listIterator()}, and the {@code size} method | ||
| 472 | * merely returns the subclass's {@code size} field. | ||
| 473 | * | ||
| 474 | * <p>All methods first check to see if the actual {@code modCount} of | ||
| 475 | * the backing list is equal to its expected value, and throw a | ||
| 476 | * {@code ConcurrentModificationException} if it is not. | ||
| 477 | * | ||
| 478 | * @throws IndexOutOfBoundsException if an endpoint index value is out of range | ||
| 479 | * {@code (fromIndex < 0 || toIndex > size)} | ||
| 480 | * @throws IllegalArgumentException if the endpoint indices are out of order | ||
| 481 | * {@code (fromIndex > toIndex)} | ||
| 482 | */ | ||
| 483 | public List<E> subList(int fromIndex, int toIndex) { | ||
| 484 | return (this instanceof RandomAccess ? | ||
| 485 | new RandomAccessSubList<>(this, fromIndex, toIndex) : | ||
| 486 | new SubList<>(this, fromIndex, toIndex)); | ||
| 487 | } | ||
| 488 | |||
| 489 | // Comparison and hashing | ||
| 490 | |||
| 491 | /** | ||
| 492 | * Compares the specified object with this list for equality. Returns | ||
| 493 | * {@code true} if and only if the specified object is also a list, both | ||
| 494 | * lists have the same size, and all corresponding pairs of elements in | ||
| 495 | * the two lists are <i>equal</i>. (Two elements {@code e1} and | ||
| 496 | * {@code e2} are <i>equal</i> if {@code (e1==null ? e2==null : | ||
| 497 | * e1.equals(e2))}.) In other words, two lists are defined to be | ||
| 498 | * equal if they contain the same elements in the same order.<p> | ||
| 499 | * | ||
| 500 | * This implementation first checks if the specified object is this | ||
| 501 | * list. If so, it returns {@code true}; if not, it checks if the | ||
| 502 | * specified object is a list. If not, it returns {@code false}; if so, | ||
| 503 | * it iterates over both lists, comparing corresponding pairs of elements. | ||
| 504 | * If any comparison returns {@code false}, this method returns | ||
| 505 | * {@code false}. If either iterator runs out of elements before the | ||
| 506 | * other it returns {@code false} (as the lists are of unequal length); | ||
| 507 | * otherwise it returns {@code true} when the iterations complete. | ||
| 508 | * | ||
| 509 | * @param o the object to be compared for equality with this list | ||
| 510 | * @return {@code true} if the specified object is equal to this list | ||
| 511 | */ | ||
| 512 | public boolean equals(Object o) { | ||
| 513 | if (o == this) | ||
| 514 | return true; | ||
| 515 | if (!(o instanceof List)) | ||
| 516 | return false; | ||
| 517 | |||
| 518 | ListIterator<E> e1 = listIterator(); | ||
| 519 | ListIterator e2 = ((List) o).listIterator(); | ||
| 520 | while (e1.hasNext() && e2.hasNext()) { | ||
| 521 | E o1 = e1.next(); | ||
| 522 | Object o2 = e2.next(); | ||
| 523 | if (!(o1==null ? o2==null : o1.equals(o2))) | ||
| 524 | return false; | ||
| 525 | } | ||
| 526 | return !(e1.hasNext() || e2.hasNext()); | ||
| 527 | } | ||
| 528 | |||
| 529 | /** | ||
| 530 | * Returns the hash code value for this list. | ||
| 531 | * | ||
| 532 | * <p>This implementation uses exactly the code that is used to define the | ||
| 533 | * list hash function in the documentation for the {@link List#hashCode} | ||
| 534 | * method. | ||
| 535 | * | ||
| 536 | * @return the hash code value for this list | ||
| 537 | */ | ||
| 538 | public int hashCode() { | ||
| 539 | int hashCode = 1; | ||
| 540 | for (E e : this) | ||
| 541 | hashCode = 31*hashCode + (e==null ? 0 : e.hashCode()); | ||
| 542 | return hashCode; | ||
| 543 | } | ||
| 544 | |||
| 545 | /** | ||
| 546 | * Removes from this list all of the elements whose index is between | ||
| 547 | * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive. | ||
| 548 | * Shifts any succeeding elements to the left (reduces their index). | ||
| 549 | * This call shortens the list by {@code (toIndex - fromIndex)} elements. | ||
| 550 | * (If {@code toIndex==fromIndex}, this operation has no effect.) | ||
| 551 | * | ||
| 552 | * <p>This method is called by the {@code clear} operation on this list | ||
| 553 | * and its subLists. Overriding this method to take advantage of | ||
| 554 | * the internals of the list implementation can <i>substantially</i> | ||
| 555 | * improve the performance of the {@code clear} operation on this list | ||
| 556 | * and its subLists. | ||
| 557 | * | ||
| 558 | * <p>This implementation gets a list iterator positioned before | ||
| 559 | * {@code fromIndex}, and repeatedly calls {@code ListIterator.next} | ||
| 560 | * followed by {@code ListIterator.remove} until the entire range has | ||
| 561 | * been removed. <b>Note: if {@code ListIterator.remove} requires linear | ||
| 562 | * time, this implementation requires quadratic time.</b> | ||
| 563 | * | ||
| 564 | * @param fromIndex index of first element to be removed | ||
| 565 | * @param toIndex index after last element to be removed | ||
| 566 | */ | ||
| 567 | protected void removeRange(int fromIndex, int toIndex) { | ||
| 568 | ListIterator<E> it = listIterator(fromIndex); | ||
| 569 | for (int i=0, n=toIndex-fromIndex; i<n; i++) { | ||
| 570 | it.next(); | ||
| 571 | it.remove(); | ||
| 572 | } | ||
| 573 | } | ||
| 574 | |||
| 575 | /** | ||
| 576 | * The number of times this list has been <i>structurally modified</i>. | ||
| 577 | * Structural modifications are those that change the size of the | ||
| 578 | * list, or otherwise perturb it in such a fashion that iterations in | ||
| 579 | * progress may yield incorrect results. | ||
| 580 | * | ||
| 581 | * <p>This field is used by the iterator and list iterator implementation | ||
| 582 | * returned by the {@code iterator} and {@code listIterator} methods. | ||
| 583 | * If the value of this field changes unexpectedly, the iterator (or list | ||
| 584 | * iterator) will throw a {@code ConcurrentModificationException} in | ||
| 585 | * response to the {@code next}, {@code remove}, {@code previous}, | ||
| 586 | * {@code set} or {@code add} operations. This provides | ||
| 587 | * <i>fail-fast</i> behavior, rather than non-deterministic behavior in | ||
| 588 | * the face of concurrent modification during iteration. | ||
| 589 | * | ||
| 590 | * <p><b>Use of this field by subclasses is optional.</b> If a subclass | ||
| 591 | * wishes to provide fail-fast iterators (and list iterators), then it | ||
| 592 | * merely has to increment this field in its {@code add(int, E)} and | ||
| 593 | * {@code remove(int)} methods (and any other methods that it overrides | ||
| 594 | * that result in structural modifications to the list). A single call to | ||
| 595 | * {@code add(int, E)} or {@code remove(int)} must add no more than | ||
| 596 | * one to this field, or the iterators (and list iterators) will throw | ||
| 597 | * bogus {@code ConcurrentModificationExceptions}. If an implementation | ||
| 598 | * does not wish to provide fail-fast iterators, this field may be | ||
| 599 | * ignored. | ||
| 600 | */ | ||
| 601 | protected transient int modCount = 0; | ||
| 602 | |||
| 603 | private void rangeCheckForAdd(int index) { | ||
| 604 | if (index < 0 || index > size()) | ||
| 605 | throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); | ||
| 606 | } | ||
| 607 | |||
| 608 | private String outOfBoundsMsg(int index) { | ||
| 609 | return "Index: "+index+", Size: "+size(); | ||
| 610 | } | ||
| 611 | } | ||
| 612 | |||
| 613 | class SubList<E> extends AbstractList<E> { | ||
| 614 | private final AbstractList<E> l; | ||
| 615 | private final int offset; | ||
| 616 | private int size; | ||
| 617 | |||
| 618 | SubList(AbstractList<E> list, int fromIndex, int toIndex) { | ||
| 619 | if (fromIndex < 0) | ||
| 620 | throw new IndexOutOfBoundsException("fromIndex = " + fromIndex); | ||
| 621 | if (toIndex > list.size()) | ||
| 622 | throw new IndexOutOfBoundsException("toIndex = " + toIndex); | ||
| 623 | if (fromIndex > toIndex) | ||
| 624 | throw new IllegalArgumentException("fromIndex(" + fromIndex + | ||
| 625 | ") > toIndex(" + toIndex + ")"); | ||
| 626 | l = list; | ||
| 627 | offset = fromIndex; | ||
| 628 | size = toIndex - fromIndex; | ||
| 629 | this.modCount = l.modCount; | ||
| 630 | } | ||
| 631 | |||
| 632 | public E set(int index, E element) { | ||
| 633 | rangeCheck(index); | ||
| 634 | checkForComodification(); | ||
| 635 | return l.set(index+offset, element); | ||
| 636 | } | ||
| 637 | |||
| 638 | public E get(int index) { | ||
| 639 | rangeCheck(index); | ||
| 640 | checkForComodification(); | ||
| 641 | return l.get(index+offset); | ||
| 642 | } | ||
| 643 | |||
| 644 | public int size() { | ||
| 645 | checkForComodification(); | ||
| 646 | return size; | ||
| 647 | } | ||
| 648 | |||
| 649 | public void add(int index, E element) { | ||
| 650 | rangeCheckForAdd(index); | ||
| 651 | checkForComodification(); | ||
| 652 | l.add(index+offset, element); | ||
| 653 | this.modCount = l.modCount; | ||
| 654 | size++; | ||
| 655 | } | ||
| 656 | |||
| 657 | public E remove(int index) { | ||
| 658 | rangeCheck(index); | ||
| 659 | checkForComodification(); | ||
| 660 | E result = l.remove(index+offset); | ||
| 661 | this.modCount = l.modCount; | ||
| 662 | size--; | ||
| 663 | return result; | ||
| 664 | } | ||
| 665 | |||
| 666 | protected void removeRange(int fromIndex, int toIndex) { | ||
| 667 | checkForComodification(); | ||
| 668 | l.removeRange(fromIndex+offset, toIndex+offset); | ||
| 669 | this.modCount = l.modCount; | ||
| 670 | size -= (toIndex-fromIndex); | ||
| 671 | } | ||
| 672 | |||
| 673 | public boolean addAll(Collection<? extends E> c) { | ||
| 674 | return addAll(size, c); | ||
| 675 | } | ||
| 676 | |||
| 677 | public boolean addAll(int index, Collection<? extends E> c) { | ||
| 678 | rangeCheckForAdd(index); | ||
| 679 | int cSize = c.size(); | ||
| 680 | if (cSize==0) | ||
| 681 | return false; | ||
| 682 | |||
| 683 | checkForComodification(); | ||
| 684 | l.addAll(offset+index, c); | ||
| 685 | this.modCount = l.modCount; | ||
| 686 | size += cSize; | ||
| 687 | return true; | ||
| 688 | } | ||
| 689 | |||
| 690 | public Iterator<E> iterator() { | ||
| 691 | return listIterator(); | ||
| 692 | } | ||
| 693 | |||
| 694 | public ListIterator<E> listIterator(final int index) { | ||
| 695 | checkForComodification(); | ||
| 696 | rangeCheckForAdd(index); | ||
| 697 | |||
| 698 | return new ListIterator<E>() { | ||
| 699 | private final ListIterator<E> i = l.listIterator(index+offset); | ||
| 700 | |||
| 701 | public boolean hasNext() { | ||
| 702 | return nextIndex() < size; | ||
| 703 | } | ||
| 704 | |||
| 705 | public E next() { | ||
| 706 | if (hasNext()) | ||
| 707 | return i.next(); | ||
| 708 | else | ||
| 709 | throw new NoSuchElementException(); | ||
| 710 | } | ||
| 711 | |||
| 712 | public boolean hasPrevious() { | ||
| 713 | return previousIndex() >= 0; | ||
| 714 | } | ||
| 715 | |||
| 716 | public E previous() { | ||
| 717 | if (hasPrevious()) | ||
| 718 | return i.previous(); | ||
| 719 | else | ||
| 720 | throw new NoSuchElementException(); | ||
| 721 | } | ||
| 722 | |||
| 723 | public int nextIndex() { | ||
| 724 | return i.nextIndex() - offset; | ||
| 725 | } | ||
| 726 | |||
| 727 | public int previousIndex() { | ||
| 728 | return i.previousIndex() - offset; | ||
| 729 | } | ||
| 730 | |||
| 731 | public void remove() { | ||
| 732 | i.remove(); | ||
| 733 | SubList.this.modCount = l.modCount; | ||
| 734 | size--; | ||
| 735 | } | ||
| 736 | |||
| 737 | public void set(E e) { | ||
| 738 | i.set(e); | ||
| 739 | } | ||
| 740 | |||
| 741 | public void add(E e) { | ||
| 742 | i.add(e); | ||
| 743 | SubList.this.modCount = l.modCount; | ||
| 744 | size++; | ||
| 745 | } | ||
| 746 | }; | ||
| 747 | } | ||
| 748 | |||
| 749 | public List<E> subList(int fromIndex, int toIndex) { | ||
| 750 | return new SubList<>(this, fromIndex, toIndex); | ||
| 751 | } | ||
| 752 | |||
| 753 | private void rangeCheck(int index) { | ||
| 754 | if (index < 0 || index >= size) | ||
| 755 | throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); | ||
| 756 | } | ||
| 757 | |||
| 758 | private void rangeCheckForAdd(int index) { | ||
| 759 | if (index < 0 || index > size) | ||
| 760 | throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); | ||
| 761 | } | ||
| 762 | |||
| 763 | private String outOfBoundsMsg(int index) { | ||
| 764 | return "Index: "+index+", Size: "+size; | ||
| 765 | } | ||
| 766 | |||
| 767 | private void checkForComodification() { | ||
| 768 | if (this.modCount != l.modCount) | ||
| 769 | throw new ConcurrentModificationException(); | ||
| 770 | } | ||
| 771 | } | ||
| 772 | |||
| 773 | class RandomAccessSubList<E> extends SubList<E> implements RandomAccess { | ||
| 774 | RandomAccessSubList(AbstractList<E> list, int fromIndex, int toIndex) { | ||
| 775 | super(list, fromIndex, toIndex); | ||
| 776 | } | ||
| 777 | |||
| 778 | public List<E> subList(int fromIndex, int toIndex) { | ||
| 779 | return new RandomAccessSubList<>(this, fromIndex, toIndex); | ||
| 780 | } | ||
| 781 | } | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,822 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package java.util; | ||
| 27 | import java.util.Map.Entry; | ||
| 28 | |||
| 29 | /** | ||
| 30 | * This class provides a skeletal implementation of the <tt>Map</tt> | ||
| 31 | * interface, to minimize the effort required to implement this interface. | ||
| 32 | * | ||
| 33 | * <p>To implement an unmodifiable map, the programmer needs only to extend this | ||
| 34 | * class and provide an implementation for the <tt>entrySet</tt> method, which | ||
| 35 | * returns a set-view of the map's mappings. Typically, the returned set | ||
| 36 | * will, in turn, be implemented atop <tt>AbstractSet</tt>. This set should | ||
| 37 | * not support the <tt>add</tt> or <tt>remove</tt> methods, and its iterator | ||
| 38 | * should not support the <tt>remove</tt> method. | ||
| 39 | * | ||
| 40 | * <p>To implement a modifiable map, the programmer must additionally override | ||
| 41 | * this class's <tt>put</tt> method (which otherwise throws an | ||
| 42 | * <tt>UnsupportedOperationException</tt>), and the iterator returned by | ||
| 43 | * <tt>entrySet().iterator()</tt> must additionally implement its | ||
| 44 | * <tt>remove</tt> method. | ||
| 45 | * | ||
| 46 | * <p>The programmer should generally provide a void (no argument) and map | ||
| 47 | * constructor, as per the recommendation in the <tt>Map</tt> interface | ||
| 48 | * specification. | ||
| 49 | * | ||
| 50 | * <p>The documentation for each non-abstract method in this class describes its | ||
| 51 | * implementation in detail. Each of these methods may be overridden if the | ||
| 52 | * map being implemented admits a more efficient implementation. | ||
| 53 | * | ||
| 54 | * <p>This class is a member of the | ||
| 55 | * <a href="{@docRoot}/../technotes/guides/collections/index.html"> | ||
| 56 | * Java Collections Framework</a>. | ||
| 57 | * | ||
| 58 | * @param <K> the type of keys maintained by this map | ||
| 59 | * @param <V> the type of mapped values | ||
| 60 | * | ||
| 61 | * @author Josh Bloch | ||
| 62 | * @author Neal Gafter | ||
| 63 | * @see Map | ||
| 64 | * @see Collection | ||
| 65 | * @since 1.2 | ||
| 66 | */ | ||
| 67 | |||
| 68 | public abstract class AbstractMap<K,V> implements Map<K,V> { | ||
| 69 | /** | ||
| 70 | * Sole constructor. (For invocation by subclass constructors, typically | ||
| 71 | * implicit.) | ||
| 72 | */ | ||
| 73 | protected AbstractMap() { | ||
| 74 | } | ||
| 75 | |||
| 76 | // Query Operations | ||
| 77 | |||
| 78 | /** | ||
| 79 | * {@inheritDoc} | ||
| 80 | * | ||
| 81 | * <p>This implementation returns <tt>entrySet().size()</tt>. | ||
| 82 | */ | ||
| 83 | public int size() { | ||
| 84 | return entrySet().size(); | ||
| 85 | } | ||
| 86 | |||
| 87 | /** | ||
| 88 | * {@inheritDoc} | ||
| 89 | * | ||
| 90 | * <p>This implementation returns <tt>size() == 0</tt>. | ||
| 91 | */ | ||
| 92 | public boolean isEmpty() { | ||
| 93 | return size() == 0; | ||
| 94 | } | ||
| 95 | |||
| 96 | /** | ||
| 97 | * {@inheritDoc} | ||
| 98 | * | ||
| 99 | * <p>This implementation iterates over <tt>entrySet()</tt> searching | ||
| 100 | * for an entry with the specified value. If such an entry is found, | ||
| 101 | * <tt>true</tt> is returned. If the iteration terminates without | ||
| 102 | * finding such an entry, <tt>false</tt> is returned. Note that this | ||
| 103 | * implementation requires linear time in the size of the map. | ||
| 104 | * | ||
| 105 | * @throws ClassCastException {@inheritDoc} | ||
| 106 | * @throws NullPointerException {@inheritDoc} | ||
| 107 | */ | ||
| 108 | public boolean containsValue(Object value) { | ||
| 109 | Iterator<Entry<K,V>> i = entrySet().iterator(); | ||
| 110 | if (value==null) { | ||
| 111 | while (i.hasNext()) { | ||
| 112 | Entry<K,V> e = i.next(); | ||
| 113 | if (e.getValue()==null) | ||
| 114 | return true; | ||
| 115 | } | ||
| 116 | } else { | ||
| 117 | while (i.hasNext()) { | ||
| 118 | Entry<K,V> e = i.next(); | ||
| 119 | if (value.equals(e.getValue())) | ||
| 120 | return true; | ||
| 121 | } | ||
| 122 | } | ||
| 123 | return false; | ||
| 124 | } | ||
| 125 | |||
| 126 | /** | ||
| 127 | * {@inheritDoc} | ||
| 128 | * | ||
| 129 | * <p>This implementation iterates over <tt>entrySet()</tt> searching | ||
| 130 | * for an entry with the specified key. If such an entry is found, | ||
| 131 | * <tt>true</tt> is returned. If the iteration terminates without | ||
| 132 | * finding such an entry, <tt>false</tt> is returned. Note that this | ||
| 133 | * implementation requires linear time in the size of the map; many | ||
| 134 | * implementations will override this method. | ||
| 135 | * | ||
| 136 | * @throws ClassCastException {@inheritDoc} | ||
| 137 | * @throws NullPointerException {@inheritDoc} | ||
| 138 | */ | ||
| 139 | public boolean containsKey(Object key) { | ||
| 140 | Iterator<Map.Entry<K,V>> i = entrySet().iterator(); | ||
| 141 | if (key==null) { | ||
| 142 | while (i.hasNext()) { | ||
| 143 | Entry<K,V> e = i.next(); | ||
| 144 | if (e.getKey()==null) | ||
| 145 | return true; | ||
| 146 | } | ||
| 147 | } else { | ||
| 148 | while (i.hasNext()) { | ||
| 149 | Entry<K,V> e = i.next(); | ||
| 150 | if (key.equals(e.getKey())) | ||
| 151 | return true; | ||
| 152 | } | ||
| 153 | } | ||
| 154 | return false; | ||
| 155 | } | ||
| 156 | |||
| 157 | /** | ||
| 158 | * {@inheritDoc} | ||
| 159 | * | ||
| 160 | * <p>This implementation iterates over <tt>entrySet()</tt> searching | ||
| 161 | * for an entry with the specified key. If such an entry is found, | ||
| 162 | * the entry's value is returned. If the iteration terminates without | ||
| 163 | * finding such an entry, <tt>null</tt> is returned. Note that this | ||
| 164 | * implementation requires linear time in the size of the map; many | ||
| 165 | * implementations will override this method. | ||
| 166 | * | ||
| 167 | * @throws ClassCastException {@inheritDoc} | ||
| 168 | * @throws NullPointerException {@inheritDoc} | ||
| 169 | */ | ||
| 170 | public V get(Object key) { | ||
| 171 | Iterator<Entry<K,V>> i = entrySet().iterator(); | ||
| 172 | if (key==null) { | ||
| 173 | while (i.hasNext()) { | ||
| 174 | Entry<K,V> e = i.next(); | ||
| 175 | if (e.getKey()==null) | ||
| 176 | return e.getValue(); | ||
| 177 | } | ||
| 178 | } else { | ||
| 179 | while (i.hasNext()) { | ||
| 180 | Entry<K,V> e = i.next(); | ||
| 181 | if (key.equals(e.getKey())) | ||
| 182 | return e.getValue(); | ||
| 183 | } | ||
| 184 | } | ||
| 185 | return null; | ||
| 186 | } | ||
| 187 | |||
| 188 | |||
| 189 | // Modification Operations | ||
| 190 | |||
| 191 | /** | ||
| 192 | * {@inheritDoc} | ||
| 193 | * | ||
| 194 | * <p>This implementation always throws an | ||
| 195 | * <tt>UnsupportedOperationException</tt>. | ||
| 196 | * | ||
| 197 | * @throws UnsupportedOperationException {@inheritDoc} | ||
| 198 | * @throws ClassCastException {@inheritDoc} | ||
| 199 | * @throws NullPointerException {@inheritDoc} | ||
| 200 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 201 | */ | ||
| 202 | public V put(K key, V value) { | ||
| 203 | throw new UnsupportedOperationException(); | ||
| 204 | } | ||
| 205 | |||
| 206 | /** | ||
| 207 | * {@inheritDoc} | ||
| 208 | * | ||
| 209 | * <p>This implementation iterates over <tt>entrySet()</tt> searching for an | ||
| 210 | * entry with the specified key. If such an entry is found, its value is | ||
| 211 | * obtained with its <tt>getValue</tt> operation, the entry is removed | ||
| 212 | * from the collection (and the backing map) with the iterator's | ||
| 213 | * <tt>remove</tt> operation, and the saved value is returned. If the | ||
| 214 | * iteration terminates without finding such an entry, <tt>null</tt> is | ||
| 215 | * returned. Note that this implementation requires linear time in the | ||
| 216 | * size of the map; many implementations will override this method. | ||
| 217 | * | ||
| 218 | * <p>Note that this implementation throws an | ||
| 219 | * <tt>UnsupportedOperationException</tt> if the <tt>entrySet</tt> | ||
| 220 | * iterator does not support the <tt>remove</tt> method and this map | ||
| 221 | * contains a mapping for the specified key. | ||
| 222 | * | ||
| 223 | * @throws UnsupportedOperationException {@inheritDoc} | ||
| 224 | * @throws ClassCastException {@inheritDoc} | ||
| 225 | * @throws NullPointerException {@inheritDoc} | ||
| 226 | */ | ||
| 227 | public V remove(Object key) { | ||
| 228 | Iterator<Entry<K,V>> i = entrySet().iterator(); | ||
| 229 | Entry<K,V> correctEntry = null; | ||
| 230 | if (key==null) { | ||
| 231 | while (correctEntry==null && i.hasNext()) { | ||
| 232 | Entry<K,V> e = i.next(); | ||
| 233 | if (e.getKey()==null) | ||
| 234 | correctEntry = e; | ||
| 235 | } | ||
| 236 | } else { | ||
| 237 | while (correctEntry==null && i.hasNext()) { | ||
| 238 | Entry<K,V> e = i.next(); | ||
| 239 | if (key.equals(e.getKey())) | ||
| 240 | correctEntry = e; | ||
| 241 | } | ||
| 242 | } | ||
| 243 | |||
| 244 | V oldValue = null; | ||
| 245 | if (correctEntry !=null) { | ||
| 246 | oldValue = correctEntry.getValue(); | ||
| 247 | i.remove(); | ||
| 248 | } | ||
| 249 | return oldValue; | ||
| 250 | } | ||
| 251 | |||
| 252 | |||
| 253 | // Bulk Operations | ||
| 254 | |||
| 255 | /** | ||
| 256 | * {@inheritDoc} | ||
| 257 | * | ||
| 258 | * <p>This implementation iterates over the specified map's | ||
| 259 | * <tt>entrySet()</tt> collection, and calls this map's <tt>put</tt> | ||
| 260 | * operation once for each entry returned by the iteration. | ||
| 261 | * | ||
| 262 | * <p>Note that this implementation throws an | ||
| 263 | * <tt>UnsupportedOperationException</tt> if this map does not support | ||
| 264 | * the <tt>put</tt> operation and the specified map is nonempty. | ||
| 265 | * | ||
| 266 | * @throws UnsupportedOperationException {@inheritDoc} | ||
| 267 | * @throws ClassCastException {@inheritDoc} | ||
| 268 | * @throws NullPointerException {@inheritDoc} | ||
| 269 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 270 | */ | ||
| 271 | public void putAll(Map<? extends K, ? extends V> m) { | ||
| 272 | for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) | ||
| 273 | put(e.getKey(), e.getValue()); | ||
| 274 | } | ||
| 275 | |||
| 276 | /** | ||
| 277 | * {@inheritDoc} | ||
| 278 | * | ||
| 279 | * <p>This implementation calls <tt>entrySet().clear()</tt>. | ||
| 280 | * | ||
| 281 | * <p>Note that this implementation throws an | ||
| 282 | * <tt>UnsupportedOperationException</tt> if the <tt>entrySet</tt> | ||
| 283 | * does not support the <tt>clear</tt> operation. | ||
| 284 | * | ||
| 285 | * @throws UnsupportedOperationException {@inheritDoc} | ||
| 286 | */ | ||
| 287 | public void clear() { | ||
| 288 | entrySet().clear(); | ||
| 289 | } | ||
| 290 | |||
| 291 | |||
| 292 | // Views | ||
| 293 | |||
| 294 | /** | ||
| 295 | * Each of these fields are initialized to contain an instance of the | ||
| 296 | * appropriate view the first time this view is requested. The views are | ||
| 297 | * stateless, so there's no reason to create more than one of each. | ||
| 298 | */ | ||
| 299 | transient volatile Set<K> keySet = null; | ||
| 300 | transient volatile Collection<V> values = null; | ||
| 301 | |||
| 302 | /** | ||
| 303 | * {@inheritDoc} | ||
| 304 | * | ||
| 305 | * <p>This implementation returns a set that subclasses {@link AbstractSet}. | ||
| 306 | * The subclass's iterator method returns a "wrapper object" over this | ||
| 307 | * map's <tt>entrySet()</tt> iterator. The <tt>size</tt> method | ||
| 308 | * delegates to this map's <tt>size</tt> method and the | ||
| 309 | * <tt>contains</tt> method delegates to this map's | ||
| 310 | * <tt>containsKey</tt> method. | ||
| 311 | * | ||
| 312 | * <p>The set is created the first time this method is called, | ||
| 313 | * and returned in response to all subsequent calls. No synchronization | ||
| 314 | * is performed, so there is a slight chance that multiple calls to this | ||
| 315 | * method will not all return the same set. | ||
| 316 | */ | ||
| 317 | public Set<K> keySet() { | ||
| 318 | if (keySet == null) { | ||
| 319 | keySet = new AbstractSet<K>() { | ||
| 320 | public Iterator<K> iterator() { | ||
| 321 | return new Iterator<K>() { | ||
| 322 | private Iterator<Entry<K,V>> i = entrySet().iterator(); | ||
| 323 | |||
| 324 | public boolean hasNext() { | ||
| 325 | return i.hasNext(); | ||
| 326 | } | ||
| 327 | |||
| 328 | public K next() { | ||
| 329 | return i.next().getKey(); | ||
| 330 | } | ||
| 331 | |||
| 332 | public void remove() { | ||
| 333 | i.remove(); | ||
| 334 | } | ||
| 335 | }; | ||
| 336 | } | ||
| 337 | |||
| 338 | public int size() { | ||
| 339 | return AbstractMap.this.size(); | ||
| 340 | } | ||
| 341 | |||
| 342 | public boolean isEmpty() { | ||
| 343 | return AbstractMap.this.isEmpty(); | ||
| 344 | } | ||
| 345 | |||
| 346 | public void clear() { | ||
| 347 | AbstractMap.this.clear(); | ||
| 348 | } | ||
| 349 | |||
| 350 | public boolean contains(Object k) { | ||
| 351 | return AbstractMap.this.containsKey(k); | ||
| 352 | } | ||
| 353 | }; | ||
| 354 | } | ||
| 355 | return keySet; | ||
| 356 | } | ||
| 357 | |||
| 358 | /** | ||
| 359 | * {@inheritDoc} | ||
| 360 | * | ||
| 361 | * <p>This implementation returns a collection that subclasses {@link | ||
| 362 | * AbstractCollection}. The subclass's iterator method returns a | ||
| 363 | * "wrapper object" over this map's <tt>entrySet()</tt> iterator. | ||
| 364 | * The <tt>size</tt> method delegates to this map's <tt>size</tt> | ||
| 365 | * method and the <tt>contains</tt> method delegates to this map's | ||
| 366 | * <tt>containsValue</tt> method. | ||
| 367 | * | ||
| 368 | * <p>The collection is created the first time this method is called, and | ||
| 369 | * returned in response to all subsequent calls. No synchronization is | ||
| 370 | * performed, so there is a slight chance that multiple calls to this | ||
| 371 | * method will not all return the same collection. | ||
| 372 | */ | ||
| 373 | public Collection<V> values() { | ||
| 374 | if (values == null) { | ||
| 375 | values = new AbstractCollection<V>() { | ||
| 376 | public Iterator<V> iterator() { | ||
| 377 | return new Iterator<V>() { | ||
| 378 | private Iterator<Entry<K,V>> i = entrySet().iterator(); | ||
| 379 | |||
| 380 | public boolean hasNext() { | ||
| 381 | return i.hasNext(); | ||
| 382 | } | ||
| 383 | |||
| 384 | public V next() { | ||
| 385 | return i.next().getValue(); | ||
| 386 | } | ||
| 387 | |||
| 388 | public void remove() { | ||
| 389 | i.remove(); | ||
| 390 | } | ||
| 391 | }; | ||
| 392 | } | ||
| 393 | |||
| 394 | public int size() { | ||
| 395 | return AbstractMap.this.size(); | ||
| 396 | } | ||
| 397 | |||
| 398 | public boolean isEmpty() { | ||
| 399 | return AbstractMap.this.isEmpty(); | ||
| 400 | } | ||
| 401 | |||
| 402 | public void clear() { | ||
| 403 | AbstractMap.this.clear(); | ||
| 404 | } | ||
| 405 | |||
| 406 | public boolean contains(Object v) { | ||
| 407 | return AbstractMap.this.containsValue(v); | ||
| 408 | } | ||
| 409 | }; | ||
| 410 | } | ||
| 411 | return values; | ||
| 412 | } | ||
| 413 | |||
| 414 | public abstract Set<Entry<K,V>> entrySet(); | ||
| 415 | |||
| 416 | |||
| 417 | // Comparison and hashing | ||
| 418 | |||
| 419 | /** | ||
| 420 | * Compares the specified object with this map for equality. Returns | ||
| 421 | * <tt>true</tt> if the given object is also a map and the two maps | ||
| 422 | * represent the same mappings. More formally, two maps <tt>m1</tt> and | ||
| 423 | * <tt>m2</tt> represent the same mappings if | ||
| 424 | * <tt>m1.entrySet().equals(m2.entrySet())</tt>. This ensures that the | ||
| 425 | * <tt>equals</tt> method works properly across different implementations | ||
| 426 | * of the <tt>Map</tt> interface. | ||
| 427 | * | ||
| 428 | * <p>This implementation first checks if the specified object is this map; | ||
| 429 | * if so it returns <tt>true</tt>. Then, it checks if the specified | ||
| 430 | * object is a map whose size is identical to the size of this map; if | ||
| 431 | * not, it returns <tt>false</tt>. If so, it iterates over this map's | ||
| 432 | * <tt>entrySet</tt> collection, and checks that the specified map | ||
| 433 | * contains each mapping that this map contains. If the specified map | ||
| 434 | * fails to contain such a mapping, <tt>false</tt> is returned. If the | ||
| 435 | * iteration completes, <tt>true</tt> is returned. | ||
| 436 | * | ||
| 437 | * @param o object to be compared for equality with this map | ||
| 438 | * @return <tt>true</tt> if the specified object is equal to this map | ||
| 439 | */ | ||
| 440 | public boolean equals(Object o) { | ||
| 441 | if (o == this) | ||
| 442 | return true; | ||
| 443 | |||
| 444 | if (!(o instanceof Map)) | ||
| 445 | return false; | ||
| 446 | Map<K,V> m = (Map<K,V>) o; | ||
| 447 | if (m.size() != size()) | ||
| 448 | return false; | ||
| 449 | |||
| 450 | try { | ||
| 451 | Iterator<Entry<K,V>> i = entrySet().iterator(); | ||
| 452 | while (i.hasNext()) { | ||
| 453 | Entry<K,V> e = i.next(); | ||
| 454 | K key = e.getKey(); | ||
| 455 | V value = e.getValue(); | ||
| 456 | if (value == null) { | ||
| 457 | if (!(m.get(key)==null && m.containsKey(key))) | ||
| 458 | return false; | ||
| 459 | } else { | ||
| 460 | if (!value.equals(m.get(key))) | ||
| 461 | return false; | ||
| 462 | } | ||
| 463 | } | ||
| 464 | } catch (ClassCastException unused) { | ||
| 465 | return false; | ||
| 466 | } catch (NullPointerException unused) { | ||
| 467 | return false; | ||
| 468 | } | ||
| 469 | |||
| 470 | return true; | ||
| 471 | } | ||
| 472 | |||
| 473 | /** | ||
| 474 | * Returns the hash code value for this map. The hash code of a map is | ||
| 475 | * defined to be the sum of the hash codes of each entry in the map's | ||
| 476 | * <tt>entrySet()</tt> view. This ensures that <tt>m1.equals(m2)</tt> | ||
| 477 | * implies that <tt>m1.hashCode()==m2.hashCode()</tt> for any two maps | ||
| 478 | * <tt>m1</tt> and <tt>m2</tt>, as required by the general contract of | ||
| 479 | * {@link Object#hashCode}. | ||
| 480 | * | ||
| 481 | * <p>This implementation iterates over <tt>entrySet()</tt>, calling | ||
| 482 | * {@link Map.Entry#hashCode hashCode()} on each element (entry) in the | ||
| 483 | * set, and adding up the results. | ||
| 484 | * | ||
| 485 | * @return the hash code value for this map | ||
| 486 | * @see Map.Entry#hashCode() | ||
| 487 | * @see Object#equals(Object) | ||
| 488 | * @see Set#equals(Object) | ||
| 489 | */ | ||
| 490 | public int hashCode() { | ||
| 491 | int h = 0; | ||
| 492 | Iterator<Entry<K,V>> i = entrySet().iterator(); | ||
| 493 | while (i.hasNext()) | ||
| 494 | h += i.next().hashCode(); | ||
| 495 | return h; | ||
| 496 | } | ||
| 497 | |||
| 498 | /** | ||
| 499 | * Returns a string representation of this map. The string representation | ||
| 500 | * consists of a list of key-value mappings in the order returned by the | ||
| 501 | * map's <tt>entrySet</tt> view's iterator, enclosed in braces | ||
| 502 | * (<tt>"{}"</tt>). Adjacent mappings are separated by the characters | ||
| 503 | * <tt>", "</tt> (comma and space). Each key-value mapping is rendered as | ||
| 504 | * the key followed by an equals sign (<tt>"="</tt>) followed by the | ||
| 505 | * associated value. Keys and values are converted to strings as by | ||
| 506 | * {@link String#valueOf(Object)}. | ||
| 507 | * | ||
| 508 | * @return a string representation of this map | ||
| 509 | */ | ||
| 510 | public String toString() { | ||
| 511 | Iterator<Entry<K,V>> i = entrySet().iterator(); | ||
| 512 | if (! i.hasNext()) | ||
| 513 | return "{}"; | ||
| 514 | |||
| 515 | StringBuilder sb = new StringBuilder(); | ||
| 516 | sb.append('{'); | ||
| 517 | for (;;) { | ||
| 518 | Entry<K,V> e = i.next(); | ||
| 519 | K key = e.getKey(); | ||
| 520 | V value = e.getValue(); | ||
| 521 | sb.append(key == this ? "(this Map)" : key); | ||
| 522 | sb.append('='); | ||
| 523 | sb.append(value == this ? "(this Map)" : value); | ||
| 524 | if (! i.hasNext()) | ||
| 525 | return sb.append('}').toString(); | ||
| 526 | sb.append(',').append(' '); | ||
| 527 | } | ||
| 528 | } | ||
| 529 | |||
| 530 | /** | ||
| 531 | * Returns a shallow copy of this <tt>AbstractMap</tt> instance: the keys | ||
| 532 | * and values themselves are not cloned. | ||
| 533 | * | ||
| 534 | * @return a shallow copy of this map | ||
| 535 | */ | ||
| 536 | protected Object clone() throws CloneNotSupportedException { | ||
| 537 | AbstractMap<K,V> result = (AbstractMap<K,V>)super.clone(); | ||
| 538 | result.keySet = null; | ||
| 539 | result.values = null; | ||
| 540 | return result; | ||
| 541 | } | ||
| 542 | |||
| 543 | /** | ||
| 544 | * Utility method for SimpleEntry and SimpleImmutableEntry. | ||
| 545 | * Test for equality, checking for nulls. | ||
| 546 | */ | ||
| 547 | private static boolean eq(Object o1, Object o2) { | ||
| 548 | return o1 == null ? o2 == null : o1.equals(o2); | ||
| 549 | } | ||
| 550 | |||
| 551 | // Implementation Note: SimpleEntry and SimpleImmutableEntry | ||
| 552 | // are distinct unrelated classes, even though they share | ||
| 553 | // some code. Since you can't add or subtract final-ness | ||
| 554 | // of a field in a subclass, they can't share representations, | ||
| 555 | // and the amount of duplicated code is too small to warrant | ||
| 556 | // exposing a common abstract class. | ||
| 557 | |||
| 558 | |||
| 559 | /** | ||
| 560 | * An Entry maintaining a key and a value. The value may be | ||
| 561 | * changed using the <tt>setValue</tt> method. This class | ||
| 562 | * facilitates the process of building custom map | ||
| 563 | * implementations. For example, it may be convenient to return | ||
| 564 | * arrays of <tt>SimpleEntry</tt> instances in method | ||
| 565 | * <tt>Map.entrySet().toArray</tt>. | ||
| 566 | * | ||
| 567 | * @since 1.6 | ||
| 568 | */ | ||
| 569 | public static class SimpleEntry<K,V> | ||
| 570 | implements Entry<K,V>, java.io.Serializable | ||
| 571 | { | ||
| 572 | private static final long serialVersionUID = -8499721149061103585L; | ||
| 573 | |||
| 574 | private final K key; | ||
| 575 | private V value; | ||
| 576 | |||
| 577 | /** | ||
| 578 | * Creates an entry representing a mapping from the specified | ||
| 579 | * key to the specified value. | ||
| 580 | * | ||
| 581 | * @param key the key represented by this entry | ||
| 582 | * @param value the value represented by this entry | ||
| 583 | */ | ||
| 584 | public SimpleEntry(K key, V value) { | ||
| 585 | this.key = key; | ||
| 586 | this.value = value; | ||
| 587 | } | ||
| 588 | |||
| 589 | /** | ||
| 590 | * Creates an entry representing the same mapping as the | ||
| 591 | * specified entry. | ||
| 592 | * | ||
| 593 | * @param entry the entry to copy | ||
| 594 | */ | ||
| 595 | public SimpleEntry(Entry<? extends K, ? extends V> entry) { | ||
| 596 | this.key = entry.getKey(); | ||
| 597 | this.value = entry.getValue(); | ||
| 598 | } | ||
| 599 | |||
| 600 | /** | ||
| 601 | * Returns the key corresponding to this entry. | ||
| 602 | * | ||
| 603 | * @return the key corresponding to this entry | ||
| 604 | */ | ||
| 605 | public K getKey() { | ||
| 606 | return key; | ||
| 607 | } | ||
| 608 | |||
| 609 | /** | ||
| 610 | * Returns the value corresponding to this entry. | ||
| 611 | * | ||
| 612 | * @return the value corresponding to this entry | ||
| 613 | */ | ||
| 614 | public V getValue() { | ||
| 615 | return value; | ||
| 616 | } | ||
| 617 | |||
| 618 | /** | ||
| 619 | * Replaces the value corresponding to this entry with the specified | ||
| 620 | * value. | ||
| 621 | * | ||
| 622 | * @param value new value to be stored in this entry | ||
| 623 | * @return the old value corresponding to the entry | ||
| 624 | */ | ||
| 625 | public V setValue(V value) { | ||
| 626 | V oldValue = this.value; | ||
| 627 | this.value = value; | ||
| 628 | return oldValue; | ||
| 629 | } | ||
| 630 | |||
| 631 | /** | ||
| 632 | * Compares the specified object with this entry for equality. | ||
| 633 | * Returns {@code true} if the given object is also a map entry and | ||
| 634 | * the two entries represent the same mapping. More formally, two | ||
| 635 | * entries {@code e1} and {@code e2} represent the same mapping | ||
| 636 | * if<pre> | ||
| 637 | * (e1.getKey()==null ? | ||
| 638 | * e2.getKey()==null : | ||
| 639 | * e1.getKey().equals(e2.getKey())) | ||
| 640 | * && | ||
| 641 | * (e1.getValue()==null ? | ||
| 642 | * e2.getValue()==null : | ||
| 643 | * e1.getValue().equals(e2.getValue()))</pre> | ||
| 644 | * This ensures that the {@code equals} method works properly across | ||
| 645 | * different implementations of the {@code Map.Entry} interface. | ||
| 646 | * | ||
| 647 | * @param o object to be compared for equality with this map entry | ||
| 648 | * @return {@code true} if the specified object is equal to this map | ||
| 649 | * entry | ||
| 650 | * @see #hashCode | ||
| 651 | */ | ||
| 652 | public boolean equals(Object o) { | ||
| 653 | if (!(o instanceof Map.Entry)) | ||
| 654 | return false; | ||
| 655 | Map.Entry e = (Map.Entry)o; | ||
| 656 | return eq(key, e.getKey()) && eq(value, e.getValue()); | ||
| 657 | } | ||
| 658 | |||
| 659 | /** | ||
| 660 | * Returns the hash code value for this map entry. The hash code | ||
| 661 | * of a map entry {@code e} is defined to be: <pre> | ||
| 662 | * (e.getKey()==null ? 0 : e.getKey().hashCode()) ^ | ||
| 663 | * (e.getValue()==null ? 0 : e.getValue().hashCode())</pre> | ||
| 664 | * This ensures that {@code e1.equals(e2)} implies that | ||
| 665 | * {@code e1.hashCode()==e2.hashCode()} for any two Entries | ||
| 666 | * {@code e1} and {@code e2}, as required by the general | ||
| 667 | * contract of {@link Object#hashCode}. | ||
| 668 | * | ||
| 669 | * @return the hash code value for this map entry | ||
| 670 | * @see #equals | ||
| 671 | */ | ||
| 672 | public int hashCode() { | ||
| 673 | return (key == null ? 0 : key.hashCode()) ^ | ||
| 674 | (value == null ? 0 : value.hashCode()); | ||
| 675 | } | ||
| 676 | |||
| 677 | /** | ||
| 678 | * Returns a String representation of this map entry. This | ||
| 679 | * implementation returns the string representation of this | ||
| 680 | * entry's key followed by the equals character ("<tt>=</tt>") | ||
| 681 | * followed by the string representation of this entry's value. | ||
| 682 | * | ||
| 683 | * @return a String representation of this map entry | ||
| 684 | */ | ||
| 685 | public String toString() { | ||
| 686 | return key + "=" + value; | ||
| 687 | } | ||
| 688 | |||
| 689 | } | ||
| 690 | |||
| 691 | /** | ||
| 692 | * An Entry maintaining an immutable key and value. This class | ||
| 693 | * does not support method <tt>setValue</tt>. This class may be | ||
| 694 | * convenient in methods that return thread-safe snapshots of | ||
| 695 | * key-value mappings. | ||
| 696 | * | ||
| 697 | * @since 1.6 | ||
| 698 | */ | ||
| 699 | public static class SimpleImmutableEntry<K,V> | ||
| 700 | implements Entry<K,V>, java.io.Serializable | ||
| 701 | { | ||
| 702 | private static final long serialVersionUID = 7138329143949025153L; | ||
| 703 | |||
| 704 | private final K key; | ||
| 705 | private final V value; | ||
| 706 | |||
| 707 | /** | ||
| 708 | * Creates an entry representing a mapping from the specified | ||
| 709 | * key to the specified value. | ||
| 710 | * | ||
| 711 | * @param key the key represented by this entry | ||
| 712 | * @param value the value represented by this entry | ||
| 713 | */ | ||
| 714 | public SimpleImmutableEntry(K key, V value) { | ||
| 715 | this.key = key; | ||
| 716 | this.value = value; | ||
| 717 | } | ||
| 718 | |||
| 719 | /** | ||
| 720 | * Creates an entry representing the same mapping as the | ||
| 721 | * specified entry. | ||
| 722 | * | ||
| 723 | * @param entry the entry to copy | ||
| 724 | */ | ||
| 725 | public SimpleImmutableEntry(Entry<? extends K, ? extends V> entry) { | ||
| 726 | this.key = entry.getKey(); | ||
| 727 | this.value = entry.getValue(); | ||
| 728 | } | ||
| 729 | |||
| 730 | /** | ||
| 731 | * Returns the key corresponding to this entry. | ||
| 732 | * | ||
| 733 | * @return the key corresponding to this entry | ||
| 734 | */ | ||
| 735 | public K getKey() { | ||
| 736 | return key; | ||
| 737 | } | ||
| 738 | |||
| 739 | /** | ||
| 740 | * Returns the value corresponding to this entry. | ||
| 741 | * | ||
| 742 | * @return the value corresponding to this entry | ||
| 743 | */ | ||
| 744 | public V getValue() { | ||
| 745 | return value; | ||
| 746 | } | ||
| 747 | |||
| 748 | /** | ||
| 749 | * Replaces the value corresponding to this entry with the specified | ||
| 750 | * value (optional operation). This implementation simply throws | ||
| 751 | * <tt>UnsupportedOperationException</tt>, as this class implements | ||
| 752 | * an <i>immutable</i> map entry. | ||
| 753 | * | ||
| 754 | * @param value new value to be stored in this entry | ||
| 755 | * @return (Does not return) | ||
| 756 | * @throws UnsupportedOperationException always | ||
| 757 | */ | ||
| 758 | public V setValue(V value) { | ||
| 759 | throw new UnsupportedOperationException(); | ||
| 760 | } | ||
| 761 | |||
| 762 | /** | ||
| 763 | * Compares the specified object with this entry for equality. | ||
| 764 | * Returns {@code true} if the given object is also a map entry and | ||
| 765 | * the two entries represent the same mapping. More formally, two | ||
| 766 | * entries {@code e1} and {@code e2} represent the same mapping | ||
| 767 | * if<pre> | ||
| 768 | * (e1.getKey()==null ? | ||
| 769 | * e2.getKey()==null : | ||
| 770 | * e1.getKey().equals(e2.getKey())) | ||
| 771 | * && | ||
| 772 | * (e1.getValue()==null ? | ||
| 773 | * e2.getValue()==null : | ||
| 774 | * e1.getValue().equals(e2.getValue()))</pre> | ||
| 775 | * This ensures that the {@code equals} method works properly across | ||
| 776 | * different implementations of the {@code Map.Entry} interface. | ||
| 777 | * | ||
| 778 | * @param o object to be compared for equality with this map entry | ||
| 779 | * @return {@code true} if the specified object is equal to this map | ||
| 780 | * entry | ||
| 781 | * @see #hashCode | ||
| 782 | */ | ||
| 783 | public boolean equals(Object o) { | ||
| 784 | if (!(o instanceof Map.Entry)) | ||
| 785 | return false; | ||
| 786 | Map.Entry e = (Map.Entry)o; | ||
| 787 | return eq(key, e.getKey()) && eq(value, e.getValue()); | ||
| 788 | } | ||
| 789 | |||
| 790 | /** | ||
| 791 | * Returns the hash code value for this map entry. The hash code | ||
| 792 | * of a map entry {@code e} is defined to be: <pre> | ||
| 793 | * (e.getKey()==null ? 0 : e.getKey().hashCode()) ^ | ||
| 794 | * (e.getValue()==null ? 0 : e.getValue().hashCode())</pre> | ||
| 795 | * This ensures that {@code e1.equals(e2)} implies that | ||
| 796 | * {@code e1.hashCode()==e2.hashCode()} for any two Entries | ||
| 797 | * {@code e1} and {@code e2}, as required by the general | ||
| 798 | * contract of {@link Object#hashCode}. | ||
| 799 | * | ||
| 800 | * @return the hash code value for this map entry | ||
| 801 | * @see #equals | ||
| 802 | */ | ||
| 803 | public int hashCode() { | ||
| 804 | return (key == null ? 0 : key.hashCode()) ^ | ||
| 805 | (value == null ? 0 : value.hashCode()); | ||
| 806 | } | ||
| 807 | |||
| 808 | /** | ||
| 809 | * Returns a String representation of this map entry. This | ||
| 810 | * implementation returns the string representation of this | ||
| 811 | * entry's key followed by the equals character ("<tt>=</tt>") | ||
| 812 | * followed by the string representation of this entry's value. | ||
| 813 | * | ||
| 814 | * @return a String representation of this map entry | ||
| 815 | */ | ||
| 816 | public String toString() { | ||
| 817 | return key + "=" + value; | ||
| 818 | } | ||
| 819 | |||
| 820 | } | ||
| 821 | |||
| 822 | } | ||
Binary file not shown.
| @@ -0,0 +1,192 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 | ||
| 32 | * Expert Group and released to the public domain, as explained at | ||
| 33 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util; | ||
| 37 | |||
| 38 | /** | ||
| 39 | * This class provides skeletal implementations of some {@link Queue} | ||
| 40 | * operations. The implementations in this class are appropriate when | ||
| 41 | * the base implementation does <em>not</em> allow <tt>null</tt> | ||
| 42 | * elements. Methods {@link #add add}, {@link #remove remove}, and | ||
| 43 | * {@link #element element} are based on {@link #offer offer}, {@link | ||
| 44 | * #poll poll}, and {@link #peek peek}, respectively, but throw | ||
| 45 | * exceptions instead of indicating failure via <tt>false</tt> or | ||
| 46 | * <tt>null</tt> returns. | ||
| 47 | * | ||
| 48 | * <p>A <tt>Queue</tt> implementation that extends this class must | ||
| 49 | * minimally define a method {@link Queue#offer} which does not permit | ||
| 50 | * insertion of <tt>null</tt> elements, along with methods {@link | ||
| 51 | * Queue#peek}, {@link Queue#poll}, {@link Collection#size}, and | ||
| 52 | * {@link Collection#iterator}. Typically, additional methods will be | ||
| 53 | * overridden as well. If these requirements cannot be met, consider | ||
| 54 | * instead subclassing {@link AbstractCollection}. | ||
| 55 | * | ||
| 56 | * <p>This class is a member of the | ||
| 57 | * <a href="{@docRoot}/../technotes/guides/collections/index.html"> | ||
| 58 | * Java Collections Framework</a>. | ||
| 59 | * | ||
| 60 | * @since 1.5 | ||
| 61 | * @author Doug Lea | ||
| 62 | * @param <E> the type of elements held in this collection | ||
| 63 | */ | ||
| 64 | public abstract class AbstractQueue<E> | ||
| 65 | extends AbstractCollection<E> | ||
| 66 | implements Queue<E> { | ||
| 67 | |||
| 68 | /** | ||
| 69 | * Constructor for use by subclasses. | ||
| 70 | */ | ||
| 71 | protected AbstractQueue() { | ||
| 72 | } | ||
| 73 | |||
| 74 | /** | ||
| 75 | * Inserts the specified element into this queue if it is possible to do so | ||
| 76 | * immediately without violating capacity restrictions, returning | ||
| 77 | * <tt>true</tt> upon success and throwing an <tt>IllegalStateException</tt> | ||
| 78 | * if no space is currently available. | ||
| 79 | * | ||
| 80 | * <p>This implementation returns <tt>true</tt> if <tt>offer</tt> succeeds, | ||
| 81 | * else throws an <tt>IllegalStateException</tt>. | ||
| 82 | * | ||
| 83 | * @param e the element to add | ||
| 84 | * @return <tt>true</tt> (as specified by {@link Collection#add}) | ||
| 85 | * @throws IllegalStateException if the element cannot be added at this | ||
| 86 | * time due to capacity restrictions | ||
| 87 | * @throws ClassCastException if the class of the specified element | ||
| 88 | * prevents it from being added to this queue | ||
| 89 | * @throws NullPointerException if the specified element is null and | ||
| 90 | * this queue does not permit null elements | ||
| 91 | * @throws IllegalArgumentException if some property of this element | ||
| 92 | * prevents it from being added to this queue | ||
| 93 | */ | ||
| 94 | public boolean add(E e) { | ||
| 95 | if (offer(e)) | ||
| 96 | return true; | ||
| 97 | else | ||
| 98 | throw new IllegalStateException("Queue full"); | ||
| 99 | } | ||
| 100 | |||
| 101 | /** | ||
| 102 | * Retrieves and removes the head of this queue. This method differs | ||
| 103 | * from {@link #poll poll} only in that it throws an exception if this | ||
| 104 | * queue is empty. | ||
| 105 | * | ||
| 106 | * <p>This implementation returns the result of <tt>poll</tt> | ||
| 107 | * unless the queue is empty. | ||
| 108 | * | ||
| 109 | * @return the head of this queue | ||
| 110 | * @throws NoSuchElementException if this queue is empty | ||
| 111 | */ | ||
| 112 | public E remove() { | ||
| 113 | E x = poll(); | ||
| 114 | if (x != null) | ||
| 115 | return x; | ||
| 116 | else | ||
| 117 | throw new NoSuchElementException(); | ||
| 118 | } | ||
| 119 | |||
| 120 | /** | ||
| 121 | * Retrieves, but does not remove, the head of this queue. This method | ||
| 122 | * differs from {@link #peek peek} only in that it throws an exception if | ||
| 123 | * this queue is empty. | ||
| 124 | * | ||
| 125 | * <p>This implementation returns the result of <tt>peek</tt> | ||
| 126 | * unless the queue is empty. | ||
| 127 | * | ||
| 128 | * @return the head of this queue | ||
| 129 | * @throws NoSuchElementException if this queue is empty | ||
| 130 | */ | ||
| 131 | public E element() { | ||
| 132 | E x = peek(); | ||
| 133 | if (x != null) | ||
| 134 | return x; | ||
| 135 | else | ||
| 136 | throw new NoSuchElementException(); | ||
| 137 | } | ||
| 138 | |||
| 139 | /** | ||
| 140 | * Removes all of the elements from this queue. | ||
| 141 | * The queue will be empty after this call returns. | ||
| 142 | * | ||
| 143 | * <p>This implementation repeatedly invokes {@link #poll poll} until it | ||
| 144 | * returns <tt>null</tt>. | ||
| 145 | */ | ||
| 146 | public void clear() { | ||
| 147 | while (poll() != null) | ||
| 148 | ; | ||
| 149 | } | ||
| 150 | |||
| 151 | /** | ||
| 152 | * Adds all of the elements in the specified collection to this | ||
| 153 | * queue. Attempts to addAll of a queue to itself result in | ||
| 154 | * <tt>IllegalArgumentException</tt>. Further, the behavior of | ||
| 155 | * this operation is undefined if the specified collection is | ||
| 156 | * modified while the operation is in progress. | ||
| 157 | * | ||
| 158 | * <p>This implementation iterates over the specified collection, | ||
| 159 | * and adds each element returned by the iterator to this | ||
| 160 | * queue, in turn. A runtime exception encountered while | ||
| 161 | * trying to add an element (including, in particular, a | ||
| 162 | * <tt>null</tt> element) may result in only some of the elements | ||
| 163 | * having been successfully added when the associated exception is | ||
| 164 | * thrown. | ||
| 165 | * | ||
| 166 | * @param c collection containing elements to be added to this queue | ||
| 167 | * @return <tt>true</tt> if this queue changed as a result of the call | ||
| 168 | * @throws ClassCastException if the class of an element of the specified | ||
| 169 | * collection prevents it from being added to this queue | ||
| 170 | * @throws NullPointerException if the specified collection contains a | ||
| 171 | * null element and this queue does not permit null elements, | ||
| 172 | * or if the specified collection is null | ||
| 173 | * @throws IllegalArgumentException if some property of an element of the | ||
| 174 | * specified collection prevents it from being added to this | ||
| 175 | * queue, or if the specified collection is this queue | ||
| 176 | * @throws IllegalStateException if not all the elements can be added at | ||
| 177 | * this time due to insertion restrictions | ||
| 178 | * @see #add(Object) | ||
| 179 | */ | ||
| 180 | public boolean addAll(Collection<? extends E> c) { | ||
| 181 | if (c == null) | ||
| 182 | throw new NullPointerException(); | ||
| 183 | if (c == this) | ||
| 184 | throw new IllegalArgumentException(); | ||
| 185 | boolean modified = false; | ||
| 186 | for (E e : c) | ||
| 187 | if (add(e)) | ||
| 188 | modified = true; | ||
| 189 | return modified; | ||
| 190 | } | ||
| 191 | |||
| 192 | } | ||
Binary file not shown.
| @@ -0,0 +1,253 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package java.util; | ||
| 27 | |||
| 28 | /** | ||
| 29 | * This class provides a skeletal implementation of the <tt>List</tt> | ||
| 30 | * interface to minimize the effort required to implement this interface | ||
| 31 | * backed by a "sequential access" data store (such as a linked list). For | ||
| 32 | * random access data (such as an array), <tt>AbstractList</tt> should be used | ||
| 33 | * in preference to this class.<p> | ||
| 34 | * | ||
| 35 | * This class is the opposite of the <tt>AbstractList</tt> class in the sense | ||
| 36 | * that it implements the "random access" methods (<tt>get(int index)</tt>, | ||
| 37 | * <tt>set(int index, E element)</tt>, <tt>add(int index, E element)</tt> and | ||
| 38 | * <tt>remove(int index)</tt>) on top of the list's list iterator, instead of | ||
| 39 | * the other way around.<p> | ||
| 40 | * | ||
| 41 | * To implement a list the programmer needs only to extend this class and | ||
| 42 | * provide implementations for the <tt>listIterator</tt> and <tt>size</tt> | ||
| 43 | * methods. For an unmodifiable list, the programmer need only implement the | ||
| 44 | * list iterator's <tt>hasNext</tt>, <tt>next</tt>, <tt>hasPrevious</tt>, | ||
| 45 | * <tt>previous</tt> and <tt>index</tt> methods.<p> | ||
| 46 | * | ||
| 47 | * For a modifiable list the programmer should additionally implement the list | ||
| 48 | * iterator's <tt>set</tt> method. For a variable-size list the programmer | ||
| 49 | * should additionally implement the list iterator's <tt>remove</tt> and | ||
| 50 | * <tt>add</tt> methods.<p> | ||
| 51 | * | ||
| 52 | * The programmer should generally provide a void (no argument) and collection | ||
| 53 | * constructor, as per the recommendation in the <tt>Collection</tt> interface | ||
| 54 | * specification.<p> | ||
| 55 | * | ||
| 56 | * This class is a member of the | ||
| 57 | * <a href="{@docRoot}/../technotes/guides/collections/index.html"> | ||
| 58 | * Java Collections Framework</a>. | ||
| 59 | * | ||
| 60 | * @author Josh Bloch | ||
| 61 | * @author Neal Gafter | ||
| 62 | * @see Collection | ||
| 63 | * @see List | ||
| 64 | * @see AbstractList | ||
| 65 | * @see AbstractCollection | ||
| 66 | * @since 1.2 | ||
| 67 | */ | ||
| 68 | |||
| 69 | public abstract class AbstractSequentialList<E> extends AbstractList<E> { | ||
| 70 | /** | ||
| 71 | * Sole constructor. (For invocation by subclass constructors, typically | ||
| 72 | * implicit.) | ||
| 73 | */ | ||
| 74 | protected AbstractSequentialList() { | ||
| 75 | } | ||
| 76 | |||
| 77 | /** | ||
| 78 | * Returns the element at the specified position in this list. | ||
| 79 | * | ||
| 80 | * <p>This implementation first gets a list iterator pointing to the | ||
| 81 | * indexed element (with <tt>listIterator(index)</tt>). Then, it gets | ||
| 82 | * the element using <tt>ListIterator.next</tt> and returns it. | ||
| 83 | * | ||
| 84 | * @throws IndexOutOfBoundsException {@inheritDoc} | ||
| 85 | */ | ||
| 86 | public E get(int index) { | ||
| 87 | try { | ||
| 88 | return listIterator(index).next(); | ||
| 89 | } catch (NoSuchElementException exc) { | ||
| 90 | throw new IndexOutOfBoundsException("Index: "+index); | ||
| 91 | } | ||
| 92 | } | ||
| 93 | |||
| 94 | /** | ||
| 95 | * Replaces the element at the specified position in this list with the | ||
| 96 | * specified element (optional operation). | ||
| 97 | * | ||
| 98 | * <p>This implementation first gets a list iterator pointing to the | ||
| 99 | * indexed element (with <tt>listIterator(index)</tt>). Then, it gets | ||
| 100 | * the current element using <tt>ListIterator.next</tt> and replaces it | ||
| 101 | * with <tt>ListIterator.set</tt>. | ||
| 102 | * | ||
| 103 | * <p>Note that this implementation will throw an | ||
| 104 | * <tt>UnsupportedOperationException</tt> if the list iterator does not | ||
| 105 | * implement the <tt>set</tt> operation. | ||
| 106 | * | ||
| 107 | * @throws UnsupportedOperationException {@inheritDoc} | ||
| 108 | * @throws ClassCastException {@inheritDoc} | ||
| 109 | * @throws NullPointerException {@inheritDoc} | ||
| 110 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 111 | * @throws IndexOutOfBoundsException {@inheritDoc} | ||
| 112 | */ | ||
| 113 | public E set(int index, E element) { | ||
| 114 | try { | ||
| 115 | ListIterator<E> e = listIterator(index); | ||
| 116 | E oldVal = e.next(); | ||
| 117 | e.set(element); | ||
| 118 | return oldVal; | ||
| 119 | } catch (NoSuchElementException exc) { | ||
| 120 | throw new IndexOutOfBoundsException("Index: "+index); | ||
| 121 | } | ||
| 122 | } | ||
| 123 | |||
| 124 | /** | ||
| 125 | * Inserts the specified element at the specified position in this list | ||
| 126 | * (optional operation). Shifts the element currently at that position | ||
| 127 | * (if any) and any subsequent elements to the right (adds one to their | ||
| 128 | * indices). | ||
| 129 | * | ||
| 130 | * <p>This implementation first gets a list iterator pointing to the | ||
| 131 | * indexed element (with <tt>listIterator(index)</tt>). Then, it | ||
| 132 | * inserts the specified element with <tt>ListIterator.add</tt>. | ||
| 133 | * | ||
| 134 | * <p>Note that this implementation will throw an | ||
| 135 | * <tt>UnsupportedOperationException</tt> if the list iterator does not | ||
| 136 | * implement the <tt>add</tt> operation. | ||
| 137 | * | ||
| 138 | * @throws UnsupportedOperationException {@inheritDoc} | ||
| 139 | * @throws ClassCastException {@inheritDoc} | ||
| 140 | * @throws NullPointerException {@inheritDoc} | ||
| 141 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 142 | * @throws IndexOutOfBoundsException {@inheritDoc} | ||
| 143 | */ | ||
| 144 | public void add(int index, E element) { | ||
| 145 | try { | ||
| 146 | listIterator(index).add(element); | ||
| 147 | } catch (NoSuchElementException exc) { | ||
| 148 | throw new IndexOutOfBoundsException("Index: "+index); | ||
| 149 | } | ||
| 150 | } | ||
| 151 | |||
| 152 | /** | ||
| 153 | * Removes the element at the specified position in this list (optional | ||
| 154 | * operation). Shifts any subsequent elements to the left (subtracts one | ||
| 155 | * from their indices). Returns the element that was removed from the | ||
| 156 | * list. | ||
| 157 | * | ||
| 158 | * <p>This implementation first gets a list iterator pointing to the | ||
| 159 | * indexed element (with <tt>listIterator(index)</tt>). Then, it removes | ||
| 160 | * the element with <tt>ListIterator.remove</tt>. | ||
| 161 | * | ||
| 162 | * <p>Note that this implementation will throw an | ||
| 163 | * <tt>UnsupportedOperationException</tt> if the list iterator does not | ||
| 164 | * implement the <tt>remove</tt> operation. | ||
| 165 | * | ||
| 166 | * @throws UnsupportedOperationException {@inheritDoc} | ||
| 167 | * @throws IndexOutOfBoundsException {@inheritDoc} | ||
| 168 | */ | ||
| 169 | public E remove(int index) { | ||
| 170 | try { | ||
| 171 | ListIterator<E> e = listIterator(index); | ||
| 172 | E outCast = e.next(); | ||
| 173 | e.remove(); | ||
| 174 | return outCast; | ||
| 175 | } catch (NoSuchElementException exc) { | ||
| 176 | throw new IndexOutOfBoundsException("Index: "+index); | ||
| 177 | } | ||
| 178 | } | ||
| 179 | |||
| 180 | |||
| 181 | // Bulk Operations | ||
| 182 | |||
| 183 | /** | ||
| 184 | * Inserts all of the elements in the specified collection into this | ||
| 185 | * list at the specified position (optional operation). Shifts the | ||
| 186 | * element currently at that position (if any) and any subsequent | ||
| 187 | * elements to the right (increases their indices). The new elements | ||
| 188 | * will appear in this list in the order that they are returned by the | ||
| 189 | * specified collection's iterator. The behavior of this operation is | ||
| 190 | * undefined if the specified collection is modified while the | ||
| 191 | * operation is in progress. (Note that this will occur if the specified | ||
| 192 | * collection is this list, and it's nonempty.) | ||
| 193 | * | ||
| 194 | * <p>This implementation gets an iterator over the specified collection and | ||
| 195 | * a list iterator over this list pointing to the indexed element (with | ||
| 196 | * <tt>listIterator(index)</tt>). Then, it iterates over the specified | ||
| 197 | * collection, inserting the elements obtained from the iterator into this | ||
| 198 | * list, one at a time, using <tt>ListIterator.add</tt> followed by | ||
| 199 | * <tt>ListIterator.next</tt> (to skip over the added element). | ||
| 200 | * | ||
| 201 | * <p>Note that this implementation will throw an | ||
| 202 | * <tt>UnsupportedOperationException</tt> if the list iterator returned by | ||
| 203 | * the <tt>listIterator</tt> method does not implement the <tt>add</tt> | ||
| 204 | * operation. | ||
| 205 | * | ||
| 206 | * @throws UnsupportedOperationException {@inheritDoc} | ||
| 207 | * @throws ClassCastException {@inheritDoc} | ||
| 208 | * @throws NullPointerException {@inheritDoc} | ||
| 209 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 210 | * @throws IndexOutOfBoundsException {@inheritDoc} | ||
| 211 | */ | ||
| 212 | public boolean addAll(int index, Collection<? extends E> c) { | ||
| 213 | try { | ||
| 214 | boolean modified = false; | ||
| 215 | ListIterator<E> e1 = listIterator(index); | ||
| 216 | Iterator<? extends E> e2 = c.iterator(); | ||
| 217 | while (e2.hasNext()) { | ||
| 218 | e1.add(e2.next()); | ||
| 219 | modified = true; | ||
| 220 | } | ||
| 221 | return modified; | ||
| 222 | } catch (NoSuchElementException exc) { | ||
| 223 | throw new IndexOutOfBoundsException("Index: "+index); | ||
| 224 | } | ||
| 225 | } | ||
| 226 | |||
| 227 | |||
| 228 | // Iterators | ||
| 229 | |||
| 230 | /** | ||
| 231 | * Returns an iterator over the elements in this list (in proper | ||
| 232 | * sequence).<p> | ||
| 233 | * | ||
| 234 | * This implementation merely returns a list iterator over the list. | ||
| 235 | * | ||
| 236 | * @return an iterator over the elements in this list (in proper sequence) | ||
| 237 | */ | ||
| 238 | public Iterator<E> iterator() { | ||
| 239 | return listIterator(); | ||
| 240 | } | ||
| 241 | |||
| 242 | /** | ||
| 243 | * Returns a list iterator over the elements in this list (in proper | ||
| 244 | * sequence). | ||
| 245 | * | ||
| 246 | * @param index index of first element to be returned from the list | ||
| 247 | * iterator (by a call to the <code>next</code> method) | ||
| 248 | * @return a list iterator over the elements in this list (in proper | ||
| 249 | * sequence) | ||
| 250 | * @throws IndexOutOfBoundsException {@inheritDoc} | ||
| 251 | */ | ||
| 252 | public abstract ListIterator<E> listIterator(int index); | ||
| 253 | } | ||
Binary file not shown.
| @@ -0,0 +1,185 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package java.util; | ||
| 27 | |||
| 28 | /** | ||
| 29 | * This class provides a skeletal implementation of the <tt>Set</tt> | ||
| 30 | * interface to minimize the effort required to implement this | ||
| 31 | * interface. <p> | ||
| 32 | * | ||
| 33 | * The process of implementing a set by extending this class is identical | ||
| 34 | * to that of implementing a Collection by extending AbstractCollection, | ||
| 35 | * except that all of the methods and constructors in subclasses of this | ||
| 36 | * class must obey the additional constraints imposed by the <tt>Set</tt> | ||
| 37 | * interface (for instance, the add method must not permit addition of | ||
| 38 | * multiple instances of an object to a set).<p> | ||
| 39 | * | ||
| 40 | * Note that this class does not override any of the implementations from | ||
| 41 | * the <tt>AbstractCollection</tt> class. It merely adds implementations | ||
| 42 | * for <tt>equals</tt> and <tt>hashCode</tt>.<p> | ||
| 43 | * | ||
| 44 | * This class is a member of the | ||
| 45 | * <a href="{@docRoot}/../technotes/guides/collections/index.html"> | ||
| 46 | * Java Collections Framework</a>. | ||
| 47 | * | ||
| 48 | * @param <E> the type of elements maintained by this set | ||
| 49 | * | ||
| 50 | * @author Josh Bloch | ||
| 51 | * @author Neal Gafter | ||
| 52 | * @see Collection | ||
| 53 | * @see AbstractCollection | ||
| 54 | * @see Set | ||
| 55 | * @since 1.2 | ||
| 56 | */ | ||
| 57 | |||
| 58 | public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> { | ||
| 59 | /** | ||
| 60 | * Sole constructor. (For invocation by subclass constructors, typically | ||
| 61 | * implicit.) | ||
| 62 | */ | ||
| 63 | protected AbstractSet() { | ||
| 64 | } | ||
| 65 | |||
| 66 | // Comparison and hashing | ||
| 67 | |||
| 68 | /** | ||
| 69 | * Compares the specified object with this set for equality. Returns | ||
| 70 | * <tt>true</tt> if the given object is also a set, the two sets have | ||
| 71 | * the same size, and every member of the given set is contained in | ||
| 72 | * this set. This ensures that the <tt>equals</tt> method works | ||
| 73 | * properly across different implementations of the <tt>Set</tt> | ||
| 74 | * interface.<p> | ||
| 75 | * | ||
| 76 | * This implementation first checks if the specified object is this | ||
| 77 | * set; if so it returns <tt>true</tt>. Then, it checks if the | ||
| 78 | * specified object is a set whose size is identical to the size of | ||
| 79 | * this set; if not, it returns false. If so, it returns | ||
| 80 | * <tt>containsAll((Collection) o)</tt>. | ||
| 81 | * | ||
| 82 | * @param o object to be compared for equality with this set | ||
| 83 | * @return <tt>true</tt> if the specified object is equal to this set | ||
| 84 | */ | ||
| 85 | public boolean equals(Object o) { | ||
| 86 | if (o == this) | ||
| 87 | return true; | ||
| 88 | |||
| 89 | if (!(o instanceof Set)) | ||
| 90 | return false; | ||
| 91 | Collection c = (Collection) o; | ||
| 92 | if (c.size() != size()) | ||
| 93 | return false; | ||
| 94 | try { | ||
| 95 | return containsAll(c); | ||
| 96 | } catch (ClassCastException unused) { | ||
| 97 | return false; | ||
| 98 | } catch (NullPointerException unused) { | ||
| 99 | return false; | ||
| 100 | } | ||
| 101 | } | ||
| 102 | |||
| 103 | /** | ||
| 104 | * Returns the hash code value for this set. The hash code of a set is | ||
| 105 | * defined to be the sum of the hash codes of the elements in the set, | ||
| 106 | * where the hash code of a <tt>null</tt> element is defined to be zero. | ||
| 107 | * This ensures that <tt>s1.equals(s2)</tt> implies that | ||
| 108 | * <tt>s1.hashCode()==s2.hashCode()</tt> for any two sets <tt>s1</tt> | ||
| 109 | * and <tt>s2</tt>, as required by the general contract of | ||
| 110 | * {@link Object#hashCode}. | ||
| 111 | * | ||
| 112 | * <p>This implementation iterates over the set, calling the | ||
| 113 | * <tt>hashCode</tt> method on each element in the set, and adding up | ||
| 114 | * the results. | ||
| 115 | * | ||
| 116 | * @return the hash code value for this set | ||
| 117 | * @see Object#equals(Object) | ||
| 118 | * @see Set#equals(Object) | ||
| 119 | */ | ||
| 120 | public int hashCode() { | ||
| 121 | int h = 0; | ||
| 122 | Iterator<E> i = iterator(); | ||
| 123 | while (i.hasNext()) { | ||
| 124 | E obj = i.next(); | ||
| 125 | if (obj != null) | ||
| 126 | h += obj.hashCode(); | ||
| 127 | } | ||
| 128 | return h; | ||
| 129 | } | ||
| 130 | |||
| 131 | /** | ||
| 132 | * Removes from this set all of its elements that are contained in the | ||
| 133 | * specified collection (optional operation). If the specified | ||
| 134 | * collection is also a set, this operation effectively modifies this | ||
| 135 | * set so that its value is the <i>asymmetric set difference</i> of | ||
| 136 | * the two sets. | ||
| 137 | * | ||
| 138 | * <p>This implementation determines which is the smaller of this set | ||
| 139 | * and the specified collection, by invoking the <tt>size</tt> | ||
| 140 | * method on each. If this set has fewer elements, then the | ||
| 141 | * implementation iterates over this set, checking each element | ||
| 142 | * returned by the iterator in turn to see if it is contained in | ||
| 143 | * the specified collection. If it is so contained, it is removed | ||
| 144 | * from this set with the iterator's <tt>remove</tt> method. If | ||
| 145 | * the specified collection has fewer elements, then the | ||
| 146 | * implementation iterates over the specified collection, removing | ||
| 147 | * from this set each element returned by the iterator, using this | ||
| 148 | * set's <tt>remove</tt> method. | ||
| 149 | * | ||
| 150 | * <p>Note that this implementation will throw an | ||
| 151 | * <tt>UnsupportedOperationException</tt> if the iterator returned by the | ||
| 152 | * <tt>iterator</tt> method does not implement the <tt>remove</tt> method. | ||
| 153 | * | ||
| 154 | * @param c collection containing elements to be removed from this set | ||
| 155 | * @return <tt>true</tt> if this set changed as a result of the call | ||
| 156 | * @throws UnsupportedOperationException if the <tt>removeAll</tt> operation | ||
| 157 | * is not supported by this set | ||
| 158 | * @throws ClassCastException if the class of an element of this set | ||
| 159 | * is incompatible with the specified collection | ||
| 160 | * (<a href="Collection.html#optional-restrictions">optional</a>) | ||
| 161 | * @throws NullPointerException if this set contains a null element and the | ||
| 162 | * specified collection does not permit null elements | ||
| 163 | * (<a href="Collection.html#optional-restrictions">optional</a>), | ||
| 164 | * or if the specified collection is null | ||
| 165 | * @see #remove(Object) | ||
| 166 | * @see #contains(Object) | ||
| 167 | */ | ||
| 168 | public boolean removeAll(Collection<?> c) { | ||
| 169 | boolean modified = false; | ||
| 170 | |||
| 171 | if (size() > c.size()) { | ||
| 172 | for (Iterator<?> i = c.iterator(); i.hasNext(); ) | ||
| 173 | modified |= remove(i.next()); | ||
| 174 | } else { | ||
| 175 | for (Iterator<?> i = iterator(); i.hasNext(); ) { | ||
| 176 | if (c.contains(i.next())) { | ||
| 177 | i.remove(); | ||
| 178 | modified = true; | ||
| 179 | } | ||
| 180 | } | ||
| 181 | } | ||
| 182 | return modified; | ||
| 183 | } | ||
| 184 | |||
| 185 | } | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,866 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Josh Bloch of Google Inc. and released to the public domain, | ||
| 32 | * as explained at http://creativecommons.org/publicdomain/zero/1.0/. | ||
| 33 | */ | ||
| 34 | |||
| 35 | package java.util; | ||
| 36 | import java.io.*; | ||
| 37 | |||
| 38 | /** | ||
| 39 | * Resizable-array implementation of the {@link Deque} interface. Array | ||
| 40 | * deques have no capacity restrictions; they grow as necessary to support | ||
| 41 | * usage. They are not thread-safe; in the absence of external | ||
| 42 | * synchronization, they do not support concurrent access by multiple threads. | ||
| 43 | * Null elements are prohibited. This class is likely to be faster than | ||
| 44 | * {@link Stack} when used as a stack, and faster than {@link LinkedList} | ||
| 45 | * when used as a queue. | ||
| 46 | * | ||
| 47 | * <p>Most <tt>ArrayDeque</tt> operations run in amortized constant time. | ||
| 48 | * Exceptions include {@link #remove(Object) remove}, {@link | ||
| 49 | * #removeFirstOccurrence removeFirstOccurrence}, {@link #removeLastOccurrence | ||
| 50 | * removeLastOccurrence}, {@link #contains contains}, {@link #iterator | ||
| 51 | * iterator.remove()}, and the bulk operations, all of which run in linear | ||
| 52 | * time. | ||
| 53 | * | ||
| 54 | * <p>The iterators returned by this class's <tt>iterator</tt> method are | ||
| 55 | * <i>fail-fast</i>: If the deque is modified at any time after the iterator | ||
| 56 | * is created, in any way except through the iterator's own <tt>remove</tt> | ||
| 57 | * method, the iterator will generally throw a {@link | ||
| 58 | * ConcurrentModificationException}. Thus, in the face of concurrent | ||
| 59 | * modification, the iterator fails quickly and cleanly, rather than risking | ||
| 60 | * arbitrary, non-deterministic behavior at an undetermined time in the | ||
| 61 | * future. | ||
| 62 | * | ||
| 63 | * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed | ||
| 64 | * as it is, generally speaking, impossible to make any hard guarantees in the | ||
| 65 | * presence of unsynchronized concurrent modification. Fail-fast iterators | ||
| 66 | * throw <tt>ConcurrentModificationException</tt> on a best-effort basis. | ||
| 67 | * Therefore, it would be wrong to write a program that depended on this | ||
| 68 | * exception for its correctness: <i>the fail-fast behavior of iterators | ||
| 69 | * should be used only to detect bugs.</i> | ||
| 70 | * | ||
| 71 | * <p>This class and its iterator implement all of the | ||
| 72 | * <em>optional</em> methods of the {@link Collection} and {@link | ||
| 73 | * Iterator} interfaces. | ||
| 74 | * | ||
| 75 | * <p>This class is a member of the | ||
| 76 | * <a href="{@docRoot}/../technotes/guides/collections/index.html"> | ||
| 77 | * Java Collections Framework</a>. | ||
| 78 | * | ||
| 79 | * @author Josh Bloch and Doug Lea | ||
| 80 | * @since 1.6 | ||
| 81 | * @param <E> the type of elements held in this collection | ||
| 82 | */ | ||
| 83 | public class ArrayDeque<E> extends AbstractCollection<E> | ||
| 84 | implements Deque<E>, Cloneable, Serializable | ||
| 85 | { | ||
| 86 | /** | ||
| 87 | * The array in which the elements of the deque are stored. | ||
| 88 | * The capacity of the deque is the length of this array, which is | ||
| 89 | * always a power of two. The array is never allowed to become | ||
| 90 | * full, except transiently within an addX method where it is | ||
| 91 | * resized (see doubleCapacity) immediately upon becoming full, | ||
| 92 | * thus avoiding head and tail wrapping around to equal each | ||
| 93 | * other. We also guarantee that all array cells not holding | ||
| 94 | * deque elements are always null. | ||
| 95 | */ | ||
| 96 | private transient E[] elements; | ||
| 97 | |||
| 98 | /** | ||
| 99 | * The index of the element at the head of the deque (which is the | ||
| 100 | * element that would be removed by remove() or pop()); or an | ||
| 101 | * arbitrary number equal to tail if the deque is empty. | ||
| 102 | */ | ||
| 103 | private transient int head; | ||
| 104 | |||
| 105 | /** | ||
| 106 | * The index at which the next element would be added to the tail | ||
| 107 | * of the deque (via addLast(E), add(E), or push(E)). | ||
| 108 | */ | ||
| 109 | private transient int tail; | ||
| 110 | |||
| 111 | /** | ||
| 112 | * The minimum capacity that we'll use for a newly created deque. | ||
| 113 | * Must be a power of 2. | ||
| 114 | */ | ||
| 115 | private static final int MIN_INITIAL_CAPACITY = 8; | ||
| 116 | |||
| 117 | // ****** Array allocation and resizing utilities ****** | ||
| 118 | |||
| 119 | /** | ||
| 120 | * Allocate empty array to hold the given number of elements. | ||
| 121 | * | ||
| 122 | * @param numElements the number of elements to hold | ||
| 123 | */ | ||
| 124 | private void allocateElements(int numElements) { | ||
| 125 | int initialCapacity = MIN_INITIAL_CAPACITY; | ||
| 126 | // Find the best power of two to hold elements. | ||
| 127 | // Tests "<=" because arrays aren't kept full. | ||
| 128 | if (numElements >= initialCapacity) { | ||
| 129 | initialCapacity = numElements; | ||
| 130 | initialCapacity |= (initialCapacity >>> 1); | ||
| 131 | initialCapacity |= (initialCapacity >>> 2); | ||
| 132 | initialCapacity |= (initialCapacity >>> 4); | ||
| 133 | initialCapacity |= (initialCapacity >>> 8); | ||
| 134 | initialCapacity |= (initialCapacity >>> 16); | ||
| 135 | initialCapacity++; | ||
| 136 | |||
| 137 | if (initialCapacity < 0) // Too many elements, must back off | ||
| 138 | initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements | ||
| 139 | } | ||
| 140 | elements = (E[]) new Object[initialCapacity]; | ||
| 141 | } | ||
| 142 | |||
| 143 | /** | ||
| 144 | * Double the capacity of this deque. Call only when full, i.e., | ||
| 145 | * when head and tail have wrapped around to become equal. | ||
| 146 | */ | ||
| 147 | private void doubleCapacity() { | ||
| 148 | assert head == tail; | ||
| 149 | int p = head; | ||
| 150 | int n = elements.length; | ||
| 151 | int r = n - p; // number of elements to the right of p | ||
| 152 | int newCapacity = n << 1; | ||
| 153 | if (newCapacity < 0) | ||
| 154 | throw new IllegalStateException("Sorry, deque too big"); | ||
| 155 | Object[] a = new Object[newCapacity]; | ||
| 156 | System.arraycopy(elements, p, a, 0, r); | ||
| 157 | System.arraycopy(elements, 0, a, r, p); | ||
| 158 | elements = (E[])a; | ||
| 159 | head = 0; | ||
| 160 | tail = n; | ||
| 161 | } | ||
| 162 | |||
| 163 | /** | ||
| 164 | * Copies the elements from our element array into the specified array, | ||
| 165 | * in order (from first to last element in the deque). It is assumed | ||
| 166 | * that the array is large enough to hold all elements in the deque. | ||
| 167 | * | ||
| 168 | * @return its argument | ||
| 169 | */ | ||
| 170 | private <T> T[] copyElements(T[] a) { | ||
| 171 | if (head < tail) { | ||
| 172 | System.arraycopy(elements, head, a, 0, size()); | ||
| 173 | } else if (head > tail) { | ||
| 174 | int headPortionLen = elements.length - head; | ||
| 175 | System.arraycopy(elements, head, a, 0, headPortionLen); | ||
| 176 | System.arraycopy(elements, 0, a, headPortionLen, tail); | ||
| 177 | } | ||
| 178 | return a; | ||
| 179 | } | ||
| 180 | |||
| 181 | /** | ||
| 182 | * Constructs an empty array deque with an initial capacity | ||
| 183 | * sufficient to hold 16 elements. | ||
| 184 | */ | ||
| 185 | public ArrayDeque() { | ||
| 186 | elements = (E[]) new Object[16]; | ||
| 187 | } | ||
| 188 | |||
| 189 | /** | ||
| 190 | * Constructs an empty array deque with an initial capacity | ||
| 191 | * sufficient to hold the specified number of elements. | ||
| 192 | * | ||
| 193 | * @param numElements lower bound on initial capacity of the deque | ||
| 194 | */ | ||
| 195 | public ArrayDeque(int numElements) { | ||
| 196 | allocateElements(numElements); | ||
| 197 | } | ||
| 198 | |||
| 199 | /** | ||
| 200 | * Constructs a deque containing the elements of the specified | ||
| 201 | * collection, in the order they are returned by the collection's | ||
| 202 | * iterator. (The first element returned by the collection's | ||
| 203 | * iterator becomes the first element, or <i>front</i> of the | ||
| 204 | * deque.) | ||
| 205 | * | ||
| 206 | * @param c the collection whose elements are to be placed into the deque | ||
| 207 | * @throws NullPointerException if the specified collection is null | ||
| 208 | */ | ||
| 209 | public ArrayDeque(Collection<? extends E> c) { | ||
| 210 | allocateElements(c.size()); | ||
| 211 | addAll(c); | ||
| 212 | } | ||
| 213 | |||
| 214 | // The main insertion and extraction methods are addFirst, | ||
| 215 | // addLast, pollFirst, pollLast. The other methods are defined in | ||
| 216 | // terms of these. | ||
| 217 | |||
| 218 | /** | ||
| 219 | * Inserts the specified element at the front of this deque. | ||
| 220 | * | ||
| 221 | * @param e the element to add | ||
| 222 | * @throws NullPointerException if the specified element is null | ||
| 223 | */ | ||
| 224 | public void addFirst(E e) { | ||
| 225 | if (e == null) | ||
| 226 | throw new NullPointerException(); | ||
| 227 | elements[head = (head - 1) & (elements.length - 1)] = e; | ||
| 228 | if (head == tail) | ||
| 229 | doubleCapacity(); | ||
| 230 | } | ||
| 231 | |||
| 232 | /** | ||
| 233 | * Inserts the specified element at the end of this deque. | ||
| 234 | * | ||
| 235 | * <p>This method is equivalent to {@link #add}. | ||
| 236 | * | ||
| 237 | * @param e the element to add | ||
| 238 | * @throws NullPointerException if the specified element is null | ||
| 239 | */ | ||
| 240 | public void addLast(E e) { | ||
| 241 | if (e == null) | ||
| 242 | throw new NullPointerException(); | ||
| 243 | elements[tail] = e; | ||
| 244 | if ( (tail = (tail + 1) & (elements.length - 1)) == head) | ||
| 245 | doubleCapacity(); | ||
| 246 | } | ||
| 247 | |||
| 248 | /** | ||
| 249 | * Inserts the specified element at the front of this deque. | ||
| 250 | * | ||
| 251 | * @param e the element to add | ||
| 252 | * @return <tt>true</tt> (as specified by {@link Deque#offerFirst}) | ||
| 253 | * @throws NullPointerException if the specified element is null | ||
| 254 | */ | ||
| 255 | public boolean offerFirst(E e) { | ||
| 256 | addFirst(e); | ||
| 257 | return true; | ||
| 258 | } | ||
| 259 | |||
| 260 | /** | ||
| 261 | * Inserts the specified element at the end of this deque. | ||
| 262 | * | ||
| 263 | * @param e the element to add | ||
| 264 | * @return <tt>true</tt> (as specified by {@link Deque#offerLast}) | ||
| 265 | * @throws NullPointerException if the specified element is null | ||
| 266 | */ | ||
| 267 | public boolean offerLast(E e) { | ||
| 268 | addLast(e); | ||
| 269 | return true; | ||
| 270 | } | ||
| 271 | |||
| 272 | /** | ||
| 273 | * @throws NoSuchElementException {@inheritDoc} | ||
| 274 | */ | ||
| 275 | public E removeFirst() { | ||
| 276 | E x = pollFirst(); | ||
| 277 | if (x == null) | ||
| 278 | throw new NoSuchElementException(); | ||
| 279 | return x; | ||
| 280 | } | ||
| 281 | |||
| 282 | /** | ||
| 283 | * @throws NoSuchElementException {@inheritDoc} | ||
| 284 | */ | ||
| 285 | public E removeLast() { | ||
| 286 | E x = pollLast(); | ||
| 287 | if (x == null) | ||
| 288 | throw new NoSuchElementException(); | ||
| 289 | return x; | ||
| 290 | } | ||
| 291 | |||
| 292 | public E pollFirst() { | ||
| 293 | int h = head; | ||
| 294 | E result = elements[h]; // Element is null if deque empty | ||
| 295 | if (result == null) | ||
| 296 | return null; | ||
| 297 | elements[h] = null; // Must null out slot | ||
| 298 | head = (h + 1) & (elements.length - 1); | ||
| 299 | return result; | ||
| 300 | } | ||
| 301 | |||
| 302 | public E pollLast() { | ||
| 303 | int t = (tail - 1) & (elements.length - 1); | ||
| 304 | E result = elements[t]; | ||
| 305 | if (result == null) | ||
| 306 | return null; | ||
| 307 | elements[t] = null; | ||
| 308 | tail = t; | ||
| 309 | return result; | ||
| 310 | } | ||
| 311 | |||
| 312 | /** | ||
| 313 | * @throws NoSuchElementException {@inheritDoc} | ||
| 314 | */ | ||
| 315 | public E getFirst() { | ||
| 316 | E x = elements[head]; | ||
| 317 | if (x == null) | ||
| 318 | throw new NoSuchElementException(); | ||
| 319 | return x; | ||
| 320 | } | ||
| 321 | |||
| 322 | /** | ||
| 323 | * @throws NoSuchElementException {@inheritDoc} | ||
| 324 | */ | ||
| 325 | public E getLast() { | ||
| 326 | E x = elements[(tail - 1) & (elements.length - 1)]; | ||
| 327 | if (x == null) | ||
| 328 | throw new NoSuchElementException(); | ||
| 329 | return x; | ||
| 330 | } | ||
| 331 | |||
| 332 | public E peekFirst() { | ||
| 333 | return elements[head]; // elements[head] is null if deque empty | ||
| 334 | } | ||
| 335 | |||
| 336 | public E peekLast() { | ||
| 337 | return elements[(tail - 1) & (elements.length - 1)]; | ||
| 338 | } | ||
| 339 | |||
| 340 | /** | ||
| 341 | * Removes the first occurrence of the specified element in this | ||
| 342 | * deque (when traversing the deque from head to tail). | ||
| 343 | * If the deque does not contain the element, it is unchanged. | ||
| 344 | * More formally, removes the first element <tt>e</tt> such that | ||
| 345 | * <tt>o.equals(e)</tt> (if such an element exists). | ||
| 346 | * Returns <tt>true</tt> if this deque contained the specified element | ||
| 347 | * (or equivalently, if this deque changed as a result of the call). | ||
| 348 | * | ||
| 349 | * @param o element to be removed from this deque, if present | ||
| 350 | * @return <tt>true</tt> if the deque contained the specified element | ||
| 351 | */ | ||
| 352 | public boolean removeFirstOccurrence(Object o) { | ||
| 353 | if (o == null) | ||
| 354 | return false; | ||
| 355 | int mask = elements.length - 1; | ||
| 356 | int i = head; | ||
| 357 | E x; | ||
| 358 | while ( (x = elements[i]) != null) { | ||
| 359 | if (o.equals(x)) { | ||
| 360 | delete(i); | ||
| 361 | return true; | ||
| 362 | } | ||
| 363 | i = (i + 1) & mask; | ||
| 364 | } | ||
| 365 | return false; | ||
| 366 | } | ||
| 367 | |||
| 368 | /** | ||
| 369 | * Removes the last occurrence of the specified element in this | ||
| 370 | * deque (when traversing the deque from head to tail). | ||
| 371 | * If the deque does not contain the element, it is unchanged. | ||
| 372 | * More formally, removes the last element <tt>e</tt> such that | ||
| 373 | * <tt>o.equals(e)</tt> (if such an element exists). | ||
| 374 | * Returns <tt>true</tt> if this deque contained the specified element | ||
| 375 | * (or equivalently, if this deque changed as a result of the call). | ||
| 376 | * | ||
| 377 | * @param o element to be removed from this deque, if present | ||
| 378 | * @return <tt>true</tt> if the deque contained the specified element | ||
| 379 | */ | ||
| 380 | public boolean removeLastOccurrence(Object o) { | ||
| 381 | if (o == null) | ||
| 382 | return false; | ||
| 383 | int mask = elements.length - 1; | ||
| 384 | int i = (tail - 1) & mask; | ||
| 385 | E x; | ||
| 386 | while ( (x = elements[i]) != null) { | ||
| 387 | if (o.equals(x)) { | ||
| 388 | delete(i); | ||
| 389 | return true; | ||
| 390 | } | ||
| 391 | i = (i - 1) & mask; | ||
| 392 | } | ||
| 393 | return false; | ||
| 394 | } | ||
| 395 | |||
| 396 | // *** Queue methods *** | ||
| 397 | |||
| 398 | /** | ||
| 399 | * Inserts the specified element at the end of this deque. | ||
| 400 | * | ||
| 401 | * <p>This method is equivalent to {@link #addLast}. | ||
| 402 | * | ||
| 403 | * @param e the element to add | ||
| 404 | * @return <tt>true</tt> (as specified by {@link Collection#add}) | ||
| 405 | * @throws NullPointerException if the specified element is null | ||
| 406 | */ | ||
| 407 | public boolean add(E e) { | ||
| 408 | addLast(e); | ||
| 409 | return true; | ||
| 410 | } | ||
| 411 | |||
| 412 | /** | ||
| 413 | * Inserts the specified element at the end of this deque. | ||
| 414 | * | ||
| 415 | * <p>This method is equivalent to {@link #offerLast}. | ||
| 416 | * | ||
| 417 | * @param e the element to add | ||
| 418 | * @return <tt>true</tt> (as specified by {@link Queue#offer}) | ||
| 419 | * @throws NullPointerException if the specified element is null | ||
| 420 | */ | ||
| 421 | public boolean offer(E e) { | ||
| 422 | return offerLast(e); | ||
| 423 | } | ||
| 424 | |||
| 425 | /** | ||
| 426 | * Retrieves and removes the head of the queue represented by this deque. | ||
| 427 | * | ||
| 428 | * This method differs from {@link #poll poll} only in that it throws an | ||
| 429 | * exception if this deque is empty. | ||
| 430 | * | ||
| 431 | * <p>This method is equivalent to {@link #removeFirst}. | ||
| 432 | * | ||
| 433 | * @return the head of the queue represented by this deque | ||
| 434 | * @throws NoSuchElementException {@inheritDoc} | ||
| 435 | */ | ||
| 436 | public E remove() { | ||
| 437 | return removeFirst(); | ||
| 438 | } | ||
| 439 | |||
| 440 | /** | ||
| 441 | * Retrieves and removes the head of the queue represented by this deque | ||
| 442 | * (in other words, the first element of this deque), or returns | ||
| 443 | * <tt>null</tt> if this deque is empty. | ||
| 444 | * | ||
| 445 | * <p>This method is equivalent to {@link #pollFirst}. | ||
| 446 | * | ||
| 447 | * @return the head of the queue represented by this deque, or | ||
| 448 | * <tt>null</tt> if this deque is empty | ||
| 449 | */ | ||
| 450 | public E poll() { | ||
| 451 | return pollFirst(); | ||
| 452 | } | ||
| 453 | |||
| 454 | /** | ||
| 455 | * Retrieves, but does not remove, the head of the queue represented by | ||
| 456 | * this deque. This method differs from {@link #peek peek} only in | ||
| 457 | * that it throws an exception if this deque is empty. | ||
| 458 | * | ||
| 459 | * <p>This method is equivalent to {@link #getFirst}. | ||
| 460 | * | ||
| 461 | * @return the head of the queue represented by this deque | ||
| 462 | * @throws NoSuchElementException {@inheritDoc} | ||
| 463 | */ | ||
| 464 | public E element() { | ||
| 465 | return getFirst(); | ||
| 466 | } | ||
| 467 | |||
| 468 | /** | ||
| 469 | * Retrieves, but does not remove, the head of the queue represented by | ||
| 470 | * this deque, or returns <tt>null</tt> if this deque is empty. | ||
| 471 | * | ||
| 472 | * <p>This method is equivalent to {@link #peekFirst}. | ||
| 473 | * | ||
| 474 | * @return the head of the queue represented by this deque, or | ||
| 475 | * <tt>null</tt> if this deque is empty | ||
| 476 | */ | ||
| 477 | public E peek() { | ||
| 478 | return peekFirst(); | ||
| 479 | } | ||
| 480 | |||
| 481 | // *** Stack methods *** | ||
| 482 | |||
| 483 | /** | ||
| 484 | * Pushes an element onto the stack represented by this deque. In other | ||
| 485 | * words, inserts the element at the front of this deque. | ||
| 486 | * | ||
| 487 | * <p>This method is equivalent to {@link #addFirst}. | ||
| 488 | * | ||
| 489 | * @param e the element to push | ||
| 490 | * @throws NullPointerException if the specified element is null | ||
| 491 | */ | ||
| 492 | public void push(E e) { | ||
| 493 | addFirst(e); | ||
| 494 | } | ||
| 495 | |||
| 496 | /** | ||
| 497 | * Pops an element from the stack represented by this deque. In other | ||
| 498 | * words, removes and returns the first element of this deque. | ||
| 499 | * | ||
| 500 | * <p>This method is equivalent to {@link #removeFirst()}. | ||
| 501 | * | ||
| 502 | * @return the element at the front of this deque (which is the top | ||
| 503 | * of the stack represented by this deque) | ||
| 504 | * @throws NoSuchElementException {@inheritDoc} | ||
| 505 | */ | ||
| 506 | public E pop() { | ||
| 507 | return removeFirst(); | ||
| 508 | } | ||
| 509 | |||
| 510 | private void checkInvariants() { | ||
| 511 | assert elements[tail] == null; | ||
| 512 | assert head == tail ? elements[head] == null : | ||
| 513 | (elements[head] != null && | ||
| 514 | elements[(tail - 1) & (elements.length - 1)] != null); | ||
| 515 | assert elements[(head - 1) & (elements.length - 1)] == null; | ||
| 516 | } | ||
| 517 | |||
| 518 | /** | ||
| 519 | * Removes the element at the specified position in the elements array, | ||
| 520 | * adjusting head and tail as necessary. This can result in motion of | ||
| 521 | * elements backwards or forwards in the array. | ||
| 522 | * | ||
| 523 | * <p>This method is called delete rather than remove to emphasize | ||
| 524 | * that its semantics differ from those of {@link List#remove(int)}. | ||
| 525 | * | ||
| 526 | * @return true if elements moved backwards | ||
| 527 | */ | ||
| 528 | private boolean delete(int i) { | ||
| 529 | checkInvariants(); | ||
| 530 | final E[] elements = this.elements; | ||
| 531 | final int mask = elements.length - 1; | ||
| 532 | final int h = head; | ||
| 533 | final int t = tail; | ||
| 534 | final int front = (i - h) & mask; | ||
| 535 | final int back = (t - i) & mask; | ||
| 536 | |||
| 537 | // Invariant: head <= i < tail mod circularity | ||
| 538 | if (front >= ((t - h) & mask)) | ||
| 539 | throw new ConcurrentModificationException(); | ||
| 540 | |||
| 541 | // Optimize for least element motion | ||
| 542 | if (front < back) { | ||
| 543 | if (h <= i) { | ||
| 544 | System.arraycopy(elements, h, elements, h + 1, front); | ||
| 545 | } else { // Wrap around | ||
| 546 | System.arraycopy(elements, 0, elements, 1, i); | ||
| 547 | elements[0] = elements[mask]; | ||
| 548 | System.arraycopy(elements, h, elements, h + 1, mask - h); | ||
| 549 | } | ||
| 550 | elements[h] = null; | ||
| 551 | head = (h + 1) & mask; | ||
| 552 | return false; | ||
| 553 | } else { | ||
| 554 | if (i < t) { // Copy the null tail as well | ||
| 555 | System.arraycopy(elements, i + 1, elements, i, back); | ||
| 556 | tail = t - 1; | ||
| 557 | } else { // Wrap around | ||
| 558 | System.arraycopy(elements, i + 1, elements, i, mask - i); | ||
| 559 | elements[mask] = elements[0]; | ||
| 560 | System.arraycopy(elements, 1, elements, 0, t); | ||
| 561 | tail = (t - 1) & mask; | ||
| 562 | } | ||
| 563 | return true; | ||
| 564 | } | ||
| 565 | } | ||
| 566 | |||
| 567 | // *** Collection Methods *** | ||
| 568 | |||
| 569 | /** | ||
| 570 | * Returns the number of elements in this deque. | ||
| 571 | * | ||
| 572 | * @return the number of elements in this deque | ||
| 573 | */ | ||
| 574 | public int size() { | ||
| 575 | return (tail - head) & (elements.length - 1); | ||
| 576 | } | ||
| 577 | |||
| 578 | /** | ||
| 579 | * Returns <tt>true</tt> if this deque contains no elements. | ||
| 580 | * | ||
| 581 | * @return <tt>true</tt> if this deque contains no elements | ||
| 582 | */ | ||
| 583 | public boolean isEmpty() { | ||
| 584 | return head == tail; | ||
| 585 | } | ||
| 586 | |||
| 587 | /** | ||
| 588 | * Returns an iterator over the elements in this deque. The elements | ||
| 589 | * will be ordered from first (head) to last (tail). This is the same | ||
| 590 | * order that elements would be dequeued (via successive calls to | ||
| 591 | * {@link #remove} or popped (via successive calls to {@link #pop}). | ||
| 592 | * | ||
| 593 | * @return an iterator over the elements in this deque | ||
| 594 | */ | ||
| 595 | public Iterator<E> iterator() { | ||
| 596 | return new DeqIterator(); | ||
| 597 | } | ||
| 598 | |||
| 599 | public Iterator<E> descendingIterator() { | ||
| 600 | return new DescendingIterator(); | ||
| 601 | } | ||
| 602 | |||
| 603 | private class DeqIterator implements Iterator<E> { | ||
| 604 | /** | ||
| 605 | * Index of element to be returned by subsequent call to next. | ||
| 606 | */ | ||
| 607 | private int cursor = head; | ||
| 608 | |||
| 609 | /** | ||
| 610 | * Tail recorded at construction (also in remove), to stop | ||
| 611 | * iterator and also to check for comodification. | ||
| 612 | */ | ||
| 613 | private int fence = tail; | ||
| 614 | |||
| 615 | /** | ||
| 616 | * Index of element returned by most recent call to next. | ||
| 617 | * Reset to -1 if element is deleted by a call to remove. | ||
| 618 | */ | ||
| 619 | private int lastRet = -1; | ||
| 620 | |||
| 621 | public boolean hasNext() { | ||
| 622 | return cursor != fence; | ||
| 623 | } | ||
| 624 | |||
| 625 | public E next() { | ||
| 626 | if (cursor == fence) | ||
| 627 | throw new NoSuchElementException(); | ||
| 628 | E result = elements[cursor]; | ||
| 629 | // This check doesn't catch all possible comodifications, | ||
| 630 | // but does catch the ones that corrupt traversal | ||
| 631 | if (tail != fence || result == null) | ||
| 632 | throw new ConcurrentModificationException(); | ||
| 633 | lastRet = cursor; | ||
| 634 | cursor = (cursor + 1) & (elements.length - 1); | ||
| 635 | return result; | ||
| 636 | } | ||
| 637 | |||
| 638 | public void remove() { | ||
| 639 | if (lastRet < 0) | ||
| 640 | throw new IllegalStateException(); | ||
| 641 | if (delete(lastRet)) { // if left-shifted, undo increment in next() | ||
| 642 | cursor = (cursor - 1) & (elements.length - 1); | ||
| 643 | fence = tail; | ||
| 644 | } | ||
| 645 | lastRet = -1; | ||
| 646 | } | ||
| 647 | } | ||
| 648 | |||
| 649 | private class DescendingIterator implements Iterator<E> { | ||
| 650 | /* | ||
| 651 | * This class is nearly a mirror-image of DeqIterator, using | ||
| 652 | * tail instead of head for initial cursor, and head instead of | ||
| 653 | * tail for fence. | ||
| 654 | */ | ||
| 655 | private int cursor = tail; | ||
| 656 | private int fence = head; | ||
| 657 | private int lastRet = -1; | ||
| 658 | |||
| 659 | public boolean hasNext() { | ||
| 660 | return cursor != fence; | ||
| 661 | } | ||
| 662 | |||
| 663 | public E next() { | ||
| 664 | if (cursor == fence) | ||
| 665 | throw new NoSuchElementException(); | ||
| 666 | cursor = (cursor - 1) & (elements.length - 1); | ||
| 667 | E result = elements[cursor]; | ||
| 668 | if (head != fence || result == null) | ||
| 669 | throw new ConcurrentModificationException(); | ||
| 670 | lastRet = cursor; | ||
| 671 | return result; | ||
| 672 | } | ||
| 673 | |||
| 674 | public void remove() { | ||
| 675 | if (lastRet < 0) | ||
| 676 | throw new IllegalStateException(); | ||
| 677 | if (!delete(lastRet)) { | ||
| 678 | cursor = (cursor + 1) & (elements.length - 1); | ||
| 679 | fence = head; | ||
| 680 | } | ||
| 681 | lastRet = -1; | ||
| 682 | } | ||
| 683 | } | ||
| 684 | |||
| 685 | /** | ||
| 686 | * Returns <tt>true</tt> if this deque contains the specified element. | ||
| 687 | * More formally, returns <tt>true</tt> if and only if this deque contains | ||
| 688 | * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>. | ||
| 689 | * | ||
| 690 | * @param o object to be checked for containment in this deque | ||
| 691 | * @return <tt>true</tt> if this deque contains the specified element | ||
| 692 | */ | ||
| 693 | public boolean contains(Object o) { | ||
| 694 | if (o == null) | ||
| 695 | return false; | ||
| 696 | int mask = elements.length - 1; | ||
| 697 | int i = head; | ||
| 698 | E x; | ||
| 699 | while ( (x = elements[i]) != null) { | ||
| 700 | if (o.equals(x)) | ||
| 701 | return true; | ||
| 702 | i = (i + 1) & mask; | ||
| 703 | } | ||
| 704 | return false; | ||
| 705 | } | ||
| 706 | |||
| 707 | /** | ||
| 708 | * Removes a single instance of the specified element from this deque. | ||
| 709 | * If the deque does not contain the element, it is unchanged. | ||
| 710 | * More formally, removes the first element <tt>e</tt> such that | ||
| 711 | * <tt>o.equals(e)</tt> (if such an element exists). | ||
| 712 | * Returns <tt>true</tt> if this deque contained the specified element | ||
| 713 | * (or equivalently, if this deque changed as a result of the call). | ||
| 714 | * | ||
| 715 | * <p>This method is equivalent to {@link #removeFirstOccurrence}. | ||
| 716 | * | ||
| 717 | * @param o element to be removed from this deque, if present | ||
| 718 | * @return <tt>true</tt> if this deque contained the specified element | ||
| 719 | */ | ||
| 720 | public boolean remove(Object o) { | ||
| 721 | return removeFirstOccurrence(o); | ||
| 722 | } | ||
| 723 | |||
| 724 | /** | ||
| 725 | * Removes all of the elements from this deque. | ||
| 726 | * The deque will be empty after this call returns. | ||
| 727 | */ | ||
| 728 | public void clear() { | ||
| 729 | int h = head; | ||
| 730 | int t = tail; | ||
| 731 | if (h != t) { // clear all cells | ||
| 732 | head = tail = 0; | ||
| 733 | int i = h; | ||
| 734 | int mask = elements.length - 1; | ||
| 735 | do { | ||
| 736 | elements[i] = null; | ||
| 737 | i = (i + 1) & mask; | ||
| 738 | } while (i != t); | ||
| 739 | } | ||
| 740 | } | ||
| 741 | |||
| 742 | /** | ||
| 743 | * Returns an array containing all of the elements in this deque | ||
| 744 | * in proper sequence (from first to last element). | ||
| 745 | * | ||
| 746 | * <p>The returned array will be "safe" in that no references to it are | ||
| 747 | * maintained by this deque. (In other words, this method must allocate | ||
| 748 | * a new array). The caller is thus free to modify the returned array. | ||
| 749 | * | ||
| 750 | * <p>This method acts as bridge between array-based and collection-based | ||
| 751 | * APIs. | ||
| 752 | * | ||
| 753 | * @return an array containing all of the elements in this deque | ||
| 754 | */ | ||
| 755 | public Object[] toArray() { | ||
| 756 | return copyElements(new Object[size()]); | ||
| 757 | } | ||
| 758 | |||
| 759 | /** | ||
| 760 | * Returns an array containing all of the elements in this deque in | ||
| 761 | * proper sequence (from first to last element); the runtime type of the | ||
| 762 | * returned array is that of the specified array. If the deque fits in | ||
| 763 | * the specified array, it is returned therein. Otherwise, a new array | ||
| 764 | * is allocated with the runtime type of the specified array and the | ||
| 765 | * size of this deque. | ||
| 766 | * | ||
| 767 | * <p>If this deque fits in the specified array with room to spare | ||
| 768 | * (i.e., the array has more elements than this deque), the element in | ||
| 769 | * the array immediately following the end of the deque is set to | ||
| 770 | * <tt>null</tt>. | ||
| 771 | * | ||
| 772 | * <p>Like the {@link #toArray()} method, this method acts as bridge between | ||
| 773 | * array-based and collection-based APIs. Further, this method allows | ||
| 774 | * precise control over the runtime type of the output array, and may, | ||
| 775 | * under certain circumstances, be used to save allocation costs. | ||
| 776 | * | ||
| 777 | * <p>Suppose <tt>x</tt> is a deque known to contain only strings. | ||
| 778 | * The following code can be used to dump the deque into a newly | ||
| 779 | * allocated array of <tt>String</tt>: | ||
| 780 | * | ||
| 781 | * <pre> | ||
| 782 | * String[] y = x.toArray(new String[0]);</pre> | ||
| 783 | * | ||
| 784 | * Note that <tt>toArray(new Object[0])</tt> is identical in function to | ||
| 785 | * <tt>toArray()</tt>. | ||
| 786 | * | ||
| 787 | * @param a the array into which the elements of the deque are to | ||
| 788 | * be stored, if it is big enough; otherwise, a new array of the | ||
| 789 | * same runtime type is allocated for this purpose | ||
| 790 | * @return an array containing all of the elements in this deque | ||
| 791 | * @throws ArrayStoreException if the runtime type of the specified array | ||
| 792 | * is not a supertype of the runtime type of every element in | ||
| 793 | * this deque | ||
| 794 | * @throws NullPointerException if the specified array is null | ||
| 795 | */ | ||
| 796 | public <T> T[] toArray(T[] a) { | ||
| 797 | int size = size(); | ||
| 798 | if (a.length < size) | ||
| 799 | a = (T[])java.lang.reflect.Array.newInstance( | ||
| 800 | a.getClass().getComponentType(), size); | ||
| 801 | copyElements(a); | ||
| 802 | if (a.length > size) | ||
| 803 | a[size] = null; | ||
| 804 | return a; | ||
| 805 | } | ||
| 806 | |||
| 807 | // *** Object methods *** | ||
| 808 | |||
| 809 | /** | ||
| 810 | * Returns a copy of this deque. | ||
| 811 | * | ||
| 812 | * @return a copy of this deque | ||
| 813 | */ | ||
| 814 | public ArrayDeque<E> clone() { | ||
| 815 | try { | ||
| 816 | ArrayDeque<E> result = (ArrayDeque<E>) super.clone(); | ||
| 817 | result.elements = Arrays.copyOf(elements, elements.length); | ||
| 818 | return result; | ||
| 819 | |||
| 820 | } catch (CloneNotSupportedException e) { | ||
| 821 | throw new AssertionError(); | ||
| 822 | } | ||
| 823 | } | ||
| 824 | |||
| 825 | /** | ||
| 826 | * Appease the serialization gods. | ||
| 827 | */ | ||
| 828 | private static final long serialVersionUID = 2340985798034038923L; | ||
| 829 | |||
| 830 | /** | ||
| 831 | * Serialize this deque. | ||
| 832 | * | ||
| 833 | * @serialData The current size (<tt>int</tt>) of the deque, | ||
| 834 | * followed by all of its elements (each an object reference) in | ||
| 835 | * first-to-last order. | ||
| 836 | */ | ||
| 837 | private void writeObject(ObjectOutputStream s) throws IOException { | ||
| 838 | s.defaultWriteObject(); | ||
| 839 | |||
| 840 | // Write out size | ||
| 841 | s.writeInt(size()); | ||
| 842 | |||
| 843 | // Write out elements in order. | ||
| 844 | int mask = elements.length - 1; | ||
| 845 | for (int i = head; i != tail; i = (i + 1) & mask) | ||
| 846 | s.writeObject(elements[i]); | ||
| 847 | } | ||
| 848 | |||
| 849 | /** | ||
| 850 | * Deserialize this deque. | ||
| 851 | */ | ||
| 852 | private void readObject(ObjectInputStream s) | ||
| 853 | throws IOException, ClassNotFoundException { | ||
| 854 | s.defaultReadObject(); | ||
| 855 | |||
| 856 | // Read in size and allocate array | ||
| 857 | int size = s.readInt(); | ||
| 858 | allocateElements(size); | ||
| 859 | head = 0; | ||
| 860 | tail = size; | ||
| 861 | |||
| 862 | // Read in all elements in the proper order. | ||
| 863 | for (int i = 0; i < size; i++) | ||
| 864 | elements[i] = (E)s.readObject(); | ||
| 865 | } | ||
| 866 | } | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,1132 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package java.util; | ||
| 27 | |||
| 28 | /** | ||
| 29 | * Resizable-array implementation of the <tt>List</tt> interface. Implements | ||
| 30 | * all optional list operations, and permits all elements, including | ||
| 31 | * <tt>null</tt>. In addition to implementing the <tt>List</tt> interface, | ||
| 32 | * this class provides methods to manipulate the size of the array that is | ||
| 33 | * used internally to store the list. (This class is roughly equivalent to | ||
| 34 | * <tt>Vector</tt>, except that it is unsynchronized.) | ||
| 35 | * | ||
| 36 | * <p>The <tt>size</tt>, <tt>isEmpty</tt>, <tt>get</tt>, <tt>set</tt>, | ||
| 37 | * <tt>iterator</tt>, and <tt>listIterator</tt> operations run in constant | ||
| 38 | * time. The <tt>add</tt> operation runs in <i>amortized constant time</i>, | ||
| 39 | * that is, adding n elements requires O(n) time. All of the other operations | ||
| 40 | * run in linear time (roughly speaking). The constant factor is low compared | ||
| 41 | * to that for the <tt>LinkedList</tt> implementation. | ||
| 42 | * | ||
| 43 | * <p>Each <tt>ArrayList</tt> instance has a <i>capacity</i>. The capacity is | ||
| 44 | * the size of the array used to store the elements in the list. It is always | ||
| 45 | * at least as large as the list size. As elements are added to an ArrayList, | ||
| 46 | * its capacity grows automatically. The details of the growth policy are not | ||
| 47 | * specified beyond the fact that adding an element has constant amortized | ||
| 48 | * time cost. | ||
| 49 | * | ||
| 50 | * <p>An application can increase the capacity of an <tt>ArrayList</tt> instance | ||
| 51 | * before adding a large number of elements using the <tt>ensureCapacity</tt> | ||
| 52 | * operation. This may reduce the amount of incremental reallocation. | ||
| 53 | * | ||
| 54 | * <p><strong>Note that this implementation is not synchronized.</strong> | ||
| 55 | * If multiple threads access an <tt>ArrayList</tt> instance concurrently, | ||
| 56 | * and at least one of the threads modifies the list structurally, it | ||
| 57 | * <i>must</i> be synchronized externally. (A structural modification is | ||
| 58 | * any operation that adds or deletes one or more elements, or explicitly | ||
| 59 | * resizes the backing array; merely setting the value of an element is not | ||
| 60 | * a structural modification.) This is typically accomplished by | ||
| 61 | * synchronizing on some object that naturally encapsulates the list. | ||
| 62 | * | ||
| 63 | * If no such object exists, the list should be "wrapped" using the | ||
| 64 | * {@link Collections#synchronizedList Collections.synchronizedList} | ||
| 65 | * method. This is best done at creation time, to prevent accidental | ||
| 66 | * unsynchronized access to the list:<pre> | ||
| 67 | * List list = Collections.synchronizedList(new ArrayList(...));</pre> | ||
| 68 | * | ||
| 69 | * <p><a name="fail-fast"/> | ||
| 70 | * The iterators returned by this class's {@link #iterator() iterator} and | ||
| 71 | * {@link #listIterator(int) listIterator} methods are <em>fail-fast</em>: | ||
| 72 | * if the list is structurally modified at any time after the iterator is | ||
| 73 | * created, in any way except through the iterator's own | ||
| 74 | * {@link ListIterator#remove() remove} or | ||
| 75 | * {@link ListIterator#add(Object) add} methods, the iterator will throw a | ||
| 76 | * {@link ConcurrentModificationException}. Thus, in the face of | ||
| 77 | * concurrent modification, the iterator fails quickly and cleanly, rather | ||
| 78 | * than risking arbitrary, non-deterministic behavior at an undetermined | ||
| 79 | * time in the future. | ||
| 80 | * | ||
| 81 | * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed | ||
| 82 | * as it is, generally speaking, impossible to make any hard guarantees in the | ||
| 83 | * presence of unsynchronized concurrent modification. Fail-fast iterators | ||
| 84 | * throw {@code ConcurrentModificationException} on a best-effort basis. | ||
| 85 | * Therefore, it would be wrong to write a program that depended on this | ||
| 86 | * exception for its correctness: <i>the fail-fast behavior of iterators | ||
| 87 | * should be used only to detect bugs.</i> | ||
| 88 | * | ||
| 89 | * <p>This class is a member of the | ||
| 90 | * <a href="{@docRoot}/../technotes/guides/collections/index.html"> | ||
| 91 | * Java Collections Framework</a>. | ||
| 92 | * | ||
| 93 | * @author Josh Bloch | ||
| 94 | * @author Neal Gafter | ||
| 95 | * @see Collection | ||
| 96 | * @see List | ||
| 97 | * @see LinkedList | ||
| 98 | * @see Vector | ||
| 99 | * @since 1.2 | ||
| 100 | */ | ||
| 101 | |||
| 102 | public class ArrayList<E> extends AbstractList<E> | ||
| 103 | implements List<E>, RandomAccess, Cloneable, java.io.Serializable | ||
| 104 | { | ||
| 105 | private static final long serialVersionUID = 8683452581122892189L; | ||
| 106 | |||
| 107 | /** | ||
| 108 | * The array buffer into which the elements of the ArrayList are stored. | ||
| 109 | * The capacity of the ArrayList is the length of this array buffer. | ||
| 110 | */ | ||
| 111 | private transient Object[] elementData; | ||
| 112 | |||
| 113 | /** | ||
| 114 | * The size of the ArrayList (the number of elements it contains). | ||
| 115 | * | ||
| 116 | * @serial | ||
| 117 | */ | ||
| 118 | private int size; | ||
| 119 | |||
| 120 | /** | ||
| 121 | * Constructs an empty list with the specified initial capacity. | ||
| 122 | * | ||
| 123 | * @param initialCapacity the initial capacity of the list | ||
| 124 | * @throws IllegalArgumentException if the specified initial capacity | ||
| 125 | * is negative | ||
| 126 | */ | ||
| 127 | public ArrayList(int initialCapacity) { | ||
| 128 | super(); | ||
| 129 | if (initialCapacity < 0) | ||
| 130 | throw new IllegalArgumentException("Illegal Capacity: "+ | ||
| 131 | initialCapacity); | ||
| 132 | this.elementData = new Object[initialCapacity]; | ||
| 133 | } | ||
| 134 | |||
| 135 | /** | ||
| 136 | * Constructs an empty list with an initial capacity of ten. | ||
| 137 | */ | ||
| 138 | public ArrayList() { | ||
| 139 | this(10); | ||
| 140 | } | ||
| 141 | |||
| 142 | /** | ||
| 143 | * Constructs a list containing the elements of the specified | ||
| 144 | * collection, in the order they are returned by the collection's | ||
| 145 | * iterator. | ||
| 146 | * | ||
| 147 | * @param c the collection whose elements are to be placed into this list | ||
| 148 | * @throws NullPointerException if the specified collection is null | ||
| 149 | */ | ||
| 150 | public ArrayList(Collection<? extends E> c) { | ||
| 151 | elementData = c.toArray(); | ||
| 152 | size = elementData.length; | ||
| 153 | // c.toArray might (incorrectly) not return Object[] (see 6260652) | ||
| 154 | if (elementData.getClass() != Object[].class) | ||
| 155 | elementData = Arrays.copyOf(elementData, size, Object[].class); | ||
| 156 | } | ||
| 157 | |||
| 158 | /** | ||
| 159 | * Trims the capacity of this <tt>ArrayList</tt> instance to be the | ||
| 160 | * list's current size. An application can use this operation to minimize | ||
| 161 | * the storage of an <tt>ArrayList</tt> instance. | ||
| 162 | */ | ||
| 163 | public void trimToSize() { | ||
| 164 | modCount++; | ||
| 165 | int oldCapacity = elementData.length; | ||
| 166 | if (size < oldCapacity) { | ||
| 167 | elementData = Arrays.copyOf(elementData, size); | ||
| 168 | } | ||
| 169 | } | ||
| 170 | |||
| 171 | /** | ||
| 172 | * Increases the capacity of this <tt>ArrayList</tt> instance, if | ||
| 173 | * necessary, to ensure that it can hold at least the number of elements | ||
| 174 | * specified by the minimum capacity argument. | ||
| 175 | * | ||
| 176 | * @param minCapacity the desired minimum capacity | ||
| 177 | */ | ||
| 178 | public void ensureCapacity(int minCapacity) { | ||
| 179 | if (minCapacity > 0) | ||
| 180 | ensureCapacityInternal(minCapacity); | ||
| 181 | } | ||
| 182 | |||
| 183 | private void ensureCapacityInternal(int minCapacity) { | ||
| 184 | modCount++; | ||
| 185 | // overflow-conscious code | ||
| 186 | if (minCapacity - elementData.length > 0) | ||
| 187 | grow(minCapacity); | ||
| 188 | } | ||
| 189 | |||
| 190 | /** | ||
| 191 | * The maximum size of array to allocate. | ||
| 192 | * Some VMs reserve some header words in an array. | ||
| 193 | * Attempts to allocate larger arrays may result in | ||
| 194 | * OutOfMemoryError: Requested array size exceeds VM limit | ||
| 195 | */ | ||
| 196 | private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; | ||
| 197 | |||
| 198 | /** | ||
| 199 | * Increases the capacity to ensure that it can hold at least the | ||
| 200 | * number of elements specified by the minimum capacity argument. | ||
| 201 | * | ||
| 202 | * @param minCapacity the desired minimum capacity | ||
| 203 | */ | ||
| 204 | private void grow(int minCapacity) { | ||
| 205 | // overflow-conscious code | ||
| 206 | int oldCapacity = elementData.length; | ||
| 207 | int newCapacity = oldCapacity + (oldCapacity >> 1); | ||
| 208 | if (newCapacity - minCapacity < 0) | ||
| 209 | newCapacity = minCapacity; | ||
| 210 | if (newCapacity - MAX_ARRAY_SIZE > 0) | ||
| 211 | newCapacity = hugeCapacity(minCapacity); | ||
| 212 | // minCapacity is usually close to size, so this is a win: | ||
| 213 | elementData = Arrays.copyOf(elementData, newCapacity); | ||
| 214 | } | ||
| 215 | |||
| 216 | private static int hugeCapacity(int minCapacity) { | ||
| 217 | if (minCapacity < 0) // overflow | ||
| 218 | throw new OutOfMemoryError(); | ||
| 219 | return (minCapacity > MAX_ARRAY_SIZE) ? | ||
| 220 | Integer.MAX_VALUE : | ||
| 221 | MAX_ARRAY_SIZE; | ||
| 222 | } | ||
| 223 | |||
| 224 | /** | ||
| 225 | * Returns the number of elements in this list. | ||
| 226 | * | ||
| 227 | * @return the number of elements in this list | ||
| 228 | */ | ||
| 229 | public int size() { | ||
| 230 | return size; | ||
| 231 | } | ||
| 232 | |||
| 233 | /** | ||
| 234 | * Returns <tt>true</tt> if this list contains no elements. | ||
| 235 | * | ||
| 236 | * @return <tt>true</tt> if this list contains no elements | ||
| 237 | */ | ||
| 238 | public boolean isEmpty() { | ||
| 239 | return size == 0; | ||
| 240 | } | ||
| 241 | |||
| 242 | /** | ||
| 243 | * Returns <tt>true</tt> if this list contains the specified element. | ||
| 244 | * More formally, returns <tt>true</tt> if and only if this list contains | ||
| 245 | * at least one element <tt>e</tt> such that | ||
| 246 | * <tt>(o==null ? e==null : o.equals(e))</tt>. | ||
| 247 | * | ||
| 248 | * @param o element whose presence in this list is to be tested | ||
| 249 | * @return <tt>true</tt> if this list contains the specified element | ||
| 250 | */ | ||
| 251 | public boolean contains(Object o) { | ||
| 252 | return indexOf(o) >= 0; | ||
| 253 | } | ||
| 254 | |||
| 255 | /** | ||
| 256 | * Returns the index of the first occurrence of the specified element | ||
| 257 | * in this list, or -1 if this list does not contain the element. | ||
| 258 | * More formally, returns the lowest index <tt>i</tt> such that | ||
| 259 | * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>, | ||
| 260 | * or -1 if there is no such index. | ||
| 261 | */ | ||
| 262 | public int indexOf(Object o) { | ||
| 263 | if (o == null) { | ||
| 264 | for (int i = 0; i < size; i++) | ||
| 265 | if (elementData[i]==null) | ||
| 266 | return i; | ||
| 267 | } else { | ||
| 268 | for (int i = 0; i < size; i++) | ||
| 269 | if (o.equals(elementData[i])) | ||
| 270 | return i; | ||
| 271 | } | ||
| 272 | return -1; | ||
| 273 | } | ||
| 274 | |||
| 275 | /** | ||
| 276 | * Returns the index of the last occurrence of the specified element | ||
| 277 | * in this list, or -1 if this list does not contain the element. | ||
| 278 | * More formally, returns the highest index <tt>i</tt> such that | ||
| 279 | * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>, | ||
| 280 | * or -1 if there is no such index. | ||
| 281 | */ | ||
| 282 | public int lastIndexOf(Object o) { | ||
| 283 | if (o == null) { | ||
| 284 | for (int i = size-1; i >= 0; i--) | ||
| 285 | if (elementData[i]==null) | ||
| 286 | return i; | ||
| 287 | } else { | ||
| 288 | for (int i = size-1; i >= 0; i--) | ||
| 289 | if (o.equals(elementData[i])) | ||
| 290 | return i; | ||
| 291 | } | ||
| 292 | return -1; | ||
| 293 | } | ||
| 294 | |||
| 295 | /** | ||
| 296 | * Returns a shallow copy of this <tt>ArrayList</tt> instance. (The | ||
| 297 | * elements themselves are not copied.) | ||
| 298 | * | ||
| 299 | * @return a clone of this <tt>ArrayList</tt> instance | ||
| 300 | */ | ||
| 301 | public Object clone() { | ||
| 302 | try { | ||
| 303 | @SuppressWarnings("unchecked") | ||
| 304 | ArrayList<E> v = (ArrayList<E>) super.clone(); | ||
| 305 | v.elementData = Arrays.copyOf(elementData, size); | ||
| 306 | v.modCount = 0; | ||
| 307 | return v; | ||
| 308 | } catch (CloneNotSupportedException e) { | ||
| 309 | // this shouldn't happen, since we are Cloneable | ||
| 310 | throw new InternalError(); | ||
| 311 | } | ||
| 312 | } | ||
| 313 | |||
| 314 | /** | ||
| 315 | * Returns an array containing all of the elements in this list | ||
| 316 | * in proper sequence (from first to last element). | ||
| 317 | * | ||
| 318 | * <p>The returned array will be "safe" in that no references to it are | ||
| 319 | * maintained by this list. (In other words, this method must allocate | ||
| 320 | * a new array). The caller is thus free to modify the returned array. | ||
| 321 | * | ||
| 322 | * <p>This method acts as bridge between array-based and collection-based | ||
| 323 | * APIs. | ||
| 324 | * | ||
| 325 | * @return an array containing all of the elements in this list in | ||
| 326 | * proper sequence | ||
| 327 | */ | ||
| 328 | public Object[] toArray() { | ||
| 329 | return Arrays.copyOf(elementData, size); | ||
| 330 | } | ||
| 331 | |||
| 332 | /** | ||
| 333 | * Returns an array containing all of the elements in this list in proper | ||
| 334 | * sequence (from first to last element); the runtime type of the returned | ||
| 335 | * array is that of the specified array. If the list fits in the | ||
| 336 | * specified array, it is returned therein. Otherwise, a new array is | ||
| 337 | * allocated with the runtime type of the specified array and the size of | ||
| 338 | * this list. | ||
| 339 | * | ||
| 340 | * <p>If the list fits in the specified array with room to spare | ||
| 341 | * (i.e., the array has more elements than the list), the element in | ||
| 342 | * the array immediately following the end of the collection is set to | ||
| 343 | * <tt>null</tt>. (This is useful in determining the length of the | ||
| 344 | * list <i>only</i> if the caller knows that the list does not contain | ||
| 345 | * any null elements.) | ||
| 346 | * | ||
| 347 | * @param a the array into which the elements of the list are to | ||
| 348 | * be stored, if it is big enough; otherwise, a new array of the | ||
| 349 | * same runtime type is allocated for this purpose. | ||
| 350 | * @return an array containing the elements of the list | ||
| 351 | * @throws ArrayStoreException if the runtime type of the specified array | ||
| 352 | * is not a supertype of the runtime type of every element in | ||
| 353 | * this list | ||
| 354 | * @throws NullPointerException if the specified array is null | ||
| 355 | */ | ||
| 356 | @SuppressWarnings("unchecked") | ||
| 357 | public <T> T[] toArray(T[] a) { | ||
| 358 | if (a.length < size) | ||
| 359 | // Make a new array of a's runtime type, but my contents: | ||
| 360 | return (T[]) Arrays.copyOf(elementData, size, a.getClass()); | ||
| 361 | System.arraycopy(elementData, 0, a, 0, size); | ||
| 362 | if (a.length > size) | ||
| 363 | a[size] = null; | ||
| 364 | return a; | ||
| 365 | } | ||
| 366 | |||
| 367 | // Positional Access Operations | ||
| 368 | |||
| 369 | @SuppressWarnings("unchecked") | ||
| 370 | E elementData(int index) { | ||
| 371 | return (E) elementData[index]; | ||
| 372 | } | ||
| 373 | |||
| 374 | /** | ||
| 375 | * Returns the element at the specified position in this list. | ||
| 376 | * | ||
| 377 | * @param index index of the element to return | ||
| 378 | * @return the element at the specified position in this list | ||
| 379 | * @throws IndexOutOfBoundsException {@inheritDoc} | ||
| 380 | */ | ||
| 381 | public E get(int index) { | ||
| 382 | rangeCheck(index); | ||
| 383 | |||
| 384 | return elementData(index); | ||
| 385 | } | ||
| 386 | |||
| 387 | /** | ||
| 388 | * Replaces the element at the specified position in this list with | ||
| 389 | * the specified element. | ||
| 390 | * | ||
| 391 | * @param index index of the element to replace | ||
| 392 | * @param element element to be stored at the specified position | ||
| 393 | * @return the element previously at the specified position | ||
| 394 | * @throws IndexOutOfBoundsException {@inheritDoc} | ||
| 395 | */ | ||
| 396 | public E set(int index, E element) { | ||
| 397 | rangeCheck(index); | ||
| 398 | |||
| 399 | E oldValue = elementData(index); | ||
| 400 | elementData[index] = element; | ||
| 401 | return oldValue; | ||
| 402 | } | ||
| 403 | |||
| 404 | /** | ||
| 405 | * Appends the specified element to the end of this list. | ||
| 406 | * | ||
| 407 | * @param e element to be appended to this list | ||
| 408 | * @return <tt>true</tt> (as specified by {@link Collection#add}) | ||
| 409 | */ | ||
| 410 | public boolean add(E e) { | ||
| 411 | ensureCapacityInternal(size + 1); // Increments modCount!! | ||
| 412 | elementData[size++] = e; | ||
| 413 | return true; | ||
| 414 | } | ||
| 415 | |||
| 416 | /** | ||
| 417 | * Inserts the specified element at the specified position in this | ||
| 418 | * list. Shifts the element currently at that position (if any) and | ||
| 419 | * any subsequent elements to the right (adds one to their indices). | ||
| 420 | * | ||
| 421 | * @param index index at which the specified element is to be inserted | ||
| 422 | * @param element element to be inserted | ||
| 423 | * @throws IndexOutOfBoundsException {@inheritDoc} | ||
| 424 | */ | ||
| 425 | public void add(int index, E element) { | ||
| 426 | rangeCheckForAdd(index); | ||
| 427 | |||
| 428 | ensureCapacityInternal(size + 1); // Increments modCount!! | ||
| 429 | System.arraycopy(elementData, index, elementData, index + 1, | ||
| 430 | size - index); | ||
| 431 | elementData[index] = element; | ||
| 432 | size++; | ||
| 433 | } | ||
| 434 | |||
| 435 | /** | ||
| 436 | * Removes the element at the specified position in this list. | ||
| 437 | * Shifts any subsequent elements to the left (subtracts one from their | ||
| 438 | * indices). | ||
| 439 | * | ||
| 440 | * @param index the index of the element to be removed | ||
| 441 | * @return the element that was removed from the list | ||
| 442 | * @throws IndexOutOfBoundsException {@inheritDoc} | ||
| 443 | */ | ||
| 444 | public E remove(int index) { | ||
| 445 | rangeCheck(index); | ||
| 446 | |||
| 447 | modCount++; | ||
| 448 | E oldValue = elementData(index); | ||
| 449 | |||
| 450 | int numMoved = size - index - 1; | ||
| 451 | if (numMoved > 0) | ||
| 452 | System.arraycopy(elementData, index+1, elementData, index, | ||
| 453 | numMoved); | ||
| 454 | elementData[--size] = null; // Let gc do its work | ||
| 455 | |||
| 456 | return oldValue; | ||
| 457 | } | ||
| 458 | |||
| 459 | /** | ||
| 460 | * Removes the first occurrence of the specified element from this list, | ||
| 461 | * if it is present. If the list does not contain the element, it is | ||
| 462 | * unchanged. More formally, removes the element with the lowest index | ||
| 463 | * <tt>i</tt> such that | ||
| 464 | * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt> | ||
| 465 | * (if such an element exists). Returns <tt>true</tt> if this list | ||
| 466 | * contained the specified element (or equivalently, if this list | ||
| 467 | * changed as a result of the call). | ||
| 468 | * | ||
| 469 | * @param o element to be removed from this list, if present | ||
| 470 | * @return <tt>true</tt> if this list contained the specified element | ||
| 471 | */ | ||
| 472 | public boolean remove(Object o) { | ||
| 473 | if (o == null) { | ||
| 474 | for (int index = 0; index < size; index++) | ||
| 475 | if (elementData[index] == null) { | ||
| 476 | fastRemove(index); | ||
| 477 | return true; | ||
| 478 | } | ||
| 479 | } else { | ||
| 480 | for (int index = 0; index < size; index++) | ||
| 481 | if (o.equals(elementData[index])) { | ||
| 482 | fastRemove(index); | ||
| 483 | return true; | ||
| 484 | } | ||
| 485 | } | ||
| 486 | return false; | ||
| 487 | } | ||
| 488 | |||
| 489 | /* | ||
| 490 | * Private remove method that skips bounds checking and does not | ||
| 491 | * return the value removed. | ||
| 492 | */ | ||
| 493 | private void fastRemove(int index) { | ||
| 494 | modCount++; | ||
| 495 | int numMoved = size - index - 1; | ||
| 496 | if (numMoved > 0) | ||
| 497 | System.arraycopy(elementData, index+1, elementData, index, | ||
| 498 | numMoved); | ||
| 499 | elementData[--size] = null; // Let gc do its work | ||
| 500 | } | ||
| 501 | |||
| 502 | /** | ||
| 503 | * Removes all of the elements from this list. The list will | ||
| 504 | * be empty after this call returns. | ||
| 505 | */ | ||
| 506 | public void clear() { | ||
| 507 | modCount++; | ||
| 508 | |||
| 509 | // Let gc do its work | ||
| 510 | for (int i = 0; i < size; i++) | ||
| 511 | elementData[i] = null; | ||
| 512 | |||
| 513 | size = 0; | ||
| 514 | } | ||
| 515 | |||
| 516 | /** | ||
| 517 | * Appends all of the elements in the specified collection to the end of | ||
| 518 | * this list, in the order that they are returned by the | ||
| 519 | * specified collection's Iterator. The behavior of this operation is | ||
| 520 | * undefined if the specified collection is modified while the operation | ||
| 521 | * is in progress. (This implies that the behavior of this call is | ||
| 522 | * undefined if the specified collection is this list, and this | ||
| 523 | * list is nonempty.) | ||
| 524 | * | ||
| 525 | * @param c collection containing elements to be added to this list | ||
| 526 | * @return <tt>true</tt> if this list changed as a result of the call | ||
| 527 | * @throws NullPointerException if the specified collection is null | ||
| 528 | */ | ||
| 529 | public boolean addAll(Collection<? extends E> c) { | ||
| 530 | Object[] a = c.toArray(); | ||
| 531 | int numNew = a.length; | ||
| 532 | ensureCapacityInternal(size + numNew); // Increments modCount | ||
| 533 | System.arraycopy(a, 0, elementData, size, numNew); | ||
| 534 | size += numNew; | ||
| 535 | return numNew != 0; | ||
| 536 | } | ||
| 537 | |||
| 538 | /** | ||
| 539 | * Inserts all of the elements in the specified collection into this | ||
| 540 | * list, starting at the specified position. Shifts the element | ||
| 541 | * currently at that position (if any) and any subsequent elements to | ||
| 542 | * the right (increases their indices). The new elements will appear | ||
| 543 | * in the list in the order that they are returned by the | ||
| 544 | * specified collection's iterator. | ||
| 545 | * | ||
| 546 | * @param index index at which to insert the first element from the | ||
| 547 | * specified collection | ||
| 548 | * @param c collection containing elements to be added to this list | ||
| 549 | * @return <tt>true</tt> if this list changed as a result of the call | ||
| 550 | * @throws IndexOutOfBoundsException {@inheritDoc} | ||
| 551 | * @throws NullPointerException if the specified collection is null | ||
| 552 | */ | ||
| 553 | public boolean addAll(int index, Collection<? extends E> c) { | ||
| 554 | rangeCheckForAdd(index); | ||
| 555 | |||
| 556 | Object[] a = c.toArray(); | ||
| 557 | int numNew = a.length; | ||
| 558 | ensureCapacityInternal(size + numNew); // Increments modCount | ||
| 559 | |||
| 560 | int numMoved = size - index; | ||
| 561 | if (numMoved > 0) | ||
| 562 | System.arraycopy(elementData, index, elementData, index + numNew, | ||
| 563 | numMoved); | ||
| 564 | |||
| 565 | System.arraycopy(a, 0, elementData, index, numNew); | ||
| 566 | size += numNew; | ||
| 567 | return numNew != 0; | ||
| 568 | } | ||
| 569 | |||
| 570 | /** | ||
| 571 | * Removes from this list all of the elements whose index is between | ||
| 572 | * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive. | ||
| 573 | * Shifts any succeeding elements to the left (reduces their index). | ||
| 574 | * This call shortens the list by {@code (toIndex - fromIndex)} elements. | ||
| 575 | * (If {@code toIndex==fromIndex}, this operation has no effect.) | ||
| 576 | * | ||
| 577 | * @throws IndexOutOfBoundsException if {@code fromIndex} or | ||
| 578 | * {@code toIndex} is out of range | ||
| 579 | * ({@code fromIndex < 0 || | ||
| 580 | * fromIndex >= size() || | ||
| 581 | * toIndex > size() || | ||
| 582 | * toIndex < fromIndex}) | ||
| 583 | */ | ||
| 584 | protected void removeRange(int fromIndex, int toIndex) { | ||
| 585 | modCount++; | ||
| 586 | int numMoved = size - toIndex; | ||
| 587 | System.arraycopy(elementData, toIndex, elementData, fromIndex, | ||
| 588 | numMoved); | ||
| 589 | |||
| 590 | // Let gc do its work | ||
| 591 | int newSize = size - (toIndex-fromIndex); | ||
| 592 | while (size != newSize) | ||
| 593 | elementData[--size] = null; | ||
| 594 | } | ||
| 595 | |||
| 596 | /** | ||
| 597 | * Checks if the given index is in range. If not, throws an appropriate | ||
| 598 | * runtime exception. This method does *not* check if the index is | ||
| 599 | * negative: It is always used immediately prior to an array access, | ||
| 600 | * which throws an ArrayIndexOutOfBoundsException if index is negative. | ||
| 601 | */ | ||
| 602 | private void rangeCheck(int index) { | ||
| 603 | if (index >= size) | ||
| 604 | throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); | ||
| 605 | } | ||
| 606 | |||
| 607 | /** | ||
| 608 | * A version of rangeCheck used by add and addAll. | ||
| 609 | */ | ||
| 610 | private void rangeCheckForAdd(int index) { | ||
| 611 | if (index > size || index < 0) | ||
| 612 | throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); | ||
| 613 | } | ||
| 614 | |||
| 615 | /** | ||
| 616 | * Constructs an IndexOutOfBoundsException detail message. | ||
| 617 | * Of the many possible refactorings of the error handling code, | ||
| 618 | * this "outlining" performs best with both server and client VMs. | ||
| 619 | */ | ||
| 620 | private String outOfBoundsMsg(int index) { | ||
| 621 | return "Index: "+index+", Size: "+size; | ||
| 622 | } | ||
| 623 | |||
| 624 | /** | ||
| 625 | * Removes from this list all of its elements that are contained in the | ||
| 626 | * specified collection. | ||
| 627 | * | ||
| 628 | * @param c collection containing elements to be removed from this list | ||
| 629 | * @return {@code true} if this list changed as a result of the call | ||
| 630 | * @throws ClassCastException if the class of an element of this list | ||
| 631 | * is incompatible with the specified collection | ||
| 632 | * (<a href="Collection.html#optional-restrictions">optional</a>) | ||
| 633 | * @throws NullPointerException if this list contains a null element and the | ||
| 634 | * specified collection does not permit null elements | ||
| 635 | * (<a href="Collection.html#optional-restrictions">optional</a>), | ||
| 636 | * or if the specified collection is null | ||
| 637 | * @see Collection#contains(Object) | ||
| 638 | */ | ||
| 639 | public boolean removeAll(Collection<?> c) { | ||
| 640 | return batchRemove(c, false); | ||
| 641 | } | ||
| 642 | |||
| 643 | /** | ||
| 644 | * Retains only the elements in this list that are contained in the | ||
| 645 | * specified collection. In other words, removes from this list all | ||
| 646 | * of its elements that are not contained in the specified collection. | ||
| 647 | * | ||
| 648 | * @param c collection containing elements to be retained in this list | ||
| 649 | * @return {@code true} if this list changed as a result of the call | ||
| 650 | * @throws ClassCastException if the class of an element of this list | ||
| 651 | * is incompatible with the specified collection | ||
| 652 | * (<a href="Collection.html#optional-restrictions">optional</a>) | ||
| 653 | * @throws NullPointerException if this list contains a null element and the | ||
| 654 | * specified collection does not permit null elements | ||
| 655 | * (<a href="Collection.html#optional-restrictions">optional</a>), | ||
| 656 | * or if the specified collection is null | ||
| 657 | * @see Collection#contains(Object) | ||
| 658 | */ | ||
| 659 | public boolean retainAll(Collection<?> c) { | ||
| 660 | return batchRemove(c, true); | ||
| 661 | } | ||
| 662 | |||
| 663 | private boolean batchRemove(Collection<?> c, boolean complement) { | ||
| 664 | final Object[] elementData = this.elementData; | ||
| 665 | int r = 0, w = 0; | ||
| 666 | boolean modified = false; | ||
| 667 | try { | ||
| 668 | for (; r < size; r++) | ||
| 669 | if (c.contains(elementData[r]) == complement) | ||
| 670 | elementData[w++] = elementData[r]; | ||
| 671 | } finally { | ||
| 672 | // Preserve behavioral compatibility with AbstractCollection, | ||
| 673 | // even if c.contains() throws. | ||
| 674 | if (r != size) { | ||
| 675 | System.arraycopy(elementData, r, | ||
| 676 | elementData, w, | ||
| 677 | size - r); | ||
| 678 | w += size - r; | ||
| 679 | } | ||
| 680 | if (w != size) { | ||
| 681 | for (int i = w; i < size; i++) | ||
| 682 | elementData[i] = null; | ||
| 683 | modCount += size - w; | ||
| 684 | size = w; | ||
| 685 | modified = true; | ||
| 686 | } | ||
| 687 | } | ||
| 688 | return modified; | ||
| 689 | } | ||
| 690 | |||
| 691 | /** | ||
| 692 | * Save the state of the <tt>ArrayList</tt> instance to a stream (that | ||
| 693 | * is, serialize it). | ||
| 694 | * | ||
| 695 | * @serialData The length of the array backing the <tt>ArrayList</tt> | ||
| 696 | * instance is emitted (int), followed by all of its elements | ||
| 697 | * (each an <tt>Object</tt>) in the proper order. | ||
| 698 | */ | ||
| 699 | private void writeObject(java.io.ObjectOutputStream s) | ||
| 700 | throws java.io.IOException{ | ||
| 701 | // Write out element count, and any hidden stuff | ||
| 702 | int expectedModCount = modCount; | ||
| 703 | s.defaultWriteObject(); | ||
| 704 | |||
| 705 | // Write out array length | ||
| 706 | s.writeInt(elementData.length); | ||
| 707 | |||
| 708 | // Write out all elements in the proper order. | ||
| 709 | for (int i=0; i<size; i++) | ||
| 710 | s.writeObject(elementData[i]); | ||
| 711 | |||
| 712 | if (modCount != expectedModCount) { | ||
| 713 | throw new ConcurrentModificationException(); | ||
| 714 | } | ||
| 715 | |||
| 716 | } | ||
| 717 | |||
| 718 | /** | ||
| 719 | * Reconstitute the <tt>ArrayList</tt> instance from a stream (that is, | ||
| 720 | * deserialize it). | ||
| 721 | */ | ||
| 722 | private void readObject(java.io.ObjectInputStream s) | ||
| 723 | throws java.io.IOException, ClassNotFoundException { | ||
| 724 | // Read in size, and any hidden stuff | ||
| 725 | s.defaultReadObject(); | ||
| 726 | |||
| 727 | // Read in array length and allocate array | ||
| 728 | int arrayLength = s.readInt(); | ||
| 729 | Object[] a = elementData = new Object[arrayLength]; | ||
| 730 | |||
| 731 | // Read in all elements in the proper order. | ||
| 732 | for (int i=0; i<size; i++) | ||
| 733 | a[i] = s.readObject(); | ||
| 734 | } | ||
| 735 | |||
| 736 | /** | ||
| 737 | * Returns a list iterator over the elements in this list (in proper | ||
| 738 | * sequence), starting at the specified position in the list. | ||
| 739 | * The specified index indicates the first element that would be | ||
| 740 | * returned by an initial call to {@link ListIterator#next next}. | ||
| 741 | * An initial call to {@link ListIterator#previous previous} would | ||
| 742 | * return the element with the specified index minus one. | ||
| 743 | * | ||
| 744 | * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>. | ||
| 745 | * | ||
| 746 | * @throws IndexOutOfBoundsException {@inheritDoc} | ||
| 747 | */ | ||
| 748 | public ListIterator<E> listIterator(int index) { | ||
| 749 | if (index < 0 || index > size) | ||
| 750 | throw new IndexOutOfBoundsException("Index: "+index); | ||
| 751 | return new ListItr(index); | ||
| 752 | } | ||
| 753 | |||
| 754 | /** | ||
| 755 | * Returns a list iterator over the elements in this list (in proper | ||
| 756 | * sequence). | ||
| 757 | * | ||
| 758 | * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>. | ||
| 759 | * | ||
| 760 | * @see #listIterator(int) | ||
| 761 | */ | ||
| 762 | public ListIterator<E> listIterator() { | ||
| 763 | return new ListItr(0); | ||
| 764 | } | ||
| 765 | |||
| 766 | /** | ||
| 767 | * Returns an iterator over the elements in this list in proper sequence. | ||
| 768 | * | ||
| 769 | * <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>. | ||
| 770 | * | ||
| 771 | * @return an iterator over the elements in this list in proper sequence | ||
| 772 | */ | ||
| 773 | public Iterator<E> iterator() { | ||
| 774 | return new Itr(); | ||
| 775 | } | ||
| 776 | |||
| 777 | /** | ||
| 778 | * An optimized version of AbstractList.Itr | ||
| 779 | */ | ||
| 780 | private class Itr implements Iterator<E> { | ||
| 781 | int cursor; // index of next element to return | ||
| 782 | int lastRet = -1; // index of last element returned; -1 if no such | ||
| 783 | int expectedModCount = modCount; | ||
| 784 | |||
| 785 | public boolean hasNext() { | ||
| 786 | return cursor != size; | ||
| 787 | } | ||
| 788 | |||
| 789 | @SuppressWarnings("unchecked") | ||
| 790 | public E next() { | ||
| 791 | checkForComodification(); | ||
| 792 | int i = cursor; | ||
| 793 | if (i >= size) | ||
| 794 | throw new NoSuchElementException(); | ||
| 795 | Object[] elementData = ArrayList.this.elementData; | ||
| 796 | if (i >= elementData.length) | ||
| 797 | throw new ConcurrentModificationException(); | ||
| 798 | cursor = i + 1; | ||
| 799 | return (E) elementData[lastRet = i]; | ||
| 800 | } | ||
| 801 | |||
| 802 | public void remove() { | ||
| 803 | if (lastRet < 0) | ||
| 804 | throw new IllegalStateException(); | ||
| 805 | checkForComodification(); | ||
| 806 | |||
| 807 | try { | ||
| 808 | ArrayList.this.remove(lastRet); | ||
| 809 | cursor = lastRet; | ||
| 810 | lastRet = -1; | ||
| 811 | expectedModCount = modCount; | ||
| 812 | } catch (IndexOutOfBoundsException ex) { | ||
| 813 | throw new ConcurrentModificationException(); | ||
| 814 | } | ||
| 815 | } | ||
| 816 | |||
| 817 | final void checkForComodification() { | ||
| 818 | if (modCount != expectedModCount) | ||
| 819 | throw new ConcurrentModificationException(); | ||
| 820 | } | ||
| 821 | } | ||
| 822 | |||
| 823 | /** | ||
| 824 | * An optimized version of AbstractList.ListItr | ||
| 825 | */ | ||
| 826 | private class ListItr extends Itr implements ListIterator<E> { | ||
| 827 | ListItr(int index) { | ||
| 828 | super(); | ||
| 829 | cursor = index; | ||
| 830 | } | ||
| 831 | |||
| 832 | public boolean hasPrevious() { | ||
| 833 | return cursor != 0; | ||
| 834 | } | ||
| 835 | |||
| 836 | public int nextIndex() { | ||
| 837 | return cursor; | ||
| 838 | } | ||
| 839 | |||
| 840 | public int previousIndex() { | ||
| 841 | return cursor - 1; | ||
| 842 | } | ||
| 843 | |||
| 844 | @SuppressWarnings("unchecked") | ||
| 845 | public E previous() { | ||
| 846 | checkForComodification(); | ||
| 847 | int i = cursor - 1; | ||
| 848 | if (i < 0) | ||
| 849 | throw new NoSuchElementException(); | ||
| 850 | Object[] elementData = ArrayList.this.elementData; | ||
| 851 | if (i >= elementData.length) | ||
| 852 | throw new ConcurrentModificationException(); | ||
| 853 | cursor = i; | ||
| 854 | return (E) elementData[lastRet = i]; | ||
| 855 | } | ||
| 856 | |||
| 857 | public void set(E e) { | ||
| 858 | if (lastRet < 0) | ||
| 859 | throw new IllegalStateException(); | ||
| 860 | checkForComodification(); | ||
| 861 | |||
| 862 | try { | ||
| 863 | ArrayList.this.set(lastRet, e); | ||
| 864 | } catch (IndexOutOfBoundsException ex) { | ||
| 865 | throw new ConcurrentModificationException(); | ||
| 866 | } | ||
| 867 | } | ||
| 868 | |||
| 869 | public void add(E e) { | ||
| 870 | checkForComodification(); | ||
| 871 | |||
| 872 | try { | ||
| 873 | int i = cursor; | ||
| 874 | ArrayList.this.add(i, e); | ||
| 875 | cursor = i + 1; | ||
| 876 | lastRet = -1; | ||
| 877 | expectedModCount = modCount; | ||
| 878 | } catch (IndexOutOfBoundsException ex) { | ||
| 879 | throw new ConcurrentModificationException(); | ||
| 880 | } | ||
| 881 | } | ||
| 882 | } | ||
| 883 | |||
| 884 | /** | ||
| 885 | * Returns a view of the portion of this list between the specified | ||
| 886 | * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive. (If | ||
| 887 | * {@code fromIndex} and {@code toIndex} are equal, the returned list is | ||
| 888 | * empty.) The returned list is backed by this list, so non-structural | ||
| 889 | * changes in the returned list are reflected in this list, and vice-versa. | ||
| 890 | * The returned list supports all of the optional list operations. | ||
| 891 | * | ||
| 892 | * <p>This method eliminates the need for explicit range operations (of | ||
| 893 | * the sort that commonly exist for arrays). Any operation that expects | ||
| 894 | * a list can be used as a range operation by passing a subList view | ||
| 895 | * instead of a whole list. For example, the following idiom | ||
| 896 | * removes a range of elements from a list: | ||
| 897 | * <pre> | ||
| 898 | * list.subList(from, to).clear(); | ||
| 899 | * </pre> | ||
| 900 | * Similar idioms may be constructed for {@link #indexOf(Object)} and | ||
| 901 | * {@link #lastIndexOf(Object)}, and all of the algorithms in the | ||
| 902 | * {@link Collections} class can be applied to a subList. | ||
| 903 | * | ||
| 904 | * <p>The semantics of the list returned by this method become undefined if | ||
| 905 | * the backing list (i.e., this list) is <i>structurally modified</i> in | ||
| 906 | * any way other than via the returned list. (Structural modifications are | ||
| 907 | * those that change the size of this list, or otherwise perturb it in such | ||
| 908 | * a fashion that iterations in progress may yield incorrect results.) | ||
| 909 | * | ||
| 910 | * @throws IndexOutOfBoundsException {@inheritDoc} | ||
| 911 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 912 | */ | ||
| 913 | public List<E> subList(int fromIndex, int toIndex) { | ||
| 914 | subListRangeCheck(fromIndex, toIndex, size); | ||
| 915 | return new SubList(this, 0, fromIndex, toIndex); | ||
| 916 | } | ||
| 917 | |||
| 918 | static void subListRangeCheck(int fromIndex, int toIndex, int size) { | ||
| 919 | if (fromIndex < 0) | ||
| 920 | throw new IndexOutOfBoundsException("fromIndex = " + fromIndex); | ||
| 921 | if (toIndex > size) | ||
| 922 | throw new IndexOutOfBoundsException("toIndex = " + toIndex); | ||
| 923 | if (fromIndex > toIndex) | ||
| 924 | throw new IllegalArgumentException("fromIndex(" + fromIndex + | ||
| 925 | ") > toIndex(" + toIndex + ")"); | ||
| 926 | } | ||
| 927 | |||
| 928 | private class SubList extends AbstractList<E> implements RandomAccess { | ||
| 929 | private final AbstractList<E> parent; | ||
| 930 | private final int parentOffset; | ||
| 931 | private final int offset; | ||
| 932 | int size; | ||
| 933 | |||
| 934 | SubList(AbstractList<E> parent, | ||
| 935 | int offset, int fromIndex, int toIndex) { | ||
| 936 | this.parent = parent; | ||
| 937 | this.parentOffset = fromIndex; | ||
| 938 | this.offset = offset + fromIndex; | ||
| 939 | this.size = toIndex - fromIndex; | ||
| 940 | this.modCount = ArrayList.this.modCount; | ||
| 941 | } | ||
| 942 | |||
| 943 | public E set(int index, E e) { | ||
| 944 | rangeCheck(index); | ||
| 945 | checkForComodification(); | ||
| 946 | E oldValue = ArrayList.this.elementData(offset + index); | ||
| 947 | ArrayList.this.elementData[offset + index] = e; | ||
| 948 | return oldValue; | ||
| 949 | } | ||
| 950 | |||
| 951 | public E get(int index) { | ||
| 952 | rangeCheck(index); | ||
| 953 | checkForComodification(); | ||
| 954 | return ArrayList.this.elementData(offset + index); | ||
| 955 | } | ||
| 956 | |||
| 957 | public int size() { | ||
| 958 | checkForComodification(); | ||
| 959 | return this.size; | ||
| 960 | } | ||
| 961 | |||
| 962 | public void add(int index, E e) { | ||
| 963 | rangeCheckForAdd(index); | ||
| 964 | checkForComodification(); | ||
| 965 | parent.add(parentOffset + index, e); | ||
| 966 | this.modCount = parent.modCount; | ||
| 967 | this.size++; | ||
| 968 | } | ||
| 969 | |||
| 970 | public E remove(int index) { | ||
| 971 | rangeCheck(index); | ||
| 972 | checkForComodification(); | ||
| 973 | E result = parent.remove(parentOffset + index); | ||
| 974 | this.modCount = parent.modCount; | ||
| 975 | this.size--; | ||
| 976 | return result; | ||
| 977 | } | ||
| 978 | |||
| 979 | protected void removeRange(int fromIndex, int toIndex) { | ||
| 980 | checkForComodification(); | ||
| 981 | parent.removeRange(parentOffset + fromIndex, | ||
| 982 | parentOffset + toIndex); | ||
| 983 | this.modCount = parent.modCount; | ||
| 984 | this.size -= toIndex - fromIndex; | ||
| 985 | } | ||
| 986 | |||
| 987 | public boolean addAll(Collection<? extends E> c) { | ||
| 988 | return addAll(this.size, c); | ||
| 989 | } | ||
| 990 | |||
| 991 | public boolean addAll(int index, Collection<? extends E> c) { | ||
| 992 | rangeCheckForAdd(index); | ||
| 993 | int cSize = c.size(); | ||
| 994 | if (cSize==0) | ||
| 995 | return false; | ||
| 996 | |||
| 997 | checkForComodification(); | ||
| 998 | parent.addAll(parentOffset + index, c); | ||
| 999 | this.modCount = parent.modCount; | ||
| 1000 | this.size += cSize; | ||
| 1001 | return true; | ||
| 1002 | } | ||
| 1003 | |||
| 1004 | public Iterator<E> iterator() { | ||
| 1005 | return listIterator(); | ||
| 1006 | } | ||
| 1007 | |||
| 1008 | public ListIterator<E> listIterator(final int index) { | ||
| 1009 | checkForComodification(); | ||
| 1010 | rangeCheckForAdd(index); | ||
| 1011 | final int offset = this.offset; | ||
| 1012 | |||
| 1013 | return new ListIterator<E>() { | ||
| 1014 | int cursor = index; | ||
| 1015 | int lastRet = -1; | ||
| 1016 | int expectedModCount = ArrayList.this.modCount; | ||
| 1017 | |||
| 1018 | public boolean hasNext() { | ||
| 1019 | return cursor != SubList.this.size; | ||
| 1020 | } | ||
| 1021 | |||
| 1022 | @SuppressWarnings("unchecked") | ||
| 1023 | public E next() { | ||
| 1024 | checkForComodification(); | ||
| 1025 | int i = cursor; | ||
| 1026 | if (i >= SubList.this.size) | ||
| 1027 | throw new NoSuchElementException(); | ||
| 1028 | Object[] elementData = ArrayList.this.elementData; | ||
| 1029 | if (offset + i >= elementData.length) | ||
| 1030 | throw new ConcurrentModificationException(); | ||
| 1031 | cursor = i + 1; | ||
| 1032 | return (E) elementData[offset + (lastRet = i)]; | ||
| 1033 | } | ||
| 1034 | |||
| 1035 | public boolean hasPrevious() { | ||
| 1036 | return cursor != 0; | ||
| 1037 | } | ||
| 1038 | |||
| 1039 | @SuppressWarnings("unchecked") | ||
| 1040 | public E previous() { | ||
| 1041 | checkForComodification(); | ||
| 1042 | int i = cursor - 1; | ||
| 1043 | if (i < 0) | ||
| 1044 | throw new NoSuchElementException(); | ||
| 1045 | Object[] elementData = ArrayList.this.elementData; | ||
| 1046 | if (offset + i >= elementData.length) | ||
| 1047 | throw new ConcurrentModificationException(); | ||
| 1048 | cursor = i; | ||
| 1049 | return (E) elementData[offset + (lastRet = i)]; | ||
| 1050 | } | ||
| 1051 | |||
| 1052 | public int nextIndex() { | ||
| 1053 | return cursor; | ||
| 1054 | } | ||
| 1055 | |||
| 1056 | public int previousIndex() { | ||
| 1057 | return cursor - 1; | ||
| 1058 | } | ||
| 1059 | |||
| 1060 | public void remove() { | ||
| 1061 | if (lastRet < 0) | ||
| 1062 | throw new IllegalStateException(); | ||
| 1063 | checkForComodification(); | ||
| 1064 | |||
| 1065 | try { | ||
| 1066 | SubList.this.remove(lastRet); | ||
| 1067 | cursor = lastRet; | ||
| 1068 | lastRet = -1; | ||
| 1069 | expectedModCount = ArrayList.this.modCount; | ||
| 1070 | } catch (IndexOutOfBoundsException ex) { | ||
| 1071 | throw new ConcurrentModificationException(); | ||
| 1072 | } | ||
| 1073 | } | ||
| 1074 | |||
| 1075 | public void set(E e) { | ||
| 1076 | if (lastRet < 0) | ||
| 1077 | throw new IllegalStateException(); | ||
| 1078 | checkForComodification(); | ||
| 1079 | |||
| 1080 | try { | ||
| 1081 | ArrayList.this.set(offset + lastRet, e); | ||
| 1082 | } catch (IndexOutOfBoundsException ex) { | ||
| 1083 | throw new ConcurrentModificationException(); | ||
| 1084 | } | ||
| 1085 | } | ||
| 1086 | |||
| 1087 | public void add(E e) { | ||
| 1088 | checkForComodification(); | ||
| 1089 | |||
| 1090 | try { | ||
| 1091 | int i = cursor; | ||
| 1092 | SubList.this.add(i, e); | ||
| 1093 | cursor = i + 1; | ||
| 1094 | lastRet = -1; | ||
| 1095 | expectedModCount = ArrayList.this.modCount; | ||
| 1096 | } catch (IndexOutOfBoundsException ex) { | ||
| 1097 | throw new ConcurrentModificationException(); | ||
| 1098 | } | ||
| 1099 | } | ||
| 1100 | |||
| 1101 | final void checkForComodification() { | ||
| 1102 | if (expectedModCount != ArrayList.this.modCount) | ||
| 1103 | throw new ConcurrentModificationException(); | ||
| 1104 | } | ||
| 1105 | }; | ||
| 1106 | } | ||
| 1107 | |||
| 1108 | public List<E> subList(int fromIndex, int toIndex) { | ||
| 1109 | subListRangeCheck(fromIndex, toIndex, size); | ||
| 1110 | return new SubList(this, offset, fromIndex, toIndex); | ||
| 1111 | } | ||
| 1112 | |||
| 1113 | private void rangeCheck(int index) { | ||
| 1114 | if (index < 0 || index >= this.size) | ||
| 1115 | throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); | ||
| 1116 | } | ||
| 1117 | |||
| 1118 | private void rangeCheckForAdd(int index) { | ||
| 1119 | if (index < 0 || index > this.size) | ||
| 1120 | throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); | ||
| 1121 | } | ||
| 1122 | |||
| 1123 | private String outOfBoundsMsg(int index) { | ||
| 1124 | return "Index: "+index+", Size: "+this.size; | ||
| 1125 | } | ||
| 1126 | |||
| 1127 | private void checkForComodification() { | ||
| 1128 | if (ArrayList.this.modCount != this.modCount) | ||
| 1129 | throw new ConcurrentModificationException(); | ||
| 1130 | } | ||
| 1131 | } | ||
| 1132 | } | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,3673 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package java.util; | ||
| 27 | |||
| 28 | import java.lang.reflect.*; | ||
| 29 | |||
| 30 | /** | ||
| 31 | * This class contains various methods for manipulating arrays (such as | ||
| 32 | * sorting and searching). This class also contains a static factory | ||
| 33 | * that allows arrays to be viewed as lists. | ||
| 34 | * | ||
| 35 | * <p>The methods in this class all throw a {@code NullPointerException}, | ||
| 36 | * if the specified array reference is null, except where noted. | ||
| 37 | * | ||
| 38 | * <p>The documentation for the methods contained in this class includes | ||
| 39 | * briefs description of the <i>implementations</i>. Such descriptions should | ||
| 40 | * be regarded as <i>implementation notes</i>, rather than parts of the | ||
| 41 | * <i>specification</i>. Implementors should feel free to substitute other | ||
| 42 | * algorithms, so long as the specification itself is adhered to. (For | ||
| 43 | * example, the algorithm used by {@code sort(Object[])} does not have to be | ||
| 44 | * a MergeSort, but it does have to be <i>stable</i>.) | ||
| 45 | * | ||
| 46 | * <p>This class is a member of the | ||
| 47 | * <a href="{@docRoot}/../technotes/guides/collections/index.html"> | ||
| 48 | * Java Collections Framework</a>. | ||
| 49 | * | ||
| 50 | * @author Josh Bloch | ||
| 51 | * @author Neal Gafter | ||
| 52 | * @author John Rose | ||
| 53 | * @since 1.2 | ||
| 54 | */ | ||
| 55 | public class Arrays { | ||
| 56 | |||
| 57 | // Suppresses default constructor, ensuring non-instantiability. | ||
| 58 | private Arrays() {} | ||
| 59 | |||
| 60 | /* | ||
| 61 | * Sorting of primitive type arrays. | ||
| 62 | */ | ||
| 63 | |||
| 64 | /** | ||
| 65 | * Sorts the specified array into ascending numerical order. | ||
| 66 | * | ||
| 67 | * <p>Implementation note: The sorting algorithm is a Dual-Pivot Quicksort | ||
| 68 | * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm | ||
| 69 | * offers O(n log(n)) performance on many data sets that cause other | ||
| 70 | * quicksorts to degrade to quadratic performance, and is typically | ||
| 71 | * faster than traditional (one-pivot) Quicksort implementations. | ||
| 72 | * | ||
| 73 | * @param a the array to be sorted | ||
| 74 | */ | ||
| 75 | public static void sort(int[] a) { | ||
| 76 | DualPivotQuicksort.sort(a); | ||
| 77 | } | ||
| 78 | |||
| 79 | /** | ||
| 80 | * Sorts the specified range of the array into ascending order. The range | ||
| 81 | * to be sorted extends from the index {@code fromIndex}, inclusive, to | ||
| 82 | * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, | ||
| 83 | * the range to be sorted is empty. | ||
| 84 | * | ||
| 85 | * <p>Implementation note: The sorting algorithm is a Dual-Pivot Quicksort | ||
| 86 | * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm | ||
| 87 | * offers O(n log(n)) performance on many data sets that cause other | ||
| 88 | * quicksorts to degrade to quadratic performance, and is typically | ||
| 89 | * faster than traditional (one-pivot) Quicksort implementations. | ||
| 90 | * | ||
| 91 | * @param a the array to be sorted | ||
| 92 | * @param fromIndex the index of the first element, inclusive, to be sorted | ||
| 93 | * @param toIndex the index of the last element, exclusive, to be sorted | ||
| 94 | * | ||
| 95 | * @throws IllegalArgumentException if {@code fromIndex > toIndex} | ||
| 96 | * @throws ArrayIndexOutOfBoundsException | ||
| 97 | * if {@code fromIndex < 0} or {@code toIndex > a.length} | ||
| 98 | */ | ||
| 99 | public static void sort(int[] a, int fromIndex, int toIndex) { | ||
| 100 | rangeCheck(a.length, fromIndex, toIndex); | ||
| 101 | DualPivotQuicksort.sort(a, fromIndex, toIndex - 1); | ||
| 102 | } | ||
| 103 | |||
| 104 | /** | ||
| 105 | * Sorts the specified array into ascending numerical order. | ||
| 106 | * | ||
| 107 | * <p>Implementation note: The sorting algorithm is a Dual-Pivot Quicksort | ||
| 108 | * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm | ||
| 109 | * offers O(n log(n)) performance on many data sets that cause other | ||
| 110 | * quicksorts to degrade to quadratic performance, and is typically | ||
| 111 | * faster than traditional (one-pivot) Quicksort implementations. | ||
| 112 | * | ||
| 113 | * @param a the array to be sorted | ||
| 114 | */ | ||
| 115 | public static void sort(long[] a) { | ||
| 116 | DualPivotQuicksort.sort(a); | ||
| 117 | } | ||
| 118 | |||
| 119 | /** | ||
| 120 | * Sorts the specified range of the array into ascending order. The range | ||
| 121 | * to be sorted extends from the index {@code fromIndex}, inclusive, to | ||
| 122 | * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, | ||
| 123 | * the range to be sorted is empty. | ||
| 124 | * | ||
| 125 | * <p>Implementation note: The sorting algorithm is a Dual-Pivot Quicksort | ||
| 126 | * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm | ||
| 127 | * offers O(n log(n)) performance on many data sets that cause other | ||
| 128 | * quicksorts to degrade to quadratic performance, and is typically | ||
| 129 | * faster than traditional (one-pivot) Quicksort implementations. | ||
| 130 | * | ||
| 131 | * @param a the array to be sorted | ||
| 132 | * @param fromIndex the index of the first element, inclusive, to be sorted | ||
| 133 | * @param toIndex the index of the last element, exclusive, to be sorted | ||
| 134 | * | ||
| 135 | * @throws IllegalArgumentException if {@code fromIndex > toIndex} | ||
| 136 | * @throws ArrayIndexOutOfBoundsException | ||
| 137 | * if {@code fromIndex < 0} or {@code toIndex > a.length} | ||
| 138 | */ | ||
| 139 | public static void sort(long[] a, int fromIndex, int toIndex) { | ||
| 140 | rangeCheck(a.length, fromIndex, toIndex); | ||
| 141 | DualPivotQuicksort.sort(a, fromIndex, toIndex - 1); | ||
| 142 | } | ||
| 143 | |||
| 144 | /** | ||
| 145 | * Sorts the specified array into ascending numerical order. | ||
| 146 | * | ||
| 147 | * <p>Implementation note: The sorting algorithm is a Dual-Pivot Quicksort | ||
| 148 | * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm | ||
| 149 | * offers O(n log(n)) performance on many data sets that cause other | ||
| 150 | * quicksorts to degrade to quadratic performance, and is typically | ||
| 151 | * faster than traditional (one-pivot) Quicksort implementations. | ||
| 152 | * | ||
| 153 | * @param a the array to be sorted | ||
| 154 | */ | ||
| 155 | public static void sort(short[] a) { | ||
| 156 | DualPivotQuicksort.sort(a); | ||
| 157 | } | ||
| 158 | |||
| 159 | /** | ||
| 160 | * Sorts the specified range of the array into ascending order. The range | ||
| 161 | * to be sorted extends from the index {@code fromIndex}, inclusive, to | ||
| 162 | * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, | ||
| 163 | * the range to be sorted is empty. | ||
| 164 | * | ||
| 165 | * <p>Implementation note: The sorting algorithm is a Dual-Pivot Quicksort | ||
| 166 | * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm | ||
| 167 | * offers O(n log(n)) performance on many data sets that cause other | ||
| 168 | * quicksorts to degrade to quadratic performance, and is typically | ||
| 169 | * faster than traditional (one-pivot) Quicksort implementations. | ||
| 170 | * | ||
| 171 | * @param a the array to be sorted | ||
| 172 | * @param fromIndex the index of the first element, inclusive, to be sorted | ||
| 173 | * @param toIndex the index of the last element, exclusive, to be sorted | ||
| 174 | * | ||
| 175 | * @throws IllegalArgumentException if {@code fromIndex > toIndex} | ||
| 176 | * @throws ArrayIndexOutOfBoundsException | ||
| 177 | * if {@code fromIndex < 0} or {@code toIndex > a.length} | ||
| 178 | */ | ||
| 179 | public static void sort(short[] a, int fromIndex, int toIndex) { | ||
| 180 | rangeCheck(a.length, fromIndex, toIndex); | ||
| 181 | DualPivotQuicksort.sort(a, fromIndex, toIndex - 1); | ||
| 182 | } | ||
| 183 | |||
| 184 | /** | ||
| 185 | * Sorts the specified array into ascending numerical order. | ||
| 186 | * | ||
| 187 | * <p>Implementation note: The sorting algorithm is a Dual-Pivot Quicksort | ||
| 188 | * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm | ||
| 189 | * offers O(n log(n)) performance on many data sets that cause other | ||
| 190 | * quicksorts to degrade to quadratic performance, and is typically | ||
| 191 | * faster than traditional (one-pivot) Quicksort implementations. | ||
| 192 | * | ||
| 193 | * @param a the array to be sorted | ||
| 194 | */ | ||
| 195 | public static void sort(char[] a) { | ||
| 196 | DualPivotQuicksort.sort(a); | ||
| 197 | } | ||
| 198 | |||
| 199 | /** | ||
| 200 | * Sorts the specified range of the array into ascending order. The range | ||
| 201 | * to be sorted extends from the index {@code fromIndex}, inclusive, to | ||
| 202 | * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, | ||
| 203 | * the range to be sorted is empty. | ||
| 204 | * | ||
| 205 | * <p>Implementation note: The sorting algorithm is a Dual-Pivot Quicksort | ||
| 206 | * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm | ||
| 207 | * offers O(n log(n)) performance on many data sets that cause other | ||
| 208 | * quicksorts to degrade to quadratic performance, and is typically | ||
| 209 | * faster than traditional (one-pivot) Quicksort implementations. | ||
| 210 | * | ||
| 211 | * @param a the array to be sorted | ||
| 212 | * @param fromIndex the index of the first element, inclusive, to be sorted | ||
| 213 | * @param toIndex the index of the last element, exclusive, to be sorted | ||
| 214 | * | ||
| 215 | * @throws IllegalArgumentException if {@code fromIndex > toIndex} | ||
| 216 | * @throws ArrayIndexOutOfBoundsException | ||
| 217 | * if {@code fromIndex < 0} or {@code toIndex > a.length} | ||
| 218 | */ | ||
| 219 | public static void sort(char[] a, int fromIndex, int toIndex) { | ||
| 220 | rangeCheck(a.length, fromIndex, toIndex); | ||
| 221 | DualPivotQuicksort.sort(a, fromIndex, toIndex - 1); | ||
| 222 | } | ||
| 223 | |||
| 224 | /** | ||
| 225 | * Sorts the specified array into ascending numerical order. | ||
| 226 | * | ||
| 227 | * <p>Implementation note: The sorting algorithm is a Dual-Pivot Quicksort | ||
| 228 | * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm | ||
| 229 | * offers O(n log(n)) performance on many data sets that cause other | ||
| 230 | * quicksorts to degrade to quadratic performance, and is typically | ||
| 231 | * faster than traditional (one-pivot) Quicksort implementations. | ||
| 232 | * | ||
| 233 | * @param a the array to be sorted | ||
| 234 | */ | ||
| 235 | public static void sort(byte[] a) { | ||
| 236 | DualPivotQuicksort.sort(a); | ||
| 237 | } | ||
| 238 | |||
| 239 | /** | ||
| 240 | * Sorts the specified range of the array into ascending order. The range | ||
| 241 | * to be sorted extends from the index {@code fromIndex}, inclusive, to | ||
| 242 | * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, | ||
| 243 | * the range to be sorted is empty. | ||
| 244 | * | ||
| 245 | * <p>Implementation note: The sorting algorithm is a Dual-Pivot Quicksort | ||
| 246 | * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm | ||
| 247 | * offers O(n log(n)) performance on many data sets that cause other | ||
| 248 | * quicksorts to degrade to quadratic performance, and is typically | ||
| 249 | * faster than traditional (one-pivot) Quicksort implementations. | ||
| 250 | * | ||
| 251 | * @param a the array to be sorted | ||
| 252 | * @param fromIndex the index of the first element, inclusive, to be sorted | ||
| 253 | * @param toIndex the index of the last element, exclusive, to be sorted | ||
| 254 | * | ||
| 255 | * @throws IllegalArgumentException if {@code fromIndex > toIndex} | ||
| 256 | * @throws ArrayIndexOutOfBoundsException | ||
| 257 | * if {@code fromIndex < 0} or {@code toIndex > a.length} | ||
| 258 | */ | ||
| 259 | public static void sort(byte[] a, int fromIndex, int toIndex) { | ||
| 260 | rangeCheck(a.length, fromIndex, toIndex); | ||
| 261 | DualPivotQuicksort.sort(a, fromIndex, toIndex - 1); | ||
| 262 | } | ||
| 263 | |||
| 264 | /** | ||
| 265 | * Sorts the specified array into ascending numerical order. | ||
| 266 | * | ||
| 267 | * <p>The {@code <} relation does not provide a total order on all float | ||
| 268 | * values: {@code -0.0f == 0.0f} is {@code true} and a {@code Float.NaN} | ||
| 269 | * value compares neither less than, greater than, nor equal to any value, | ||
| 270 | * even itself. This method uses the total order imposed by the method | ||
| 271 | * {@link Float#compareTo}: {@code -0.0f} is treated as less than value | ||
| 272 | * {@code 0.0f} and {@code Float.NaN} is considered greater than any | ||
| 273 | * other value and all {@code Float.NaN} values are considered equal. | ||
| 274 | * | ||
| 275 | * <p>Implementation note: The sorting algorithm is a Dual-Pivot Quicksort | ||
| 276 | * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm | ||
| 277 | * offers O(n log(n)) performance on many data sets that cause other | ||
| 278 | * quicksorts to degrade to quadratic performance, and is typically | ||
| 279 | * faster than traditional (one-pivot) Quicksort implementations. | ||
| 280 | * | ||
| 281 | * @param a the array to be sorted | ||
| 282 | */ | ||
| 283 | public static void sort(float[] a) { | ||
| 284 | DualPivotQuicksort.sort(a); | ||
| 285 | } | ||
| 286 | |||
| 287 | /** | ||
| 288 | * Sorts the specified range of the array into ascending order. The range | ||
| 289 | * to be sorted extends from the index {@code fromIndex}, inclusive, to | ||
| 290 | * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, | ||
| 291 | * the range to be sorted is empty. | ||
| 292 | * | ||
| 293 | * <p>The {@code <} relation does not provide a total order on all float | ||
| 294 | * values: {@code -0.0f == 0.0f} is {@code true} and a {@code Float.NaN} | ||
| 295 | * value compares neither less than, greater than, nor equal to any value, | ||
| 296 | * even itself. This method uses the total order imposed by the method | ||
| 297 | * {@link Float#compareTo}: {@code -0.0f} is treated as less than value | ||
| 298 | * {@code 0.0f} and {@code Float.NaN} is considered greater than any | ||
| 299 | * other value and all {@code Float.NaN} values are considered equal. | ||
| 300 | * | ||
| 301 | * <p>Implementation note: The sorting algorithm is a Dual-Pivot Quicksort | ||
| 302 | * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm | ||
| 303 | * offers O(n log(n)) performance on many data sets that cause other | ||
| 304 | * quicksorts to degrade to quadratic performance, and is typically | ||
| 305 | * faster than traditional (one-pivot) Quicksort implementations. | ||
| 306 | * | ||
| 307 | * @param a the array to be sorted | ||
| 308 | * @param fromIndex the index of the first element, inclusive, to be sorted | ||
| 309 | * @param toIndex the index of the last element, exclusive, to be sorted | ||
| 310 | * | ||
| 311 | * @throws IllegalArgumentException if {@code fromIndex > toIndex} | ||
| 312 | * @throws ArrayIndexOutOfBoundsException | ||
| 313 | * if {@code fromIndex < 0} or {@code toIndex > a.length} | ||
| 314 | */ | ||
| 315 | public static void sort(float[] a, int fromIndex, int toIndex) { | ||
| 316 | rangeCheck(a.length, fromIndex, toIndex); | ||
| 317 | DualPivotQuicksort.sort(a, fromIndex, toIndex - 1); | ||
| 318 | } | ||
| 319 | |||
| 320 | /** | ||
| 321 | * Sorts the specified array into ascending numerical order. | ||
| 322 | * | ||
| 323 | * <p>The {@code <} relation does not provide a total order on all double | ||
| 324 | * values: {@code -0.0d == 0.0d} is {@code true} and a {@code Double.NaN} | ||
| 325 | * value compares neither less than, greater than, nor equal to any value, | ||
| 326 | * even itself. This method uses the total order imposed by the method | ||
| 327 | * {@link Double#compareTo}: {@code -0.0d} is treated as less than value | ||
| 328 | * {@code 0.0d} and {@code Double.NaN} is considered greater than any | ||
| 329 | * other value and all {@code Double.NaN} values are considered equal. | ||
| 330 | * | ||
| 331 | * <p>Implementation note: The sorting algorithm is a Dual-Pivot Quicksort | ||
| 332 | * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm | ||
| 333 | * offers O(n log(n)) performance on many data sets that cause other | ||
| 334 | * quicksorts to degrade to quadratic performance, and is typically | ||
| 335 | * faster than traditional (one-pivot) Quicksort implementations. | ||
| 336 | * | ||
| 337 | * @param a the array to be sorted | ||
| 338 | */ | ||
| 339 | public static void sort(double[] a) { | ||
| 340 | DualPivotQuicksort.sort(a); | ||
| 341 | } | ||
| 342 | |||
| 343 | /** | ||
| 344 | * Sorts the specified range of the array into ascending order. The range | ||
| 345 | * to be sorted extends from the index {@code fromIndex}, inclusive, to | ||
| 346 | * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, | ||
| 347 | * the range to be sorted is empty. | ||
| 348 | * | ||
| 349 | * <p>The {@code <} relation does not provide a total order on all double | ||
| 350 | * values: {@code -0.0d == 0.0d} is {@code true} and a {@code Double.NaN} | ||
| 351 | * value compares neither less than, greater than, nor equal to any value, | ||
| 352 | * even itself. This method uses the total order imposed by the method | ||
| 353 | * {@link Double#compareTo}: {@code -0.0d} is treated as less than value | ||
| 354 | * {@code 0.0d} and {@code Double.NaN} is considered greater than any | ||
| 355 | * other value and all {@code Double.NaN} values are considered equal. | ||
| 356 | * | ||
| 357 | * <p>Implementation note: The sorting algorithm is a Dual-Pivot Quicksort | ||
| 358 | * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm | ||
| 359 | * offers O(n log(n)) performance on many data sets that cause other | ||
| 360 | * quicksorts to degrade to quadratic performance, and is typically | ||
| 361 | * faster than traditional (one-pivot) Quicksort implementations. | ||
| 362 | * | ||
| 363 | * @param a the array to be sorted | ||
| 364 | * @param fromIndex the index of the first element, inclusive, to be sorted | ||
| 365 | * @param toIndex the index of the last element, exclusive, to be sorted | ||
| 366 | * | ||
| 367 | * @throws IllegalArgumentException if {@code fromIndex > toIndex} | ||
| 368 | * @throws ArrayIndexOutOfBoundsException | ||
| 369 | * if {@code fromIndex < 0} or {@code toIndex > a.length} | ||
| 370 | */ | ||
| 371 | public static void sort(double[] a, int fromIndex, int toIndex) { | ||
| 372 | rangeCheck(a.length, fromIndex, toIndex); | ||
| 373 | DualPivotQuicksort.sort(a, fromIndex, toIndex - 1); | ||
| 374 | } | ||
| 375 | |||
| 376 | /* | ||
| 377 | * Sorting of complex type arrays. | ||
| 378 | */ | ||
| 379 | |||
| 380 | /** | ||
| 381 | * Old merge sort implementation can be selected (for | ||
| 382 | * compatibility with broken comparators) using a system property. | ||
| 383 | * Cannot be a static boolean in the enclosing class due to | ||
| 384 | * circular dependencies. To be removed in a future release. | ||
| 385 | */ | ||
| 386 | static final class LegacyMergeSort { | ||
| 387 | private static final boolean userRequested = | ||
| 388 | java.security.AccessController.doPrivileged( | ||
| 389 | new sun.security.action.GetBooleanAction( | ||
| 390 | "java.util.Arrays.useLegacyMergeSort")).booleanValue(); | ||
| 391 | } | ||
| 392 | |||
| 393 | /* | ||
| 394 | * If this platform has an optimizing VM, check whether ComparableTimSort | ||
| 395 | * offers any performance benefit over TimSort in conjunction with a | ||
| 396 | * comparator that returns: | ||
| 397 | * {@code ((Comparable)first).compareTo(Second)}. | ||
| 398 | * If not, you are better off deleting ComparableTimSort to | ||
| 399 | * eliminate the code duplication. In other words, the commented | ||
| 400 | * out code below is the preferable implementation for sorting | ||
| 401 | * arrays of Comparables if it offers sufficient performance. | ||
| 402 | */ | ||
| 403 | |||
| 404 | // /** | ||
| 405 | // * A comparator that implements the natural ordering of a group of | ||
| 406 | // * mutually comparable elements. Using this comparator saves us | ||
| 407 | // * from duplicating most of the code in this file (one version for | ||
| 408 | // * Comparables, one for explicit Comparators). | ||
| 409 | // */ | ||
| 410 | // private static final Comparator<Object> NATURAL_ORDER = | ||
| 411 | // new Comparator<Object>() { | ||
| 412 | // @SuppressWarnings("unchecked") | ||
| 413 | // public int compare(Object first, Object second) { | ||
| 414 | // return ((Comparable<Object>)first).compareTo(second); | ||
| 415 | // } | ||
| 416 | // }; | ||
| 417 | // | ||
| 418 | // public static void sort(Object[] a) { | ||
| 419 | // sort(a, 0, a.length, NATURAL_ORDER); | ||
| 420 | // } | ||
| 421 | // | ||
| 422 | // public static void sort(Object[] a, int fromIndex, int toIndex) { | ||
| 423 | // sort(a, fromIndex, toIndex, NATURAL_ORDER); | ||
| 424 | // } | ||
| 425 | |||
| 426 | /** | ||
| 427 | * Sorts the specified array of objects into ascending order, according | ||
| 428 | * to the {@linkplain Comparable natural ordering} of its elements. | ||
| 429 | * All elements in the array must implement the {@link Comparable} | ||
| 430 | * interface. Furthermore, all elements in the array must be | ||
| 431 | * <i>mutually comparable</i> (that is, {@code e1.compareTo(e2)} must | ||
| 432 | * not throw a {@code ClassCastException} for any elements {@code e1} | ||
| 433 | * and {@code e2} in the array). | ||
| 434 | * | ||
| 435 | * <p>This sort is guaranteed to be <i>stable</i>: equal elements will | ||
| 436 | * not be reordered as a result of the sort. | ||
| 437 | * | ||
| 438 | * <p>Implementation note: This implementation is a stable, adaptive, | ||
| 439 | * iterative mergesort that requires far fewer than n lg(n) comparisons | ||
| 440 | * when the input array is partially sorted, while offering the | ||
| 441 | * performance of a traditional mergesort when the input array is | ||
| 442 | * randomly ordered. If the input array is nearly sorted, the | ||
| 443 | * implementation requires approximately n comparisons. Temporary | ||
| 444 | * storage requirements vary from a small constant for nearly sorted | ||
| 445 | * input arrays to n/2 object references for randomly ordered input | ||
| 446 | * arrays. | ||
| 447 | * | ||
| 448 | * <p>The implementation takes equal advantage of ascending and | ||
| 449 | * descending order in its input array, and can take advantage of | ||
| 450 | * ascending and descending order in different parts of the the same | ||
| 451 | * input array. It is well-suited to merging two or more sorted arrays: | ||
| 452 | * simply concatenate the arrays and sort the resulting array. | ||
| 453 | * | ||
| 454 | * <p>The implementation was adapted from Tim Peters's list sort for Python | ||
| 455 | * (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt"> | ||
| 456 | * TimSort</a>). It uses techiques from Peter McIlroy's "Optimistic | ||
| 457 | * Sorting and Information Theoretic Complexity", in Proceedings of the | ||
| 458 | * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474, | ||
| 459 | * January 1993. | ||
| 460 | * | ||
| 461 | * @param a the array to be sorted | ||
| 462 | * @throws ClassCastException if the array contains elements that are not | ||
| 463 | * <i>mutually comparable</i> (for example, strings and integers) | ||
| 464 | * @throws IllegalArgumentException (optional) if the natural | ||
| 465 | * ordering of the array elements is found to violate the | ||
| 466 | * {@link Comparable} contract | ||
| 467 | */ | ||
| 468 | public static void sort(Object[] a) { | ||
| 469 | if (LegacyMergeSort.userRequested) | ||
| 470 | legacyMergeSort(a); | ||
| 471 | else | ||
| 472 | ComparableTimSort.sort(a); | ||
| 473 | } | ||
| 474 | |||
| 475 | /** To be removed in a future release. */ | ||
| 476 | private static void legacyMergeSort(Object[] a) { | ||
| 477 | Object[] aux = a.clone(); | ||
| 478 | mergeSort(aux, a, 0, a.length, 0); | ||
| 479 | } | ||
| 480 | |||
| 481 | /** | ||
| 482 | * Sorts the specified range of the specified array of objects into | ||
| 483 | * ascending order, according to the | ||
| 484 | * {@linkplain Comparable natural ordering} of its | ||
| 485 | * elements. The range to be sorted extends from index | ||
| 486 | * {@code fromIndex}, inclusive, to index {@code toIndex}, exclusive. | ||
| 487 | * (If {@code fromIndex==toIndex}, the range to be sorted is empty.) All | ||
| 488 | * elements in this range must implement the {@link Comparable} | ||
| 489 | * interface. Furthermore, all elements in this range must be <i>mutually | ||
| 490 | * comparable</i> (that is, {@code e1.compareTo(e2)} must not throw a | ||
| 491 | * {@code ClassCastException} for any elements {@code e1} and | ||
| 492 | * {@code e2} in the array). | ||
| 493 | * | ||
| 494 | * <p>This sort is guaranteed to be <i>stable</i>: equal elements will | ||
| 495 | * not be reordered as a result of the sort. | ||
| 496 | * | ||
| 497 | * <p>Implementation note: This implementation is a stable, adaptive, | ||
| 498 | * iterative mergesort that requires far fewer than n lg(n) comparisons | ||
| 499 | * when the input array is partially sorted, while offering the | ||
| 500 | * performance of a traditional mergesort when the input array is | ||
| 501 | * randomly ordered. If the input array is nearly sorted, the | ||
| 502 | * implementation requires approximately n comparisons. Temporary | ||
| 503 | * storage requirements vary from a small constant for nearly sorted | ||
| 504 | * input arrays to n/2 object references for randomly ordered input | ||
| 505 | * arrays. | ||
| 506 | * | ||
| 507 | * <p>The implementation takes equal advantage of ascending and | ||
| 508 | * descending order in its input array, and can take advantage of | ||
| 509 | * ascending and descending order in different parts of the the same | ||
| 510 | * input array. It is well-suited to merging two or more sorted arrays: | ||
| 511 | * simply concatenate the arrays and sort the resulting array. | ||
| 512 | * | ||
| 513 | * <p>The implementation was adapted from Tim Peters's list sort for Python | ||
| 514 | * (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt"> | ||
| 515 | * TimSort</a>). It uses techiques from Peter McIlroy's "Optimistic | ||
| 516 | * Sorting and Information Theoretic Complexity", in Proceedings of the | ||
| 517 | * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474, | ||
| 518 | * January 1993. | ||
| 519 | * | ||
| 520 | * @param a the array to be sorted | ||
| 521 | * @param fromIndex the index of the first element (inclusive) to be | ||
| 522 | * sorted | ||
| 523 | * @param toIndex the index of the last element (exclusive) to be sorted | ||
| 524 | * @throws IllegalArgumentException if {@code fromIndex > toIndex} or | ||
| 525 | * (optional) if the natural ordering of the array elements is | ||
| 526 | * found to violate the {@link Comparable} contract | ||
| 527 | * @throws ArrayIndexOutOfBoundsException if {@code fromIndex < 0} or | ||
| 528 | * {@code toIndex > a.length} | ||
| 529 | * @throws ClassCastException if the array contains elements that are | ||
| 530 | * not <i>mutually comparable</i> (for example, strings and | ||
| 531 | * integers). | ||
| 532 | */ | ||
| 533 | public static void sort(Object[] a, int fromIndex, int toIndex) { | ||
| 534 | if (LegacyMergeSort.userRequested) | ||
| 535 | legacyMergeSort(a, fromIndex, toIndex); | ||
| 536 | else | ||
| 537 | ComparableTimSort.sort(a, fromIndex, toIndex); | ||
| 538 | } | ||
| 539 | |||
| 540 | /** To be removed in a future release. */ | ||
| 541 | private static void legacyMergeSort(Object[] a, | ||
| 542 | int fromIndex, int toIndex) { | ||
| 543 | rangeCheck(a.length, fromIndex, toIndex); | ||
| 544 | Object[] aux = copyOfRange(a, fromIndex, toIndex); | ||
| 545 | mergeSort(aux, a, fromIndex, toIndex, -fromIndex); | ||
| 546 | } | ||
| 547 | |||
| 548 | /** | ||
| 549 | * Tuning parameter: list size at or below which insertion sort will be | ||
| 550 | * used in preference to mergesort. | ||
| 551 | * To be removed in a future release. | ||
| 552 | */ | ||
| 553 | private static final int INSERTIONSORT_THRESHOLD = 7; | ||
| 554 | |||
| 555 | /** | ||
| 556 | * Src is the source array that starts at index 0 | ||
| 557 | * Dest is the (possibly larger) array destination with a possible offset | ||
| 558 | * low is the index in dest to start sorting | ||
| 559 | * high is the end index in dest to end sorting | ||
| 560 | * off is the offset to generate corresponding low, high in src | ||
| 561 | * To be removed in a future release. | ||
| 562 | */ | ||
| 563 | private static void mergeSort(Object[] src, | ||
| 564 | Object[] dest, | ||
| 565 | int low, | ||
| 566 | int high, | ||
| 567 | int off) { | ||
| 568 | int length = high - low; | ||
| 569 | |||
| 570 | // Insertion sort on smallest arrays | ||
| 571 | if (length < INSERTIONSORT_THRESHOLD) { | ||
| 572 | for (int i=low; i<high; i++) | ||
| 573 | for (int j=i; j>low && | ||
| 574 | ((Comparable) dest[j-1]).compareTo(dest[j])>0; j--) | ||
| 575 | swap(dest, j, j-1); | ||
| 576 | return; | ||
| 577 | } | ||
| 578 | |||
| 579 | // Recursively sort halves of dest into src | ||
| 580 | int destLow = low; | ||
| 581 | int destHigh = high; | ||
| 582 | low += off; | ||
| 583 | high += off; | ||
| 584 | int mid = (low + high) >>> 1; | ||
| 585 | mergeSort(dest, src, low, mid, -off); | ||
| 586 | mergeSort(dest, src, mid, high, -off); | ||
| 587 | |||
| 588 | // If list is already sorted, just copy from src to dest. This is an | ||
| 589 | // optimization that results in faster sorts for nearly ordered lists. | ||
| 590 | if (((Comparable)src[mid-1]).compareTo(src[mid]) <= 0) { | ||
| 591 | System.arraycopy(src, low, dest, destLow, length); | ||
| 592 | return; | ||
| 593 | } | ||
| 594 | |||
| 595 | // Merge sorted halves (now in src) into dest | ||
| 596 | for(int i = destLow, p = low, q = mid; i < destHigh; i++) { | ||
| 597 | if (q >= high || p < mid && ((Comparable)src[p]).compareTo(src[q])<=0) | ||
| 598 | dest[i] = src[p++]; | ||
| 599 | else | ||
| 600 | dest[i] = src[q++]; | ||
| 601 | } | ||
| 602 | } | ||
| 603 | |||
| 604 | /** | ||
| 605 | * Swaps x[a] with x[b]. | ||
| 606 | */ | ||
| 607 | private static void swap(Object[] x, int a, int b) { | ||
| 608 | Object t = x[a]; | ||
| 609 | x[a] = x[b]; | ||
| 610 | x[b] = t; | ||
| 611 | } | ||
| 612 | |||
| 613 | /** | ||
| 614 | * Sorts the specified array of objects according to the order induced by | ||
| 615 | * the specified comparator. All elements in the array must be | ||
| 616 | * <i>mutually comparable</i> by the specified comparator (that is, | ||
| 617 | * {@code c.compare(e1, e2)} must not throw a {@code ClassCastException} | ||
| 618 | * for any elements {@code e1} and {@code e2} in the array). | ||
| 619 | * | ||
| 620 | * <p>This sort is guaranteed to be <i>stable</i>: equal elements will | ||
| 621 | * not be reordered as a result of the sort. | ||
| 622 | * | ||
| 623 | * <p>Implementation note: This implementation is a stable, adaptive, | ||
| 624 | * iterative mergesort that requires far fewer than n lg(n) comparisons | ||
| 625 | * when the input array is partially sorted, while offering the | ||
| 626 | * performance of a traditional mergesort when the input array is | ||
| 627 | * randomly ordered. If the input array is nearly sorted, the | ||
| 628 | * implementation requires approximately n comparisons. Temporary | ||
| 629 | * storage requirements vary from a small constant for nearly sorted | ||
| 630 | * input arrays to n/2 object references for randomly ordered input | ||
| 631 | * arrays. | ||
| 632 | * | ||
| 633 | * <p>The implementation takes equal advantage of ascending and | ||
| 634 | * descending order in its input array, and can take advantage of | ||
| 635 | * ascending and descending order in different parts of the the same | ||
| 636 | * input array. It is well-suited to merging two or more sorted arrays: | ||
| 637 | * simply concatenate the arrays and sort the resulting array. | ||
| 638 | * | ||
| 639 | * <p>The implementation was adapted from Tim Peters's list sort for Python | ||
| 640 | * (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt"> | ||
| 641 | * TimSort</a>). It uses techiques from Peter McIlroy's "Optimistic | ||
| 642 | * Sorting and Information Theoretic Complexity", in Proceedings of the | ||
| 643 | * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474, | ||
| 644 | * January 1993. | ||
| 645 | * | ||
| 646 | * @param a the array to be sorted | ||
| 647 | * @param c the comparator to determine the order of the array. A | ||
| 648 | * {@code null} value indicates that the elements' | ||
| 649 | * {@linkplain Comparable natural ordering} should be used. | ||
| 650 | * @throws ClassCastException if the array contains elements that are | ||
| 651 | * not <i>mutually comparable</i> using the specified comparator | ||
| 652 | * @throws IllegalArgumentException (optional) if the comparator is | ||
| 653 | * found to violate the {@link Comparator} contract | ||
| 654 | */ | ||
| 655 | public static <T> void sort(T[] a, Comparator<? super T> c) { | ||
| 656 | if (LegacyMergeSort.userRequested) | ||
| 657 | legacyMergeSort(a, c); | ||
| 658 | else | ||
| 659 | TimSort.sort(a, c); | ||
| 660 | } | ||
| 661 | |||
| 662 | /** To be removed in a future release. */ | ||
| 663 | private static <T> void legacyMergeSort(T[] a, Comparator<? super T> c) { | ||
| 664 | T[] aux = a.clone(); | ||
| 665 | if (c==null) | ||
| 666 | mergeSort(aux, a, 0, a.length, 0); | ||
| 667 | else | ||
| 668 | mergeSort(aux, a, 0, a.length, 0, c); | ||
| 669 | } | ||
| 670 | |||
| 671 | /** | ||
| 672 | * Sorts the specified range of the specified array of objects according | ||
| 673 | * to the order induced by the specified comparator. The range to be | ||
| 674 | * sorted extends from index {@code fromIndex}, inclusive, to index | ||
| 675 | * {@code toIndex}, exclusive. (If {@code fromIndex==toIndex}, the | ||
| 676 | * range to be sorted is empty.) All elements in the range must be | ||
| 677 | * <i>mutually comparable</i> by the specified comparator (that is, | ||
| 678 | * {@code c.compare(e1, e2)} must not throw a {@code ClassCastException} | ||
| 679 | * for any elements {@code e1} and {@code e2} in the range). | ||
| 680 | * | ||
| 681 | * <p>This sort is guaranteed to be <i>stable</i>: equal elements will | ||
| 682 | * not be reordered as a result of the sort. | ||
| 683 | * | ||
| 684 | * <p>Implementation note: This implementation is a stable, adaptive, | ||
| 685 | * iterative mergesort that requires far fewer than n lg(n) comparisons | ||
| 686 | * when the input array is partially sorted, while offering the | ||
| 687 | * performance of a traditional mergesort when the input array is | ||
| 688 | * randomly ordered. If the input array is nearly sorted, the | ||
| 689 | * implementation requires approximately n comparisons. Temporary | ||
| 690 | * storage requirements vary from a small constant for nearly sorted | ||
| 691 | * input arrays to n/2 object references for randomly ordered input | ||
| 692 | * arrays. | ||
| 693 | * | ||
| 694 | * <p>The implementation takes equal advantage of ascending and | ||
| 695 | * descending order in its input array, and can take advantage of | ||
| 696 | * ascending and descending order in different parts of the the same | ||
| 697 | * input array. It is well-suited to merging two or more sorted arrays: | ||
| 698 | * simply concatenate the arrays and sort the resulting array. | ||
| 699 | * | ||
| 700 | * <p>The implementation was adapted from Tim Peters's list sort for Python | ||
| 701 | * (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt"> | ||
| 702 | * TimSort</a>). It uses techiques from Peter McIlroy's "Optimistic | ||
| 703 | * Sorting and Information Theoretic Complexity", in Proceedings of the | ||
| 704 | * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474, | ||
| 705 | * January 1993. | ||
| 706 | * | ||
| 707 | * @param a the array to be sorted | ||
| 708 | * @param fromIndex the index of the first element (inclusive) to be | ||
| 709 | * sorted | ||
| 710 | * @param toIndex the index of the last element (exclusive) to be sorted | ||
| 711 | * @param c the comparator to determine the order of the array. A | ||
| 712 | * {@code null} value indicates that the elements' | ||
| 713 | * {@linkplain Comparable natural ordering} should be used. | ||
| 714 | * @throws ClassCastException if the array contains elements that are not | ||
| 715 | * <i>mutually comparable</i> using the specified comparator. | ||
| 716 | * @throws IllegalArgumentException if {@code fromIndex > toIndex} or | ||
| 717 | * (optional) if the comparator is found to violate the | ||
| 718 | * {@link Comparator} contract | ||
| 719 | * @throws ArrayIndexOutOfBoundsException if {@code fromIndex < 0} or | ||
| 720 | * {@code toIndex > a.length} | ||
| 721 | */ | ||
| 722 | public static <T> void sort(T[] a, int fromIndex, int toIndex, | ||
| 723 | Comparator<? super T> c) { | ||
| 724 | if (LegacyMergeSort.userRequested) | ||
| 725 | legacyMergeSort(a, fromIndex, toIndex, c); | ||
| 726 | else | ||
| 727 | TimSort.sort(a, fromIndex, toIndex, c); | ||
| 728 | } | ||
| 729 | |||
| 730 | /** To be removed in a future release. */ | ||
| 731 | private static <T> void legacyMergeSort(T[] a, int fromIndex, int toIndex, | ||
| 732 | Comparator<? super T> c) { | ||
| 733 | rangeCheck(a.length, fromIndex, toIndex); | ||
| 734 | T[] aux = copyOfRange(a, fromIndex, toIndex); | ||
| 735 | if (c==null) | ||
| 736 | mergeSort(aux, a, fromIndex, toIndex, -fromIndex); | ||
| 737 | else | ||
| 738 | mergeSort(aux, a, fromIndex, toIndex, -fromIndex, c); | ||
| 739 | } | ||
| 740 | |||
| 741 | /** | ||
| 742 | * Src is the source array that starts at index 0 | ||
| 743 | * Dest is the (possibly larger) array destination with a possible offset | ||
| 744 | * low is the index in dest to start sorting | ||
| 745 | * high is the end index in dest to end sorting | ||
| 746 | * off is the offset into src corresponding to low in dest | ||
| 747 | * To be removed in a future release. | ||
| 748 | */ | ||
| 749 | private static void mergeSort(Object[] src, | ||
| 750 | Object[] dest, | ||
| 751 | int low, int high, int off, | ||
| 752 | Comparator c) { | ||
| 753 | int length = high - low; | ||
| 754 | |||
| 755 | // Insertion sort on smallest arrays | ||
| 756 | if (length < INSERTIONSORT_THRESHOLD) { | ||
| 757 | for (int i=low; i<high; i++) | ||
| 758 | for (int j=i; j>low && c.compare(dest[j-1], dest[j])>0; j--) | ||
| 759 | swap(dest, j, j-1); | ||
| 760 | return; | ||
| 761 | } | ||
| 762 | |||
| 763 | // Recursively sort halves of dest into src | ||
| 764 | int destLow = low; | ||
| 765 | int destHigh = high; | ||
| 766 | low += off; | ||
| 767 | high += off; | ||
| 768 | int mid = (low + high) >>> 1; | ||
| 769 | mergeSort(dest, src, low, mid, -off, c); | ||
| 770 | mergeSort(dest, src, mid, high, -off, c); | ||
| 771 | |||
| 772 | // If list is already sorted, just copy from src to dest. This is an | ||
| 773 | // optimization that results in faster sorts for nearly ordered lists. | ||
| 774 | if (c.compare(src[mid-1], src[mid]) <= 0) { | ||
| 775 | System.arraycopy(src, low, dest, destLow, length); | ||
| 776 | return; | ||
| 777 | } | ||
| 778 | |||
| 779 | // Merge sorted halves (now in src) into dest | ||
| 780 | for(int i = destLow, p = low, q = mid; i < destHigh; i++) { | ||
| 781 | if (q >= high || p < mid && c.compare(src[p], src[q]) <= 0) | ||
| 782 | dest[i] = src[p++]; | ||
| 783 | else | ||
| 784 | dest[i] = src[q++]; | ||
| 785 | } | ||
| 786 | } | ||
| 787 | |||
| 788 | /** | ||
| 789 | * Checks that {@code fromIndex} and {@code toIndex} are in | ||
| 790 | * the range and throws an appropriate exception, if they aren't. | ||
| 791 | */ | ||
| 792 | private static void rangeCheck(int length, int fromIndex, int toIndex) { | ||
| 793 | if (fromIndex > toIndex) { | ||
| 794 | throw new IllegalArgumentException( | ||
| 795 | "fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")"); | ||
| 796 | } | ||
| 797 | if (fromIndex < 0) { | ||
| 798 | throw new ArrayIndexOutOfBoundsException(fromIndex); | ||
| 799 | } | ||
| 800 | if (toIndex > length) { | ||
| 801 | throw new ArrayIndexOutOfBoundsException(toIndex); | ||
| 802 | } | ||
| 803 | } | ||
| 804 | |||
| 805 | // Searching | ||
| 806 | |||
| 807 | /** | ||
| 808 | * Searches the specified array of longs for the specified value using the | ||
| 809 | * binary search algorithm. The array must be sorted (as | ||
| 810 | * by the {@link #sort(long[])} method) prior to making this call. If it | ||
| 811 | * is not sorted, the results are undefined. If the array contains | ||
| 812 | * multiple elements with the specified value, there is no guarantee which | ||
| 813 | * one will be found. | ||
| 814 | * | ||
| 815 | * @param a the array to be searched | ||
| 816 | * @param key the value to be searched for | ||
| 817 | * @return index of the search key, if it is contained in the array; | ||
| 818 | * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The | ||
| 819 | * <i>insertion point</i> is defined as the point at which the | ||
| 820 | * key would be inserted into the array: the index of the first | ||
| 821 | * element greater than the key, or <tt>a.length</tt> if all | ||
| 822 | * elements in the array are less than the specified key. Note | ||
| 823 | * that this guarantees that the return value will be >= 0 if | ||
| 824 | * and only if the key is found. | ||
| 825 | */ | ||
| 826 | public static int binarySearch(long[] a, long key) { | ||
| 827 | return binarySearch0(a, 0, a.length, key); | ||
| 828 | } | ||
| 829 | |||
| 830 | /** | ||
| 831 | * Searches a range of | ||
| 832 | * the specified array of longs for the specified value using the | ||
| 833 | * binary search algorithm. | ||
| 834 | * The range must be sorted (as | ||
| 835 | * by the {@link #sort(long[], int, int)} method) | ||
| 836 | * prior to making this call. If it | ||
| 837 | * is not sorted, the results are undefined. If the range contains | ||
| 838 | * multiple elements with the specified value, there is no guarantee which | ||
| 839 | * one will be found. | ||
| 840 | * | ||
| 841 | * @param a the array to be searched | ||
| 842 | * @param fromIndex the index of the first element (inclusive) to be | ||
| 843 | * searched | ||
| 844 | * @param toIndex the index of the last element (exclusive) to be searched | ||
| 845 | * @param key the value to be searched for | ||
| 846 | * @return index of the search key, if it is contained in the array | ||
| 847 | * within the specified range; | ||
| 848 | * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The | ||
| 849 | * <i>insertion point</i> is defined as the point at which the | ||
| 850 | * key would be inserted into the array: the index of the first | ||
| 851 | * element in the range greater than the key, | ||
| 852 | * or <tt>toIndex</tt> if all | ||
| 853 | * elements in the range are less than the specified key. Note | ||
| 854 | * that this guarantees that the return value will be >= 0 if | ||
| 855 | * and only if the key is found. | ||
| 856 | * @throws IllegalArgumentException | ||
| 857 | * if {@code fromIndex > toIndex} | ||
| 858 | * @throws ArrayIndexOutOfBoundsException | ||
| 859 | * if {@code fromIndex < 0 or toIndex > a.length} | ||
| 860 | * @since 1.6 | ||
| 861 | */ | ||
| 862 | public static int binarySearch(long[] a, int fromIndex, int toIndex, | ||
| 863 | long key) { | ||
| 864 | rangeCheck(a.length, fromIndex, toIndex); | ||
| 865 | return binarySearch0(a, fromIndex, toIndex, key); | ||
| 866 | } | ||
| 867 | |||
| 868 | // Like public version, but without range checks. | ||
| 869 | private static int binarySearch0(long[] a, int fromIndex, int toIndex, | ||
| 870 | long key) { | ||
| 871 | int low = fromIndex; | ||
| 872 | int high = toIndex - 1; | ||
| 873 | |||
| 874 | while (low <= high) { | ||
| 875 | int mid = (low + high) >>> 1; | ||
| 876 | long midVal = a[mid]; | ||
| 877 | |||
| 878 | if (midVal < key) | ||
| 879 | low = mid + 1; | ||
| 880 | else if (midVal > key) | ||
| 881 | high = mid - 1; | ||
| 882 | else | ||
| 883 | return mid; // key found | ||
| 884 | } | ||
| 885 | return -(low + 1); // key not found. | ||
| 886 | } | ||
| 887 | |||
| 888 | /** | ||
| 889 | * Searches the specified array of ints for the specified value using the | ||
| 890 | * binary search algorithm. The array must be sorted (as | ||
| 891 | * by the {@link #sort(int[])} method) prior to making this call. If it | ||
| 892 | * is not sorted, the results are undefined. If the array contains | ||
| 893 | * multiple elements with the specified value, there is no guarantee which | ||
| 894 | * one will be found. | ||
| 895 | * | ||
| 896 | * @param a the array to be searched | ||
| 897 | * @param key the value to be searched for | ||
| 898 | * @return index of the search key, if it is contained in the array; | ||
| 899 | * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The | ||
| 900 | * <i>insertion point</i> is defined as the point at which the | ||
| 901 | * key would be inserted into the array: the index of the first | ||
| 902 | * element greater than the key, or <tt>a.length</tt> if all | ||
| 903 | * elements in the array are less than the specified key. Note | ||
| 904 | * that this guarantees that the return value will be >= 0 if | ||
| 905 | * and only if the key is found. | ||
| 906 | */ | ||
| 907 | public static int binarySearch(int[] a, int key) { | ||
| 908 | return binarySearch0(a, 0, a.length, key); | ||
| 909 | } | ||
| 910 | |||
| 911 | /** | ||
| 912 | * Searches a range of | ||
| 913 | * the specified array of ints for the specified value using the | ||
| 914 | * binary search algorithm. | ||
| 915 | * The range must be sorted (as | ||
| 916 | * by the {@link #sort(int[], int, int)} method) | ||
| 917 | * prior to making this call. If it | ||
| 918 | * is not sorted, the results are undefined. If the range contains | ||
| 919 | * multiple elements with the specified value, there is no guarantee which | ||
| 920 | * one will be found. | ||
| 921 | * | ||
| 922 | * @param a the array to be searched | ||
| 923 | * @param fromIndex the index of the first element (inclusive) to be | ||
| 924 | * searched | ||
| 925 | * @param toIndex the index of the last element (exclusive) to be searched | ||
| 926 | * @param key the value to be searched for | ||
| 927 | * @return index of the search key, if it is contained in the array | ||
| 928 | * within the specified range; | ||
| 929 | * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The | ||
| 930 | * <i>insertion point</i> is defined as the point at which the | ||
| 931 | * key would be inserted into the array: the index of the first | ||
| 932 | * element in the range greater than the key, | ||
| 933 | * or <tt>toIndex</tt> if all | ||
| 934 | * elements in the range are less than the specified key. Note | ||
| 935 | * that this guarantees that the return value will be >= 0 if | ||
| 936 | * and only if the key is found. | ||
| 937 | * @throws IllegalArgumentException | ||
| 938 | * if {@code fromIndex > toIndex} | ||
| 939 | * @throws ArrayIndexOutOfBoundsException | ||
| 940 | * if {@code fromIndex < 0 or toIndex > a.length} | ||
| 941 | * @since 1.6 | ||
| 942 | */ | ||
| 943 | public static int binarySearch(int[] a, int fromIndex, int toIndex, | ||
| 944 | int key) { | ||
| 945 | rangeCheck(a.length, fromIndex, toIndex); | ||
| 946 | return binarySearch0(a, fromIndex, toIndex, key); | ||
| 947 | } | ||
| 948 | |||
| 949 | // Like public version, but without range checks. | ||
| 950 | private static int binarySearch0(int[] a, int fromIndex, int toIndex, | ||
| 951 | int key) { | ||
| 952 | int low = fromIndex; | ||
| 953 | int high = toIndex - 1; | ||
| 954 | |||
| 955 | while (low <= high) { | ||
| 956 | int mid = (low + high) >>> 1; | ||
| 957 | int midVal = a[mid]; | ||
| 958 | |||
| 959 | if (midVal < key) | ||
| 960 | low = mid + 1; | ||
| 961 | else if (midVal > key) | ||
| 962 | high = mid - 1; | ||
| 963 | else | ||
| 964 | return mid; // key found | ||
| 965 | } | ||
| 966 | return -(low + 1); // key not found. | ||
| 967 | } | ||
| 968 | |||
| 969 | /** | ||
| 970 | * Searches the specified array of shorts for the specified value using | ||
| 971 | * the binary search algorithm. The array must be sorted | ||
| 972 | * (as by the {@link #sort(short[])} method) prior to making this call. If | ||
| 973 | * it is not sorted, the results are undefined. If the array contains | ||
| 974 | * multiple elements with the specified value, there is no guarantee which | ||
| 975 | * one will be found. | ||
| 976 | * | ||
| 977 | * @param a the array to be searched | ||
| 978 | * @param key the value to be searched for | ||
| 979 | * @return index of the search key, if it is contained in the array; | ||
| 980 | * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The | ||
| 981 | * <i>insertion point</i> is defined as the point at which the | ||
| 982 | * key would be inserted into the array: the index of the first | ||
| 983 | * element greater than the key, or <tt>a.length</tt> if all | ||
| 984 | * elements in the array are less than the specified key. Note | ||
| 985 | * that this guarantees that the return value will be >= 0 if | ||
| 986 | * and only if the key is found. | ||
| 987 | */ | ||
| 988 | public static int binarySearch(short[] a, short key) { | ||
| 989 | return binarySearch0(a, 0, a.length, key); | ||
| 990 | } | ||
| 991 | |||
| 992 | /** | ||
| 993 | * Searches a range of | ||
| 994 | * the specified array of shorts for the specified value using | ||
| 995 | * the binary search algorithm. | ||
| 996 | * The range must be sorted | ||
| 997 | * (as by the {@link #sort(short[], int, int)} method) | ||
| 998 | * prior to making this call. If | ||
| 999 | * it is not sorted, the results are undefined. If the range contains | ||
| 1000 | * multiple elements with the specified value, there is no guarantee which | ||
| 1001 | * one will be found. | ||
| 1002 | * | ||
| 1003 | * @param a the array to be searched | ||
| 1004 | * @param fromIndex the index of the first element (inclusive) to be | ||
| 1005 | * searched | ||
| 1006 | * @param toIndex the index of the last element (exclusive) to be searched | ||
| 1007 | * @param key the value to be searched for | ||
| 1008 | * @return index of the search key, if it is contained in the array | ||
| 1009 | * within the specified range; | ||
| 1010 | * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The | ||
| 1011 | * <i>insertion point</i> is defined as the point at which the | ||
| 1012 | * key would be inserted into the array: the index of the first | ||
| 1013 | * element in the range greater than the key, | ||
| 1014 | * or <tt>toIndex</tt> if all | ||
| 1015 | * elements in the range are less than the specified key. Note | ||
| 1016 | * that this guarantees that the return value will be >= 0 if | ||
| 1017 | * and only if the key is found. | ||
| 1018 | * @throws IllegalArgumentException | ||
| 1019 | * if {@code fromIndex > toIndex} | ||
| 1020 | * @throws ArrayIndexOutOfBoundsException | ||
| 1021 | * if {@code fromIndex < 0 or toIndex > a.length} | ||
| 1022 | * @since 1.6 | ||
| 1023 | */ | ||
| 1024 | public static int binarySearch(short[] a, int fromIndex, int toIndex, | ||
| 1025 | short key) { | ||
| 1026 | rangeCheck(a.length, fromIndex, toIndex); | ||
| 1027 | return binarySearch0(a, fromIndex, toIndex, key); | ||
| 1028 | } | ||
| 1029 | |||
| 1030 | // Like public version, but without range checks. | ||
| 1031 | private static int binarySearch0(short[] a, int fromIndex, int toIndex, | ||
| 1032 | short key) { | ||
| 1033 | int low = fromIndex; | ||
| 1034 | int high = toIndex - 1; | ||
| 1035 | |||
| 1036 | while (low <= high) { | ||
| 1037 | int mid = (low + high) >>> 1; | ||
| 1038 | short midVal = a[mid]; | ||
| 1039 | |||
| 1040 | if (midVal < key) | ||
| 1041 | low = mid + 1; | ||
| 1042 | else if (midVal > key) | ||
| 1043 | high = mid - 1; | ||
| 1044 | else | ||
| 1045 | return mid; // key found | ||
| 1046 | } | ||
| 1047 | return -(low + 1); // key not found. | ||
| 1048 | } | ||
| 1049 | |||
| 1050 | /** | ||
| 1051 | * Searches the specified array of chars for the specified value using the | ||
| 1052 | * binary search algorithm. The array must be sorted (as | ||
| 1053 | * by the {@link #sort(char[])} method) prior to making this call. If it | ||
| 1054 | * is not sorted, the results are undefined. If the array contains | ||
| 1055 | * multiple elements with the specified value, there is no guarantee which | ||
| 1056 | * one will be found. | ||
| 1057 | * | ||
| 1058 | * @param a the array to be searched | ||
| 1059 | * @param key the value to be searched for | ||
| 1060 | * @return index of the search key, if it is contained in the array; | ||
| 1061 | * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The | ||
| 1062 | * <i>insertion point</i> is defined as the point at which the | ||
| 1063 | * key would be inserted into the array: the index of the first | ||
| 1064 | * element greater than the key, or <tt>a.length</tt> if all | ||
| 1065 | * elements in the array are less than the specified key. Note | ||
| 1066 | * that this guarantees that the return value will be >= 0 if | ||
| 1067 | * and only if the key is found. | ||
| 1068 | */ | ||
| 1069 | public static int binarySearch(char[] a, char key) { | ||
| 1070 | return binarySearch0(a, 0, a.length, key); | ||
| 1071 | } | ||
| 1072 | |||
| 1073 | /** | ||
| 1074 | * Searches a range of | ||
| 1075 | * the specified array of chars for the specified value using the | ||
| 1076 | * binary search algorithm. | ||
| 1077 | * The range must be sorted (as | ||
| 1078 | * by the {@link #sort(char[], int, int)} method) | ||
| 1079 | * prior to making this call. If it | ||
| 1080 | * is not sorted, the results are undefined. If the range contains | ||
| 1081 | * multiple elements with the specified value, there is no guarantee which | ||
| 1082 | * one will be found. | ||
| 1083 | * | ||
| 1084 | * @param a the array to be searched | ||
| 1085 | * @param fromIndex the index of the first element (inclusive) to be | ||
| 1086 | * searched | ||
| 1087 | * @param toIndex the index of the last element (exclusive) to be searched | ||
| 1088 | * @param key the value to be searched for | ||
| 1089 | * @return index of the search key, if it is contained in the array | ||
| 1090 | * within the specified range; | ||
| 1091 | * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The | ||
| 1092 | * <i>insertion point</i> is defined as the point at which the | ||
| 1093 | * key would be inserted into the array: the index of the first | ||
| 1094 | * element in the range greater than the key, | ||
| 1095 | * or <tt>toIndex</tt> if all | ||
| 1096 | * elements in the range are less than the specified key. Note | ||
| 1097 | * that this guarantees that the return value will be >= 0 if | ||
| 1098 | * and only if the key is found. | ||
| 1099 | * @throws IllegalArgumentException | ||
| 1100 | * if {@code fromIndex > toIndex} | ||
| 1101 | * @throws ArrayIndexOutOfBoundsException | ||
| 1102 | * if {@code fromIndex < 0 or toIndex > a.length} | ||
| 1103 | * @since 1.6 | ||
| 1104 | */ | ||
| 1105 | public static int binarySearch(char[] a, int fromIndex, int toIndex, | ||
| 1106 | char key) { | ||
| 1107 | rangeCheck(a.length, fromIndex, toIndex); | ||
| 1108 | return binarySearch0(a, fromIndex, toIndex, key); | ||
| 1109 | } | ||
| 1110 | |||
| 1111 | // Like public version, but without range checks. | ||
| 1112 | private static int binarySearch0(char[] a, int fromIndex, int toIndex, | ||
| 1113 | char key) { | ||
| 1114 | int low = fromIndex; | ||
| 1115 | int high = toIndex - 1; | ||
| 1116 | |||
| 1117 | while (low <= high) { | ||
| 1118 | int mid = (low + high) >>> 1; | ||
| 1119 | char midVal = a[mid]; | ||
| 1120 | |||
| 1121 | if (midVal < key) | ||
| 1122 | low = mid + 1; | ||
| 1123 | else if (midVal > key) | ||
| 1124 | high = mid - 1; | ||
| 1125 | else | ||
| 1126 | return mid; // key found | ||
| 1127 | } | ||
| 1128 | return -(low + 1); // key not found. | ||
| 1129 | } | ||
| 1130 | |||
| 1131 | /** | ||
| 1132 | * Searches the specified array of bytes for the specified value using the | ||
| 1133 | * binary search algorithm. The array must be sorted (as | ||
| 1134 | * by the {@link #sort(byte[])} method) prior to making this call. If it | ||
| 1135 | * is not sorted, the results are undefined. If the array contains | ||
| 1136 | * multiple elements with the specified value, there is no guarantee which | ||
| 1137 | * one will be found. | ||
| 1138 | * | ||
| 1139 | * @param a the array to be searched | ||
| 1140 | * @param key the value to be searched for | ||
| 1141 | * @return index of the search key, if it is contained in the array; | ||
| 1142 | * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The | ||
| 1143 | * <i>insertion point</i> is defined as the point at which the | ||
| 1144 | * key would be inserted into the array: the index of the first | ||
| 1145 | * element greater than the key, or <tt>a.length</tt> if all | ||
| 1146 | * elements in the array are less than the specified key. Note | ||
| 1147 | * that this guarantees that the return value will be >= 0 if | ||
| 1148 | * and only if the key is found. | ||
| 1149 | */ | ||
| 1150 | public static int binarySearch(byte[] a, byte key) { | ||
| 1151 | return binarySearch0(a, 0, a.length, key); | ||
| 1152 | } | ||
| 1153 | |||
| 1154 | /** | ||
| 1155 | * Searches a range of | ||
| 1156 | * the specified array of bytes for the specified value using the | ||
| 1157 | * binary search algorithm. | ||
| 1158 | * The range must be sorted (as | ||
| 1159 | * by the {@link #sort(byte[], int, int)} method) | ||
| 1160 | * prior to making this call. If it | ||
| 1161 | * is not sorted, the results are undefined. If the range contains | ||
| 1162 | * multiple elements with the specified value, there is no guarantee which | ||
| 1163 | * one will be found. | ||
| 1164 | * | ||
| 1165 | * @param a the array to be searched | ||
| 1166 | * @param fromIndex the index of the first element (inclusive) to be | ||
| 1167 | * searched | ||
| 1168 | * @param toIndex the index of the last element (exclusive) to be searched | ||
| 1169 | * @param key the value to be searched for | ||
| 1170 | * @return index of the search key, if it is contained in the array | ||
| 1171 | * within the specified range; | ||
| 1172 | * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The | ||
| 1173 | * <i>insertion point</i> is defined as the point at which the | ||
| 1174 | * key would be inserted into the array: the index of the first | ||
| 1175 | * element in the range greater than the key, | ||
| 1176 | * or <tt>toIndex</tt> if all | ||
| 1177 | * elements in the range are less than the specified key. Note | ||
| 1178 | * that this guarantees that the return value will be >= 0 if | ||
| 1179 | * and only if the key is found. | ||
| 1180 | * @throws IllegalArgumentException | ||
| 1181 | * if {@code fromIndex > toIndex} | ||
| 1182 | * @throws ArrayIndexOutOfBoundsException | ||
| 1183 | * if {@code fromIndex < 0 or toIndex > a.length} | ||
| 1184 | * @since 1.6 | ||
| 1185 | */ | ||
| 1186 | public static int binarySearch(byte[] a, int fromIndex, int toIndex, | ||
| 1187 | byte key) { | ||
| 1188 | rangeCheck(a.length, fromIndex, toIndex); | ||
| 1189 | return binarySearch0(a, fromIndex, toIndex, key); | ||
| 1190 | } | ||
| 1191 | |||
| 1192 | // Like public version, but without range checks. | ||
| 1193 | private static int binarySearch0(byte[] a, int fromIndex, int toIndex, | ||
| 1194 | byte key) { | ||
| 1195 | int low = fromIndex; | ||
| 1196 | int high = toIndex - 1; | ||
| 1197 | |||
| 1198 | while (low <= high) { | ||
| 1199 | int mid = (low + high) >>> 1; | ||
| 1200 | byte midVal = a[mid]; | ||
| 1201 | |||
| 1202 | if (midVal < key) | ||
| 1203 | low = mid + 1; | ||
| 1204 | else if (midVal > key) | ||
| 1205 | high = mid - 1; | ||
| 1206 | else | ||
| 1207 | return mid; // key found | ||
| 1208 | } | ||
| 1209 | return -(low + 1); // key not found. | ||
| 1210 | } | ||
| 1211 | |||
| 1212 | /** | ||
| 1213 | * Searches the specified array of doubles for the specified value using | ||
| 1214 | * the binary search algorithm. The array must be sorted | ||
| 1215 | * (as by the {@link #sort(double[])} method) prior to making this call. | ||
| 1216 | * If it is not sorted, the results are undefined. If the array contains | ||
| 1217 | * multiple elements with the specified value, there is no guarantee which | ||
| 1218 | * one will be found. This method considers all NaN values to be | ||
| 1219 | * equivalent and equal. | ||
| 1220 | * | ||
| 1221 | * @param a the array to be searched | ||
| 1222 | * @param key the value to be searched for | ||
| 1223 | * @return index of the search key, if it is contained in the array; | ||
| 1224 | * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The | ||
| 1225 | * <i>insertion point</i> is defined as the point at which the | ||
| 1226 | * key would be inserted into the array: the index of the first | ||
| 1227 | * element greater than the key, or <tt>a.length</tt> if all | ||
| 1228 | * elements in the array are less than the specified key. Note | ||
| 1229 | * that this guarantees that the return value will be >= 0 if | ||
| 1230 | * and only if the key is found. | ||
| 1231 | */ | ||
| 1232 | public static int binarySearch(double[] a, double key) { | ||
| 1233 | return binarySearch0(a, 0, a.length, key); | ||
| 1234 | } | ||
| 1235 | |||
| 1236 | /** | ||
| 1237 | * Searches a range of | ||
| 1238 | * the specified array of doubles for the specified value using | ||
| 1239 | * the binary search algorithm. | ||
| 1240 | * The range must be sorted | ||
| 1241 | * (as by the {@link #sort(double[], int, int)} method) | ||
| 1242 | * prior to making this call. | ||
| 1243 | * If it is not sorted, the results are undefined. If the range contains | ||
| 1244 | * multiple elements with the specified value, there is no guarantee which | ||
| 1245 | * one will be found. This method considers all NaN values to be | ||
| 1246 | * equivalent and equal. | ||
| 1247 | * | ||
| 1248 | * @param a the array to be searched | ||
| 1249 | * @param fromIndex the index of the first element (inclusive) to be | ||
| 1250 | * searched | ||
| 1251 | * @param toIndex the index of the last element (exclusive) to be searched | ||
| 1252 | * @param key the value to be searched for | ||
| 1253 | * @return index of the search key, if it is contained in the array | ||
| 1254 | * within the specified range; | ||
| 1255 | * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The | ||
| 1256 | * <i>insertion point</i> is defined as the point at which the | ||
| 1257 | * key would be inserted into the array: the index of the first | ||
| 1258 | * element in the range greater than the key, | ||
| 1259 | * or <tt>toIndex</tt> if all | ||
| 1260 | * elements in the range are less than the specified key. Note | ||
| 1261 | * that this guarantees that the return value will be >= 0 if | ||
| 1262 | * and only if the key is found. | ||
| 1263 | * @throws IllegalArgumentException | ||
| 1264 | * if {@code fromIndex > toIndex} | ||
| 1265 | * @throws ArrayIndexOutOfBoundsException | ||
| 1266 | * if {@code fromIndex < 0 or toIndex > a.length} | ||
| 1267 | * @since 1.6 | ||
| 1268 | */ | ||
| 1269 | public static int binarySearch(double[] a, int fromIndex, int toIndex, | ||
| 1270 | double key) { | ||
| 1271 | rangeCheck(a.length, fromIndex, toIndex); | ||
| 1272 | return binarySearch0(a, fromIndex, toIndex, key); | ||
| 1273 | } | ||
| 1274 | |||
| 1275 | // Like public version, but without range checks. | ||
| 1276 | private static int binarySearch0(double[] a, int fromIndex, int toIndex, | ||
| 1277 | double key) { | ||
| 1278 | int low = fromIndex; | ||
| 1279 | int high = toIndex - 1; | ||
| 1280 | |||
| 1281 | while (low <= high) { | ||
| 1282 | int mid = (low + high) >>> 1; | ||
| 1283 | double midVal = a[mid]; | ||
| 1284 | |||
| 1285 | if (midVal < key) | ||
| 1286 | low = mid + 1; // Neither val is NaN, thisVal is smaller | ||
| 1287 | else if (midVal > key) | ||
| 1288 | high = mid - 1; // Neither val is NaN, thisVal is larger | ||
| 1289 | else { | ||
| 1290 | long midBits = Double.doubleToLongBits(midVal); | ||
| 1291 | long keyBits = Double.doubleToLongBits(key); | ||
| 1292 | if (midBits == keyBits) // Values are equal | ||
| 1293 | return mid; // Key found | ||
| 1294 | else if (midBits < keyBits) // (-0.0, 0.0) or (!NaN, NaN) | ||
| 1295 | low = mid + 1; | ||
| 1296 | else // (0.0, -0.0) or (NaN, !NaN) | ||
| 1297 | high = mid - 1; | ||
| 1298 | } | ||
| 1299 | } | ||
| 1300 | return -(low + 1); // key not found. | ||
| 1301 | } | ||
| 1302 | |||
| 1303 | /** | ||
| 1304 | * Searches the specified array of floats for the specified value using | ||
| 1305 | * the binary search algorithm. The array must be sorted | ||
| 1306 | * (as by the {@link #sort(float[])} method) prior to making this call. If | ||
| 1307 | * it is not sorted, the results are undefined. If the array contains | ||
| 1308 | * multiple elements with the specified value, there is no guarantee which | ||
| 1309 | * one will be found. This method considers all NaN values to be | ||
| 1310 | * equivalent and equal. | ||
| 1311 | * | ||
| 1312 | * @param a the array to be searched | ||
| 1313 | * @param key the value to be searched for | ||
| 1314 | * @return index of the search key, if it is contained in the array; | ||
| 1315 | * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The | ||
| 1316 | * <i>insertion point</i> is defined as the point at which the | ||
| 1317 | * key would be inserted into the array: the index of the first | ||
| 1318 | * element greater than the key, or <tt>a.length</tt> if all | ||
| 1319 | * elements in the array are less than the specified key. Note | ||
| 1320 | * that this guarantees that the return value will be >= 0 if | ||
| 1321 | * and only if the key is found. | ||
| 1322 | */ | ||
| 1323 | public static int binarySearch(float[] a, float key) { | ||
| 1324 | return binarySearch0(a, 0, a.length, key); | ||
| 1325 | } | ||
| 1326 | |||
| 1327 | /** | ||
| 1328 | * Searches a range of | ||
| 1329 | * the specified array of floats for the specified value using | ||
| 1330 | * the binary search algorithm. | ||
| 1331 | * The range must be sorted | ||
| 1332 | * (as by the {@link #sort(float[], int, int)} method) | ||
| 1333 | * prior to making this call. If | ||
| 1334 | * it is not sorted, the results are undefined. If the range contains | ||
| 1335 | * multiple elements with the specified value, there is no guarantee which | ||
| 1336 | * one will be found. This method considers all NaN values to be | ||
| 1337 | * equivalent and equal. | ||
| 1338 | * | ||
| 1339 | * @param a the array to be searched | ||
| 1340 | * @param fromIndex the index of the first element (inclusive) to be | ||
| 1341 | * searched | ||
| 1342 | * @param toIndex the index of the last element (exclusive) to be searched | ||
| 1343 | * @param key the value to be searched for | ||
| 1344 | * @return index of the search key, if it is contained in the array | ||
| 1345 | * within the specified range; | ||
| 1346 | * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The | ||
| 1347 | * <i>insertion point</i> is defined as the point at which the | ||
| 1348 | * key would be inserted into the array: the index of the first | ||
| 1349 | * element in the range greater than the key, | ||
| 1350 | * or <tt>toIndex</tt> if all | ||
| 1351 | * elements in the range are less than the specified key. Note | ||
| 1352 | * that this guarantees that the return value will be >= 0 if | ||
| 1353 | * and only if the key is found. | ||
| 1354 | * @throws IllegalArgumentException | ||
| 1355 | * if {@code fromIndex > toIndex} | ||
| 1356 | * @throws ArrayIndexOutOfBoundsException | ||
| 1357 | * if {@code fromIndex < 0 or toIndex > a.length} | ||
| 1358 | * @since 1.6 | ||
| 1359 | */ | ||
| 1360 | public static int binarySearch(float[] a, int fromIndex, int toIndex, | ||
| 1361 | float key) { | ||
| 1362 | rangeCheck(a.length, fromIndex, toIndex); | ||
| 1363 | return binarySearch0(a, fromIndex, toIndex, key); | ||
| 1364 | } | ||
| 1365 | |||
| 1366 | // Like public version, but without range checks. | ||
| 1367 | private static int binarySearch0(float[] a, int fromIndex, int toIndex, | ||
| 1368 | float key) { | ||
| 1369 | int low = fromIndex; | ||
| 1370 | int high = toIndex - 1; | ||
| 1371 | |||
| 1372 | while (low <= high) { | ||
| 1373 | int mid = (low + high) >>> 1; | ||
| 1374 | float midVal = a[mid]; | ||
| 1375 | |||
| 1376 | if (midVal < key) | ||
| 1377 | low = mid + 1; // Neither val is NaN, thisVal is smaller | ||
| 1378 | else if (midVal > key) | ||
| 1379 | high = mid - 1; // Neither val is NaN, thisVal is larger | ||
| 1380 | else { | ||
| 1381 | int midBits = Float.floatToIntBits(midVal); | ||
| 1382 | int keyBits = Float.floatToIntBits(key); | ||
| 1383 | if (midBits == keyBits) // Values are equal | ||
| 1384 | return mid; // Key found | ||
| 1385 | else if (midBits < keyBits) // (-0.0, 0.0) or (!NaN, NaN) | ||
| 1386 | low = mid + 1; | ||
| 1387 | else // (0.0, -0.0) or (NaN, !NaN) | ||
| 1388 | high = mid - 1; | ||
| 1389 | } | ||
| 1390 | } | ||
| 1391 | return -(low + 1); // key not found. | ||
| 1392 | } | ||
| 1393 | |||
| 1394 | /** | ||
| 1395 | * Searches the specified array for the specified object using the binary | ||
| 1396 | * search algorithm. The array must be sorted into ascending order | ||
| 1397 | * according to the | ||
| 1398 | * {@linkplain Comparable natural ordering} | ||
| 1399 | * of its elements (as by the | ||
| 1400 | * {@link #sort(Object[])} method) prior to making this call. | ||
| 1401 | * If it is not sorted, the results are undefined. | ||
| 1402 | * (If the array contains elements that are not mutually comparable (for | ||
| 1403 | * example, strings and integers), it <i>cannot</i> be sorted according | ||
| 1404 | * to the natural ordering of its elements, hence results are undefined.) | ||
| 1405 | * If the array contains multiple | ||
| 1406 | * elements equal to the specified object, there is no guarantee which | ||
| 1407 | * one will be found. | ||
| 1408 | * | ||
| 1409 | * @param a the array to be searched | ||
| 1410 | * @param key the value to be searched for | ||
| 1411 | * @return index of the search key, if it is contained in the array; | ||
| 1412 | * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The | ||
| 1413 | * <i>insertion point</i> is defined as the point at which the | ||
| 1414 | * key would be inserted into the array: the index of the first | ||
| 1415 | * element greater than the key, or <tt>a.length</tt> if all | ||
| 1416 | * elements in the array are less than the specified key. Note | ||
| 1417 | * that this guarantees that the return value will be >= 0 if | ||
| 1418 | * and only if the key is found. | ||
| 1419 | * @throws ClassCastException if the search key is not comparable to the | ||
| 1420 | * elements of the array. | ||
| 1421 | */ | ||
| 1422 | public static int binarySearch(Object[] a, Object key) { | ||
| 1423 | return binarySearch0(a, 0, a.length, key); | ||
| 1424 | } | ||
| 1425 | |||
| 1426 | /** | ||
| 1427 | * Searches a range of | ||
| 1428 | * the specified array for the specified object using the binary | ||
| 1429 | * search algorithm. | ||
| 1430 | * The range must be sorted into ascending order | ||
| 1431 | * according to the | ||
| 1432 | * {@linkplain Comparable natural ordering} | ||
| 1433 | * of its elements (as by the | ||
| 1434 | * {@link #sort(Object[], int, int)} method) prior to making this | ||
| 1435 | * call. If it is not sorted, the results are undefined. | ||
| 1436 | * (If the range contains elements that are not mutually comparable (for | ||
| 1437 | * example, strings and integers), it <i>cannot</i> be sorted according | ||
| 1438 | * to the natural ordering of its elements, hence results are undefined.) | ||
| 1439 | * If the range contains multiple | ||
| 1440 | * elements equal to the specified object, there is no guarantee which | ||
| 1441 | * one will be found. | ||
| 1442 | * | ||
| 1443 | * @param a the array to be searched | ||
| 1444 | * @param fromIndex the index of the first element (inclusive) to be | ||
| 1445 | * searched | ||
| 1446 | * @param toIndex the index of the last element (exclusive) to be searched | ||
| 1447 | * @param key the value to be searched for | ||
| 1448 | * @return index of the search key, if it is contained in the array | ||
| 1449 | * within the specified range; | ||
| 1450 | * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The | ||
| 1451 | * <i>insertion point</i> is defined as the point at which the | ||
| 1452 | * key would be inserted into the array: the index of the first | ||
| 1453 | * element in the range greater than the key, | ||
| 1454 | * or <tt>toIndex</tt> if all | ||
| 1455 | * elements in the range are less than the specified key. Note | ||
| 1456 | * that this guarantees that the return value will be >= 0 if | ||
| 1457 | * and only if the key is found. | ||
| 1458 | * @throws ClassCastException if the search key is not comparable to the | ||
| 1459 | * elements of the array within the specified range. | ||
| 1460 | * @throws IllegalArgumentException | ||
| 1461 | * if {@code fromIndex > toIndex} | ||
| 1462 | * @throws ArrayIndexOutOfBoundsException | ||
| 1463 | * if {@code fromIndex < 0 or toIndex > a.length} | ||
| 1464 | * @since 1.6 | ||
| 1465 | */ | ||
| 1466 | public static int binarySearch(Object[] a, int fromIndex, int toIndex, | ||
| 1467 | Object key) { | ||
| 1468 | rangeCheck(a.length, fromIndex, toIndex); | ||
| 1469 | return binarySearch0(a, fromIndex, toIndex, key); | ||
| 1470 | } | ||
| 1471 | |||
| 1472 | // Like public version, but without range checks. | ||
| 1473 | private static int binarySearch0(Object[] a, int fromIndex, int toIndex, | ||
| 1474 | Object key) { | ||
| 1475 | int low = fromIndex; | ||
| 1476 | int high = toIndex - 1; | ||
| 1477 | |||
| 1478 | while (low <= high) { | ||
| 1479 | int mid = (low + high) >>> 1; | ||
| 1480 | Comparable midVal = (Comparable)a[mid]; | ||
| 1481 | int cmp = midVal.compareTo(key); | ||
| 1482 | |||
| 1483 | if (cmp < 0) | ||
| 1484 | low = mid + 1; | ||
| 1485 | else if (cmp > 0) | ||
| 1486 | high = mid - 1; | ||
| 1487 | else | ||
| 1488 | return mid; // key found | ||
| 1489 | } | ||
| 1490 | return -(low + 1); // key not found. | ||
| 1491 | } | ||
| 1492 | |||
| 1493 | /** | ||
| 1494 | * Searches the specified array for the specified object using the binary | ||
| 1495 | * search algorithm. The array must be sorted into ascending order | ||
| 1496 | * according to the specified comparator (as by the | ||
| 1497 | * {@link #sort(Object[], Comparator) sort(T[], Comparator)} | ||
| 1498 | * method) prior to making this call. If it is | ||
| 1499 | * not sorted, the results are undefined. | ||
| 1500 | * If the array contains multiple | ||
| 1501 | * elements equal to the specified object, there is no guarantee which one | ||
| 1502 | * will be found. | ||
| 1503 | * | ||
| 1504 | * @param a the array to be searched | ||
| 1505 | * @param key the value to be searched for | ||
| 1506 | * @param c the comparator by which the array is ordered. A | ||
| 1507 | * <tt>null</tt> value indicates that the elements' | ||
| 1508 | * {@linkplain Comparable natural ordering} should be used. | ||
| 1509 | * @return index of the search key, if it is contained in the array; | ||
| 1510 | * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The | ||
| 1511 | * <i>insertion point</i> is defined as the point at which the | ||
| 1512 | * key would be inserted into the array: the index of the first | ||
| 1513 | * element greater than the key, or <tt>a.length</tt> if all | ||
| 1514 | * elements in the array are less than the specified key. Note | ||
| 1515 | * that this guarantees that the return value will be >= 0 if | ||
| 1516 | * and only if the key is found. | ||
| 1517 | * @throws ClassCastException if the array contains elements that are not | ||
| 1518 | * <i>mutually comparable</i> using the specified comparator, | ||
| 1519 | * or the search key is not comparable to the | ||
| 1520 | * elements of the array using this comparator. | ||
| 1521 | */ | ||
| 1522 | public static <T> int binarySearch(T[] a, T key, Comparator<? super T> c) { | ||
| 1523 | return binarySearch0(a, 0, a.length, key, c); | ||
| 1524 | } | ||
| 1525 | |||
| 1526 | /** | ||
| 1527 | * Searches a range of | ||
| 1528 | * the specified array for the specified object using the binary | ||
| 1529 | * search algorithm. | ||
| 1530 | * The range must be sorted into ascending order | ||
| 1531 | * according to the specified comparator (as by the | ||
| 1532 | * {@link #sort(Object[], int, int, Comparator) | ||
| 1533 | * sort(T[], int, int, Comparator)} | ||
| 1534 | * method) prior to making this call. | ||
| 1535 | * If it is not sorted, the results are undefined. | ||
| 1536 | * If the range contains multiple elements equal to the specified object, | ||
| 1537 | * there is no guarantee which one will be found. | ||
| 1538 | * | ||
| 1539 | * @param a the array to be searched | ||
| 1540 | * @param fromIndex the index of the first element (inclusive) to be | ||
| 1541 | * searched | ||
| 1542 | * @param toIndex the index of the last element (exclusive) to be searched | ||
| 1543 | * @param key the value to be searched for | ||
| 1544 | * @param c the comparator by which the array is ordered. A | ||
| 1545 | * <tt>null</tt> value indicates that the elements' | ||
| 1546 | * {@linkplain Comparable natural ordering} should be used. | ||
| 1547 | * @return index of the search key, if it is contained in the array | ||
| 1548 | * within the specified range; | ||
| 1549 | * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The | ||
| 1550 | * <i>insertion point</i> is defined as the point at which the | ||
| 1551 | * key would be inserted into the array: the index of the first | ||
| 1552 | * element in the range greater than the key, | ||
| 1553 | * or <tt>toIndex</tt> if all | ||
| 1554 | * elements in the range are less than the specified key. Note | ||
| 1555 | * that this guarantees that the return value will be >= 0 if | ||
| 1556 | * and only if the key is found. | ||
| 1557 | * @throws ClassCastException if the range contains elements that are not | ||
| 1558 | * <i>mutually comparable</i> using the specified comparator, | ||
| 1559 | * or the search key is not comparable to the | ||
| 1560 | * elements in the range using this comparator. | ||
| 1561 | * @throws IllegalArgumentException | ||
| 1562 | * if {@code fromIndex > toIndex} | ||
| 1563 | * @throws ArrayIndexOutOfBoundsException | ||
| 1564 | * if {@code fromIndex < 0 or toIndex > a.length} | ||
| 1565 | * @since 1.6 | ||
| 1566 | */ | ||
| 1567 | public static <T> int binarySearch(T[] a, int fromIndex, int toIndex, | ||
| 1568 | T key, Comparator<? super T> c) { | ||
| 1569 | rangeCheck(a.length, fromIndex, toIndex); | ||
| 1570 | return binarySearch0(a, fromIndex, toIndex, key, c); | ||
| 1571 | } | ||
| 1572 | |||
| 1573 | // Like public version, but without range checks. | ||
| 1574 | private static <T> int binarySearch0(T[] a, int fromIndex, int toIndex, | ||
| 1575 | T key, Comparator<? super T> c) { | ||
| 1576 | if (c == null) { | ||
| 1577 | return binarySearch0(a, fromIndex, toIndex, key); | ||
| 1578 | } | ||
| 1579 | int low = fromIndex; | ||
| 1580 | int high = toIndex - 1; | ||
| 1581 | |||
| 1582 | while (low <= high) { | ||
| 1583 | int mid = (low + high) >>> 1; | ||
| 1584 | T midVal = a[mid]; | ||
| 1585 | int cmp = c.compare(midVal, key); | ||
| 1586 | if (cmp < 0) | ||
| 1587 | low = mid + 1; | ||
| 1588 | else if (cmp > 0) | ||
| 1589 | high = mid - 1; | ||
| 1590 | else | ||
| 1591 | return mid; // key found | ||
| 1592 | } | ||
| 1593 | return -(low + 1); // key not found. | ||
| 1594 | } | ||
| 1595 | |||
| 1596 | // Equality Testing | ||
| 1597 | |||
| 1598 | /** | ||
| 1599 | * Returns <tt>true</tt> if the two specified arrays of longs are | ||
| 1600 | * <i>equal</i> to one another. Two arrays are considered equal if both | ||
| 1601 | * arrays contain the same number of elements, and all corresponding pairs | ||
| 1602 | * of elements in the two arrays are equal. In other words, two arrays | ||
| 1603 | * are equal if they contain the same elements in the same order. Also, | ||
| 1604 | * two array references are considered equal if both are <tt>null</tt>.<p> | ||
| 1605 | * | ||
| 1606 | * @param a one array to be tested for equality | ||
| 1607 | * @param a2 the other array to be tested for equality | ||
| 1608 | * @return <tt>true</tt> if the two arrays are equal | ||
| 1609 | */ | ||
| 1610 | public static boolean equals(long[] a, long[] a2) { | ||
| 1611 | if (a==a2) | ||
| 1612 | return true; | ||
| 1613 | if (a==null || a2==null) | ||
| 1614 | return false; | ||
| 1615 | |||
| 1616 | int length = a.length; | ||
| 1617 | if (a2.length != length) | ||
| 1618 | return false; | ||
| 1619 | |||
| 1620 | for (int i=0; i<length; i++) | ||
| 1621 | if (a[i] != a2[i]) | ||
| 1622 | return false; | ||
| 1623 | |||
| 1624 | return true; | ||
| 1625 | } | ||
| 1626 | |||
| 1627 | /** | ||
| 1628 | * Returns <tt>true</tt> if the two specified arrays of ints are | ||
| 1629 | * <i>equal</i> to one another. Two arrays are considered equal if both | ||
| 1630 | * arrays contain the same number of elements, and all corresponding pairs | ||
| 1631 | * of elements in the two arrays are equal. In other words, two arrays | ||
| 1632 | * are equal if they contain the same elements in the same order. Also, | ||
| 1633 | * two array references are considered equal if both are <tt>null</tt>.<p> | ||
| 1634 | * | ||
| 1635 | * @param a one array to be tested for equality | ||
| 1636 | * @param a2 the other array to be tested for equality | ||
| 1637 | * @return <tt>true</tt> if the two arrays are equal | ||
| 1638 | */ | ||
| 1639 | public static boolean equals(int[] a, int[] a2) { | ||
| 1640 | if (a==a2) | ||
| 1641 | return true; | ||
| 1642 | if (a==null || a2==null) | ||
| 1643 | return false; | ||
| 1644 | |||
| 1645 | int length = a.length; | ||
| 1646 | if (a2.length != length) | ||
| 1647 | return false; | ||
| 1648 | |||
| 1649 | for (int i=0; i<length; i++) | ||
| 1650 | if (a[i] != a2[i]) | ||
| 1651 | return false; | ||
| 1652 | |||
| 1653 | return true; | ||
| 1654 | } | ||
| 1655 | |||
| 1656 | /** | ||
| 1657 | * Returns <tt>true</tt> if the two specified arrays of shorts are | ||
| 1658 | * <i>equal</i> to one another. Two arrays are considered equal if both | ||
| 1659 | * arrays contain the same number of elements, and all corresponding pairs | ||
| 1660 | * of elements in the two arrays are equal. In other words, two arrays | ||
| 1661 | * are equal if they contain the same elements in the same order. Also, | ||
| 1662 | * two array references are considered equal if both are <tt>null</tt>.<p> | ||
| 1663 | * | ||
| 1664 | * @param a one array to be tested for equality | ||
| 1665 | * @param a2 the other array to be tested for equality | ||
| 1666 | * @return <tt>true</tt> if the two arrays are equal | ||
| 1667 | */ | ||
| 1668 | public static boolean equals(short[] a, short a2[]) { | ||
| 1669 | if (a==a2) | ||
| 1670 | return true; | ||
| 1671 | if (a==null || a2==null) | ||
| 1672 | return false; | ||
| 1673 | |||
| 1674 | int length = a.length; | ||
| 1675 | if (a2.length != length) | ||
| 1676 | return false; | ||
| 1677 | |||
| 1678 | for (int i=0; i<length; i++) | ||
| 1679 | if (a[i] != a2[i]) | ||
| 1680 | return false; | ||
| 1681 | |||
| 1682 | return true; | ||
| 1683 | } | ||
| 1684 | |||
| 1685 | /** | ||
| 1686 | * Returns <tt>true</tt> if the two specified arrays of chars are | ||
| 1687 | * <i>equal</i> to one another. Two arrays are considered equal if both | ||
| 1688 | * arrays contain the same number of elements, and all corresponding pairs | ||
| 1689 | * of elements in the two arrays are equal. In other words, two arrays | ||
| 1690 | * are equal if they contain the same elements in the same order. Also, | ||
| 1691 | * two array references are considered equal if both are <tt>null</tt>.<p> | ||
| 1692 | * | ||
| 1693 | * @param a one array to be tested for equality | ||
| 1694 | * @param a2 the other array to be tested for equality | ||
| 1695 | * @return <tt>true</tt> if the two arrays are equal | ||
| 1696 | */ | ||
| 1697 | public static boolean equals(char[] a, char[] a2) { | ||
| 1698 | if (a==a2) | ||
| 1699 | return true; | ||
| 1700 | if (a==null || a2==null) | ||
| 1701 | return false; | ||
| 1702 | |||
| 1703 | int length = a.length; | ||
| 1704 | if (a2.length != length) | ||
| 1705 | return false; | ||
| 1706 | |||
| 1707 | for (int i=0; i<length; i++) | ||
| 1708 | if (a[i] != a2[i]) | ||
| 1709 | return false; | ||
| 1710 | |||
| 1711 | return true; | ||
| 1712 | } | ||
| 1713 | |||
| 1714 | /** | ||
| 1715 | * Returns <tt>true</tt> if the two specified arrays of bytes are | ||
| 1716 | * <i>equal</i> to one another. Two arrays are considered equal if both | ||
| 1717 | * arrays contain the same number of elements, and all corresponding pairs | ||
| 1718 | * of elements in the two arrays are equal. In other words, two arrays | ||
| 1719 | * are equal if they contain the same elements in the same order. Also, | ||
| 1720 | * two array references are considered equal if both are <tt>null</tt>.<p> | ||
| 1721 | * | ||
| 1722 | * @param a one array to be tested for equality | ||
| 1723 | * @param a2 the other array to be tested for equality | ||
| 1724 | * @return <tt>true</tt> if the two arrays are equal | ||
| 1725 | */ | ||
| 1726 | public static boolean equals(byte[] a, byte[] a2) { | ||
| 1727 | if (a==a2) | ||
| 1728 | return true; | ||
| 1729 | if (a==null || a2==null) | ||
| 1730 | return false; | ||
| 1731 | |||
| 1732 | int length = a.length; | ||
| 1733 | if (a2.length != length) | ||
| 1734 | return false; | ||
| 1735 | |||
| 1736 | for (int i=0; i<length; i++) | ||
| 1737 | if (a[i] != a2[i]) | ||
| 1738 | return false; | ||
| 1739 | |||
| 1740 | return true; | ||
| 1741 | } | ||
| 1742 | |||
| 1743 | /** | ||
| 1744 | * Returns <tt>true</tt> if the two specified arrays of booleans are | ||
| 1745 | * <i>equal</i> to one another. Two arrays are considered equal if both | ||
| 1746 | * arrays contain the same number of elements, and all corresponding pairs | ||
| 1747 | * of elements in the two arrays are equal. In other words, two arrays | ||
| 1748 | * are equal if they contain the same elements in the same order. Also, | ||
| 1749 | * two array references are considered equal if both are <tt>null</tt>.<p> | ||
| 1750 | * | ||
| 1751 | * @param a one array to be tested for equality | ||
| 1752 | * @param a2 the other array to be tested for equality | ||
| 1753 | * @return <tt>true</tt> if the two arrays are equal | ||
| 1754 | */ | ||
| 1755 | public static boolean equals(boolean[] a, boolean[] a2) { | ||
| 1756 | if (a==a2) | ||
| 1757 | return true; | ||
| 1758 | if (a==null || a2==null) | ||
| 1759 | return false; | ||
| 1760 | |||
| 1761 | int length = a.length; | ||
| 1762 | if (a2.length != length) | ||
| 1763 | return false; | ||
| 1764 | |||
| 1765 | for (int i=0; i<length; i++) | ||
| 1766 | if (a[i] != a2[i]) | ||
| 1767 | return false; | ||
| 1768 | |||
| 1769 | return true; | ||
| 1770 | } | ||
| 1771 | |||
| 1772 | /** | ||
| 1773 | * Returns <tt>true</tt> if the two specified arrays of doubles are | ||
| 1774 | * <i>equal</i> to one another. Two arrays are considered equal if both | ||
| 1775 | * arrays contain the same number of elements, and all corresponding pairs | ||
| 1776 | * of elements in the two arrays are equal. In other words, two arrays | ||
| 1777 | * are equal if they contain the same elements in the same order. Also, | ||
| 1778 | * two array references are considered equal if both are <tt>null</tt>.<p> | ||
| 1779 | * | ||
| 1780 | * Two doubles <tt>d1</tt> and <tt>d2</tt> are considered equal if: | ||
| 1781 | * <pre> <tt>new Double(d1).equals(new Double(d2))</tt></pre> | ||
| 1782 | * (Unlike the <tt>==</tt> operator, this method considers | ||
| 1783 | * <tt>NaN</tt> equals to itself, and 0.0d unequal to -0.0d.) | ||
| 1784 | * | ||
| 1785 | * @param a one array to be tested for equality | ||
| 1786 | * @param a2 the other array to be tested for equality | ||
| 1787 | * @return <tt>true</tt> if the two arrays are equal | ||
| 1788 | * @see Double#equals(Object) | ||
| 1789 | */ | ||
| 1790 | public static boolean equals(double[] a, double[] a2) { | ||
| 1791 | if (a==a2) | ||
| 1792 | return true; | ||
| 1793 | if (a==null || a2==null) | ||
| 1794 | return false; | ||
| 1795 | |||
| 1796 | int length = a.length; | ||
| 1797 | if (a2.length != length) | ||
| 1798 | return false; | ||
| 1799 | |||
| 1800 | for (int i=0; i<length; i++) | ||
| 1801 | if (Double.doubleToLongBits(a[i])!=Double.doubleToLongBits(a2[i])) | ||
| 1802 | return false; | ||
| 1803 | |||
| 1804 | return true; | ||
| 1805 | } | ||
| 1806 | |||
| 1807 | /** | ||
| 1808 | * Returns <tt>true</tt> if the two specified arrays of floats are | ||
| 1809 | * <i>equal</i> to one another. Two arrays are considered equal if both | ||
| 1810 | * arrays contain the same number of elements, and all corresponding pairs | ||
| 1811 | * of elements in the two arrays are equal. In other words, two arrays | ||
| 1812 | * are equal if they contain the same elements in the same order. Also, | ||
| 1813 | * two array references are considered equal if both are <tt>null</tt>.<p> | ||
| 1814 | * | ||
| 1815 | * Two floats <tt>f1</tt> and <tt>f2</tt> are considered equal if: | ||
| 1816 | * <pre> <tt>new Float(f1).equals(new Float(f2))</tt></pre> | ||
| 1817 | * (Unlike the <tt>==</tt> operator, this method considers | ||
| 1818 | * <tt>NaN</tt> equals to itself, and 0.0f unequal to -0.0f.) | ||
| 1819 | * | ||
| 1820 | * @param a one array to be tested for equality | ||
| 1821 | * @param a2 the other array to be tested for equality | ||
| 1822 | * @return <tt>true</tt> if the two arrays are equal | ||
| 1823 | * @see Float#equals(Object) | ||
| 1824 | */ | ||
| 1825 | public static boolean equals(float[] a, float[] a2) { | ||
| 1826 | if (a==a2) | ||
| 1827 | return true; | ||
| 1828 | if (a==null || a2==null) | ||
| 1829 | return false; | ||
| 1830 | |||
| 1831 | int length = a.length; | ||
| 1832 | if (a2.length != length) | ||
| 1833 | return false; | ||
| 1834 | |||
| 1835 | for (int i=0; i<length; i++) | ||
| 1836 | if (Float.floatToIntBits(a[i])!=Float.floatToIntBits(a2[i])) | ||
| 1837 | return false; | ||
| 1838 | |||
| 1839 | return true; | ||
| 1840 | } | ||
| 1841 | |||
| 1842 | /** | ||
| 1843 | * Returns <tt>true</tt> if the two specified arrays of Objects are | ||
| 1844 | * <i>equal</i> to one another. The two arrays are considered equal if | ||
| 1845 | * both arrays contain the same number of elements, and all corresponding | ||
| 1846 | * pairs of elements in the two arrays are equal. Two objects <tt>e1</tt> | ||
| 1847 | * and <tt>e2</tt> are considered <i>equal</i> if <tt>(e1==null ? e2==null | ||
| 1848 | * : e1.equals(e2))</tt>. In other words, the two arrays are equal if | ||
| 1849 | * they contain the same elements in the same order. Also, two array | ||
| 1850 | * references are considered equal if both are <tt>null</tt>.<p> | ||
| 1851 | * | ||
| 1852 | * @param a one array to be tested for equality | ||
| 1853 | * @param a2 the other array to be tested for equality | ||
| 1854 | * @return <tt>true</tt> if the two arrays are equal | ||
| 1855 | */ | ||
| 1856 | public static boolean equals(Object[] a, Object[] a2) { | ||
| 1857 | if (a==a2) | ||
| 1858 | return true; | ||
| 1859 | if (a==null || a2==null) | ||
| 1860 | return false; | ||
| 1861 | |||
| 1862 | int length = a.length; | ||
| 1863 | if (a2.length != length) | ||
| 1864 | return false; | ||
| 1865 | |||
| 1866 | for (int i=0; i<length; i++) { | ||
| 1867 | Object o1 = a[i]; | ||
| 1868 | Object o2 = a2[i]; | ||
| 1869 | if (!(o1==null ? o2==null : o1.equals(o2))) | ||
| 1870 | return false; | ||
| 1871 | } | ||
| 1872 | |||
| 1873 | return true; | ||
| 1874 | } | ||
| 1875 | |||
| 1876 | // Filling | ||
| 1877 | |||
| 1878 | /** | ||
| 1879 | * Assigns the specified long value to each element of the specified array | ||
| 1880 | * of longs. | ||
| 1881 | * | ||
| 1882 | * @param a the array to be filled | ||
| 1883 | * @param val the value to be stored in all elements of the array | ||
| 1884 | */ | ||
| 1885 | public static void fill(long[] a, long val) { | ||
| 1886 | for (int i = 0, len = a.length; i < len; i++) | ||
| 1887 | a[i] = val; | ||
| 1888 | } | ||
| 1889 | |||
| 1890 | /** | ||
| 1891 | * Assigns the specified long value to each element of the specified | ||
| 1892 | * range of the specified array of longs. The range to be filled | ||
| 1893 | * extends from index <tt>fromIndex</tt>, inclusive, to index | ||
| 1894 | * <tt>toIndex</tt>, exclusive. (If <tt>fromIndex==toIndex</tt>, the | ||
| 1895 | * range to be filled is empty.) | ||
| 1896 | * | ||
| 1897 | * @param a the array to be filled | ||
| 1898 | * @param fromIndex the index of the first element (inclusive) to be | ||
| 1899 | * filled with the specified value | ||
| 1900 | * @param toIndex the index of the last element (exclusive) to be | ||
| 1901 | * filled with the specified value | ||
| 1902 | * @param val the value to be stored in all elements of the array | ||
| 1903 | * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt> | ||
| 1904 | * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or | ||
| 1905 | * <tt>toIndex > a.length</tt> | ||
| 1906 | */ | ||
| 1907 | public static void fill(long[] a, int fromIndex, int toIndex, long val) { | ||
| 1908 | rangeCheck(a.length, fromIndex, toIndex); | ||
| 1909 | for (int i = fromIndex; i < toIndex; i++) | ||
| 1910 | a[i] = val; | ||
| 1911 | } | ||
| 1912 | |||
| 1913 | /** | ||
| 1914 | * Assigns the specified int value to each element of the specified array | ||
| 1915 | * of ints. | ||
| 1916 | * | ||
| 1917 | * @param a the array to be filled | ||
| 1918 | * @param val the value to be stored in all elements of the array | ||
| 1919 | */ | ||
| 1920 | public static void fill(int[] a, int val) { | ||
| 1921 | for (int i = 0, len = a.length; i < len; i++) | ||
| 1922 | a[i] = val; | ||
| 1923 | } | ||
| 1924 | |||
| 1925 | /** | ||
| 1926 | * Assigns the specified int value to each element of the specified | ||
| 1927 | * range of the specified array of ints. The range to be filled | ||
| 1928 | * extends from index <tt>fromIndex</tt>, inclusive, to index | ||
| 1929 | * <tt>toIndex</tt>, exclusive. (If <tt>fromIndex==toIndex</tt>, the | ||
| 1930 | * range to be filled is empty.) | ||
| 1931 | * | ||
| 1932 | * @param a the array to be filled | ||
| 1933 | * @param fromIndex the index of the first element (inclusive) to be | ||
| 1934 | * filled with the specified value | ||
| 1935 | * @param toIndex the index of the last element (exclusive) to be | ||
| 1936 | * filled with the specified value | ||
| 1937 | * @param val the value to be stored in all elements of the array | ||
| 1938 | * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt> | ||
| 1939 | * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or | ||
| 1940 | * <tt>toIndex > a.length</tt> | ||
| 1941 | */ | ||
| 1942 | public static void fill(int[] a, int fromIndex, int toIndex, int val) { | ||
| 1943 | rangeCheck(a.length, fromIndex, toIndex); | ||
| 1944 | for (int i = fromIndex; i < toIndex; i++) | ||
| 1945 | a[i] = val; | ||
| 1946 | } | ||
| 1947 | |||
| 1948 | /** | ||
| 1949 | * Assigns the specified short value to each element of the specified array | ||
| 1950 | * of shorts. | ||
| 1951 | * | ||
| 1952 | * @param a the array to be filled | ||
| 1953 | * @param val the value to be stored in all elements of the array | ||
| 1954 | */ | ||
| 1955 | public static void fill(short[] a, short val) { | ||
| 1956 | for (int i = 0, len = a.length; i < len; i++) | ||
| 1957 | a[i] = val; | ||
| 1958 | } | ||
| 1959 | |||
| 1960 | /** | ||
| 1961 | * Assigns the specified short value to each element of the specified | ||
| 1962 | * range of the specified array of shorts. The range to be filled | ||
| 1963 | * extends from index <tt>fromIndex</tt>, inclusive, to index | ||
| 1964 | * <tt>toIndex</tt>, exclusive. (If <tt>fromIndex==toIndex</tt>, the | ||
| 1965 | * range to be filled is empty.) | ||
| 1966 | * | ||
| 1967 | * @param a the array to be filled | ||
| 1968 | * @param fromIndex the index of the first element (inclusive) to be | ||
| 1969 | * filled with the specified value | ||
| 1970 | * @param toIndex the index of the last element (exclusive) to be | ||
| 1971 | * filled with the specified value | ||
| 1972 | * @param val the value to be stored in all elements of the array | ||
| 1973 | * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt> | ||
| 1974 | * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or | ||
| 1975 | * <tt>toIndex > a.length</tt> | ||
| 1976 | */ | ||
| 1977 | public static void fill(short[] a, int fromIndex, int toIndex, short val) { | ||
| 1978 | rangeCheck(a.length, fromIndex, toIndex); | ||
| 1979 | for (int i = fromIndex; i < toIndex; i++) | ||
| 1980 | a[i] = val; | ||
| 1981 | } | ||
| 1982 | |||
| 1983 | /** | ||
| 1984 | * Assigns the specified char value to each element of the specified array | ||
| 1985 | * of chars. | ||
| 1986 | * | ||
| 1987 | * @param a the array to be filled | ||
| 1988 | * @param val the value to be stored in all elements of the array | ||
| 1989 | */ | ||
| 1990 | public static void fill(char[] a, char val) { | ||
| 1991 | for (int i = 0, len = a.length; i < len; i++) | ||
| 1992 | a[i] = val; | ||
| 1993 | } | ||
| 1994 | |||
| 1995 | /** | ||
| 1996 | * Assigns the specified char value to each element of the specified | ||
| 1997 | * range of the specified array of chars. The range to be filled | ||
| 1998 | * extends from index <tt>fromIndex</tt>, inclusive, to index | ||
| 1999 | * <tt>toIndex</tt>, exclusive. (If <tt>fromIndex==toIndex</tt>, the | ||
| 2000 | * range to be filled is empty.) | ||
| 2001 | * | ||
| 2002 | * @param a the array to be filled | ||
| 2003 | * @param fromIndex the index of the first element (inclusive) to be | ||
| 2004 | * filled with the specified value | ||
| 2005 | * @param toIndex the index of the last element (exclusive) to be | ||
| 2006 | * filled with the specified value | ||
| 2007 | * @param val the value to be stored in all elements of the array | ||
| 2008 | * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt> | ||
| 2009 | * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or | ||
| 2010 | * <tt>toIndex > a.length</tt> | ||
| 2011 | */ | ||
| 2012 | public static void fill(char[] a, int fromIndex, int toIndex, char val) { | ||
| 2013 | rangeCheck(a.length, fromIndex, toIndex); | ||
| 2014 | for (int i = fromIndex; i < toIndex; i++) | ||
| 2015 | a[i] = val; | ||
| 2016 | } | ||
| 2017 | |||
| 2018 | /** | ||
| 2019 | * Assigns the specified byte value to each element of the specified array | ||
| 2020 | * of bytes. | ||
| 2021 | * | ||
| 2022 | * @param a the array to be filled | ||
| 2023 | * @param val the value to be stored in all elements of the array | ||
| 2024 | */ | ||
| 2025 | public static void fill(byte[] a, byte val) { | ||
| 2026 | for (int i = 0, len = a.length; i < len; i++) | ||
| 2027 | a[i] = val; | ||
| 2028 | } | ||
| 2029 | |||
| 2030 | /** | ||
| 2031 | * Assigns the specified byte value to each element of the specified | ||
| 2032 | * range of the specified array of bytes. The range to be filled | ||
| 2033 | * extends from index <tt>fromIndex</tt>, inclusive, to index | ||
| 2034 | * <tt>toIndex</tt>, exclusive. (If <tt>fromIndex==toIndex</tt>, the | ||
| 2035 | * range to be filled is empty.) | ||
| 2036 | * | ||
| 2037 | * @param a the array to be filled | ||
| 2038 | * @param fromIndex the index of the first element (inclusive) to be | ||
| 2039 | * filled with the specified value | ||
| 2040 | * @param toIndex the index of the last element (exclusive) to be | ||
| 2041 | * filled with the specified value | ||
| 2042 | * @param val the value to be stored in all elements of the array | ||
| 2043 | * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt> | ||
| 2044 | * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or | ||
| 2045 | * <tt>toIndex > a.length</tt> | ||
| 2046 | */ | ||
| 2047 | public static void fill(byte[] a, int fromIndex, int toIndex, byte val) { | ||
| 2048 | rangeCheck(a.length, fromIndex, toIndex); | ||
| 2049 | for (int i = fromIndex; i < toIndex; i++) | ||
| 2050 | a[i] = val; | ||
| 2051 | } | ||
| 2052 | |||
| 2053 | /** | ||
| 2054 | * Assigns the specified boolean value to each element of the specified | ||
| 2055 | * array of booleans. | ||
| 2056 | * | ||
| 2057 | * @param a the array to be filled | ||
| 2058 | * @param val the value to be stored in all elements of the array | ||
| 2059 | */ | ||
| 2060 | public static void fill(boolean[] a, boolean val) { | ||
| 2061 | for (int i = 0, len = a.length; i < len; i++) | ||
| 2062 | a[i] = val; | ||
| 2063 | } | ||
| 2064 | |||
| 2065 | /** | ||
| 2066 | * Assigns the specified boolean value to each element of the specified | ||
| 2067 | * range of the specified array of booleans. The range to be filled | ||
| 2068 | * extends from index <tt>fromIndex</tt>, inclusive, to index | ||
| 2069 | * <tt>toIndex</tt>, exclusive. (If <tt>fromIndex==toIndex</tt>, the | ||
| 2070 | * range to be filled is empty.) | ||
| 2071 | * | ||
| 2072 | * @param a the array to be filled | ||
| 2073 | * @param fromIndex the index of the first element (inclusive) to be | ||
| 2074 | * filled with the specified value | ||
| 2075 | * @param toIndex the index of the last element (exclusive) to be | ||
| 2076 | * filled with the specified value | ||
| 2077 | * @param val the value to be stored in all elements of the array | ||
| 2078 | * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt> | ||
| 2079 | * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or | ||
| 2080 | * <tt>toIndex > a.length</tt> | ||
| 2081 | */ | ||
| 2082 | public static void fill(boolean[] a, int fromIndex, int toIndex, | ||
| 2083 | boolean val) { | ||
| 2084 | rangeCheck(a.length, fromIndex, toIndex); | ||
| 2085 | for (int i = fromIndex; i < toIndex; i++) | ||
| 2086 | a[i] = val; | ||
| 2087 | } | ||
| 2088 | |||
| 2089 | /** | ||
| 2090 | * Assigns the specified double value to each element of the specified | ||
| 2091 | * array of doubles. | ||
| 2092 | * | ||
| 2093 | * @param a the array to be filled | ||
| 2094 | * @param val the value to be stored in all elements of the array | ||
| 2095 | */ | ||
| 2096 | public static void fill(double[] a, double val) { | ||
| 2097 | for (int i = 0, len = a.length; i < len; i++) | ||
| 2098 | a[i] = val; | ||
| 2099 | } | ||
| 2100 | |||
| 2101 | /** | ||
| 2102 | * Assigns the specified double value to each element of the specified | ||
| 2103 | * range of the specified array of doubles. The range to be filled | ||
| 2104 | * extends from index <tt>fromIndex</tt>, inclusive, to index | ||
| 2105 | * <tt>toIndex</tt>, exclusive. (If <tt>fromIndex==toIndex</tt>, the | ||
| 2106 | * range to be filled is empty.) | ||
| 2107 | * | ||
| 2108 | * @param a the array to be filled | ||
| 2109 | * @param fromIndex the index of the first element (inclusive) to be | ||
| 2110 | * filled with the specified value | ||
| 2111 | * @param toIndex the index of the last element (exclusive) to be | ||
| 2112 | * filled with the specified value | ||
| 2113 | * @param val the value to be stored in all elements of the array | ||
| 2114 | * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt> | ||
| 2115 | * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or | ||
| 2116 | * <tt>toIndex > a.length</tt> | ||
| 2117 | */ | ||
| 2118 | public static void fill(double[] a, int fromIndex, int toIndex,double val){ | ||
| 2119 | rangeCheck(a.length, fromIndex, toIndex); | ||
| 2120 | for (int i = fromIndex; i < toIndex; i++) | ||
| 2121 | a[i] = val; | ||
| 2122 | } | ||
| 2123 | |||
| 2124 | /** | ||
| 2125 | * Assigns the specified float value to each element of the specified array | ||
| 2126 | * of floats. | ||
| 2127 | * | ||
| 2128 | * @param a the array to be filled | ||
| 2129 | * @param val the value to be stored in all elements of the array | ||
| 2130 | */ | ||
| 2131 | public static void fill(float[] a, float val) { | ||
| 2132 | for (int i = 0, len = a.length; i < len; i++) | ||
| 2133 | a[i] = val; | ||
| 2134 | } | ||
| 2135 | |||
| 2136 | /** | ||
| 2137 | * Assigns the specified float value to each element of the specified | ||
| 2138 | * range of the specified array of floats. The range to be filled | ||
| 2139 | * extends from index <tt>fromIndex</tt>, inclusive, to index | ||
| 2140 | * <tt>toIndex</tt>, exclusive. (If <tt>fromIndex==toIndex</tt>, the | ||
| 2141 | * range to be filled is empty.) | ||
| 2142 | * | ||
| 2143 | * @param a the array to be filled | ||
| 2144 | * @param fromIndex the index of the first element (inclusive) to be | ||
| 2145 | * filled with the specified value | ||
| 2146 | * @param toIndex the index of the last element (exclusive) to be | ||
| 2147 | * filled with the specified value | ||
| 2148 | * @param val the value to be stored in all elements of the array | ||
| 2149 | * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt> | ||
| 2150 | * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or | ||
| 2151 | * <tt>toIndex > a.length</tt> | ||
| 2152 | */ | ||
| 2153 | public static void fill(float[] a, int fromIndex, int toIndex, float val) { | ||
| 2154 | rangeCheck(a.length, fromIndex, toIndex); | ||
| 2155 | for (int i = fromIndex; i < toIndex; i++) | ||
| 2156 | a[i] = val; | ||
| 2157 | } | ||
| 2158 | |||
| 2159 | /** | ||
| 2160 | * Assigns the specified Object reference to each element of the specified | ||
| 2161 | * array of Objects. | ||
| 2162 | * | ||
| 2163 | * @param a the array to be filled | ||
| 2164 | * @param val the value to be stored in all elements of the array | ||
| 2165 | * @throws ArrayStoreException if the specified value is not of a | ||
| 2166 | * runtime type that can be stored in the specified array | ||
| 2167 | */ | ||
| 2168 | public static void fill(Object[] a, Object val) { | ||
| 2169 | for (int i = 0, len = a.length; i < len; i++) | ||
| 2170 | a[i] = val; | ||
| 2171 | } | ||
| 2172 | |||
| 2173 | /** | ||
| 2174 | * Assigns the specified Object reference to each element of the specified | ||
| 2175 | * range of the specified array of Objects. The range to be filled | ||
| 2176 | * extends from index <tt>fromIndex</tt>, inclusive, to index | ||
| 2177 | * <tt>toIndex</tt>, exclusive. (If <tt>fromIndex==toIndex</tt>, the | ||
| 2178 | * range to be filled is empty.) | ||
| 2179 | * | ||
| 2180 | * @param a the array to be filled | ||
| 2181 | * @param fromIndex the index of the first element (inclusive) to be | ||
| 2182 | * filled with the specified value | ||
| 2183 | * @param toIndex the index of the last element (exclusive) to be | ||
| 2184 | * filled with the specified value | ||
| 2185 | * @param val the value to be stored in all elements of the array | ||
| 2186 | * @throws IllegalArgumentException if <tt>fromIndex > toIndex</tt> | ||
| 2187 | * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex < 0</tt> or | ||
| 2188 | * <tt>toIndex > a.length</tt> | ||
| 2189 | * @throws ArrayStoreException if the specified value is not of a | ||
| 2190 | * runtime type that can be stored in the specified array | ||
| 2191 | */ | ||
| 2192 | public static void fill(Object[] a, int fromIndex, int toIndex, Object val) { | ||
| 2193 | rangeCheck(a.length, fromIndex, toIndex); | ||
| 2194 | for (int i = fromIndex; i < toIndex; i++) | ||
| 2195 | a[i] = val; | ||
| 2196 | } | ||
| 2197 | |||
| 2198 | // Cloning | ||
| 2199 | |||
| 2200 | /** | ||
| 2201 | * Copies the specified array, truncating or padding with nulls (if necessary) | ||
| 2202 | * so the copy has the specified length. For all indices that are | ||
| 2203 | * valid in both the original array and the copy, the two arrays will | ||
| 2204 | * contain identical values. For any indices that are valid in the | ||
| 2205 | * copy but not the original, the copy will contain <tt>null</tt>. | ||
| 2206 | * Such indices will exist if and only if the specified length | ||
| 2207 | * is greater than that of the original array. | ||
| 2208 | * The resulting array is of exactly the same class as the original array. | ||
| 2209 | * | ||
| 2210 | * @param original the array to be copied | ||
| 2211 | * @param newLength the length of the copy to be returned | ||
| 2212 | * @return a copy of the original array, truncated or padded with nulls | ||
| 2213 | * to obtain the specified length | ||
| 2214 | * @throws NegativeArraySizeException if <tt>newLength</tt> is negative | ||
| 2215 | * @throws NullPointerException if <tt>original</tt> is null | ||
| 2216 | * @since 1.6 | ||
| 2217 | */ | ||
| 2218 | public static <T> T[] copyOf(T[] original, int newLength) { | ||
| 2219 | return (T[]) copyOf(original, newLength, original.getClass()); | ||
| 2220 | } | ||
| 2221 | |||
| 2222 | /** | ||
| 2223 | * Copies the specified array, truncating or padding with nulls (if necessary) | ||
| 2224 | * so the copy has the specified length. For all indices that are | ||
| 2225 | * valid in both the original array and the copy, the two arrays will | ||
| 2226 | * contain identical values. For any indices that are valid in the | ||
| 2227 | * copy but not the original, the copy will contain <tt>null</tt>. | ||
| 2228 | * Such indices will exist if and only if the specified length | ||
| 2229 | * is greater than that of the original array. | ||
| 2230 | * The resulting array is of the class <tt>newType</tt>. | ||
| 2231 | * | ||
| 2232 | * @param original the array to be copied | ||
| 2233 | * @param newLength the length of the copy to be returned | ||
| 2234 | * @param newType the class of the copy to be returned | ||
| 2235 | * @return a copy of the original array, truncated or padded with nulls | ||
| 2236 | * to obtain the specified length | ||
| 2237 | * @throws NegativeArraySizeException if <tt>newLength</tt> is negative | ||
| 2238 | * @throws NullPointerException if <tt>original</tt> is null | ||
| 2239 | * @throws ArrayStoreException if an element copied from | ||
| 2240 | * <tt>original</tt> is not of a runtime type that can be stored in | ||
| 2241 | * an array of class <tt>newType</tt> | ||
| 2242 | * @since 1.6 | ||
| 2243 | */ | ||
| 2244 | public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) { | ||
| 2245 | T[] copy = ((Object)newType == (Object)Object[].class) | ||
| 2246 | ? (T[]) new Object[newLength] | ||
| 2247 | : (T[]) Array.newInstance(newType.getComponentType(), newLength); | ||
| 2248 | System.arraycopy(original, 0, copy, 0, | ||
| 2249 | Math.min(original.length, newLength)); | ||
| 2250 | return copy; | ||
| 2251 | } | ||
| 2252 | |||
| 2253 | /** | ||
| 2254 | * Copies the specified array, truncating or padding with zeros (if necessary) | ||
| 2255 | * so the copy has the specified length. For all indices that are | ||
| 2256 | * valid in both the original array and the copy, the two arrays will | ||
| 2257 | * contain identical values. For any indices that are valid in the | ||
| 2258 | * copy but not the original, the copy will contain <tt>(byte)0</tt>. | ||
| 2259 | * Such indices will exist if and only if the specified length | ||
| 2260 | * is greater than that of the original array. | ||
| 2261 | * | ||
| 2262 | * @param original the array to be copied | ||
| 2263 | * @param newLength the length of the copy to be returned | ||
| 2264 | * @return a copy of the original array, truncated or padded with zeros | ||
| 2265 | * to obtain the specified length | ||
| 2266 | * @throws NegativeArraySizeException if <tt>newLength</tt> is negative | ||
| 2267 | * @throws NullPointerException if <tt>original</tt> is null | ||
| 2268 | * @since 1.6 | ||
| 2269 | */ | ||
| 2270 | public static byte[] copyOf(byte[] original, int newLength) { | ||
| 2271 | byte[] copy = new byte[newLength]; | ||
| 2272 | System.arraycopy(original, 0, copy, 0, | ||
| 2273 | Math.min(original.length, newLength)); | ||
| 2274 | return copy; | ||
| 2275 | } | ||
| 2276 | |||
| 2277 | /** | ||
| 2278 | * Copies the specified array, truncating or padding with zeros (if necessary) | ||
| 2279 | * so the copy has the specified length. For all indices that are | ||
| 2280 | * valid in both the original array and the copy, the two arrays will | ||
| 2281 | * contain identical values. For any indices that are valid in the | ||
| 2282 | * copy but not the original, the copy will contain <tt>(short)0</tt>. | ||
| 2283 | * Such indices will exist if and only if the specified length | ||
| 2284 | * is greater than that of the original array. | ||
| 2285 | * | ||
| 2286 | * @param original the array to be copied | ||
| 2287 | * @param newLength the length of the copy to be returned | ||
| 2288 | * @return a copy of the original array, truncated or padded with zeros | ||
| 2289 | * to obtain the specified length | ||
| 2290 | * @throws NegativeArraySizeException if <tt>newLength</tt> is negative | ||
| 2291 | * @throws NullPointerException if <tt>original</tt> is null | ||
| 2292 | * @since 1.6 | ||
| 2293 | */ | ||
| 2294 | public static short[] copyOf(short[] original, int newLength) { | ||
| 2295 | short[] copy = new short[newLength]; | ||
| 2296 | System.arraycopy(original, 0, copy, 0, | ||
| 2297 | Math.min(original.length, newLength)); | ||
| 2298 | return copy; | ||
| 2299 | } | ||
| 2300 | |||
| 2301 | /** | ||
| 2302 | * Copies the specified array, truncating or padding with zeros (if necessary) | ||
| 2303 | * so the copy has the specified length. For all indices that are | ||
| 2304 | * valid in both the original array and the copy, the two arrays will | ||
| 2305 | * contain identical values. For any indices that are valid in the | ||
| 2306 | * copy but not the original, the copy will contain <tt>0</tt>. | ||
| 2307 | * Such indices will exist if and only if the specified length | ||
| 2308 | * is greater than that of the original array. | ||
| 2309 | * | ||
| 2310 | * @param original the array to be copied | ||
| 2311 | * @param newLength the length of the copy to be returned | ||
| 2312 | * @return a copy of the original array, truncated or padded with zeros | ||
| 2313 | * to obtain the specified length | ||
| 2314 | * @throws NegativeArraySizeException if <tt>newLength</tt> is negative | ||
| 2315 | * @throws NullPointerException if <tt>original</tt> is null | ||
| 2316 | * @since 1.6 | ||
| 2317 | */ | ||
| 2318 | public static int[] copyOf(int[] original, int newLength) { | ||
| 2319 | int[] copy = new int[newLength]; | ||
| 2320 | System.arraycopy(original, 0, copy, 0, | ||
| 2321 | Math.min(original.length, newLength)); | ||
| 2322 | return copy; | ||
| 2323 | } | ||
| 2324 | |||
| 2325 | /** | ||
| 2326 | * Copies the specified array, truncating or padding with zeros (if necessary) | ||
| 2327 | * so the copy has the specified length. For all indices that are | ||
| 2328 | * valid in both the original array and the copy, the two arrays will | ||
| 2329 | * contain identical values. For any indices that are valid in the | ||
| 2330 | * copy but not the original, the copy will contain <tt>0L</tt>. | ||
| 2331 | * Such indices will exist if and only if the specified length | ||
| 2332 | * is greater than that of the original array. | ||
| 2333 | * | ||
| 2334 | * @param original the array to be copied | ||
| 2335 | * @param newLength the length of the copy to be returned | ||
| 2336 | * @return a copy of the original array, truncated or padded with zeros | ||
| 2337 | * to obtain the specified length | ||
| 2338 | * @throws NegativeArraySizeException if <tt>newLength</tt> is negative | ||
| 2339 | * @throws NullPointerException if <tt>original</tt> is null | ||
| 2340 | * @since 1.6 | ||
| 2341 | */ | ||
| 2342 | public static long[] copyOf(long[] original, int newLength) { | ||
| 2343 | long[] copy = new long[newLength]; | ||
| 2344 | System.arraycopy(original, 0, copy, 0, | ||
| 2345 | Math.min(original.length, newLength)); | ||
| 2346 | return copy; | ||
| 2347 | } | ||
| 2348 | |||
| 2349 | /** | ||
| 2350 | * Copies the specified array, truncating or padding with null characters (if necessary) | ||
| 2351 | * so the copy has the specified length. For all indices that are valid | ||
| 2352 | * in both the original array and the copy, the two arrays will contain | ||
| 2353 | * identical values. For any indices that are valid in the copy but not | ||
| 2354 | * the original, the copy will contain <tt>'\\u000'</tt>. Such indices | ||
| 2355 | * will exist if and only if the specified length is greater than that of | ||
| 2356 | * the original array. | ||
| 2357 | * | ||
| 2358 | * @param original the array to be copied | ||
| 2359 | * @param newLength the length of the copy to be returned | ||
| 2360 | * @return a copy of the original array, truncated or padded with null characters | ||
| 2361 | * to obtain the specified length | ||
| 2362 | * @throws NegativeArraySizeException if <tt>newLength</tt> is negative | ||
| 2363 | * @throws NullPointerException if <tt>original</tt> is null | ||
| 2364 | * @since 1.6 | ||
| 2365 | */ | ||
| 2366 | public static char[] copyOf(char[] original, int newLength) { | ||
| 2367 | char[] copy = new char[newLength]; | ||
| 2368 | System.arraycopy(original, 0, copy, 0, | ||
| 2369 | Math.min(original.length, newLength)); | ||
| 2370 | return copy; | ||
| 2371 | } | ||
| 2372 | |||
| 2373 | /** | ||
| 2374 | * Copies the specified array, truncating or padding with zeros (if necessary) | ||
| 2375 | * so the copy has the specified length. For all indices that are | ||
| 2376 | * valid in both the original array and the copy, the two arrays will | ||
| 2377 | * contain identical values. For any indices that are valid in the | ||
| 2378 | * copy but not the original, the copy will contain <tt>0f</tt>. | ||
| 2379 | * Such indices will exist if and only if the specified length | ||
| 2380 | * is greater than that of the original array. | ||
| 2381 | * | ||
| 2382 | * @param original the array to be copied | ||
| 2383 | * @param newLength the length of the copy to be returned | ||
| 2384 | * @return a copy of the original array, truncated or padded with zeros | ||
| 2385 | * to obtain the specified length | ||
| 2386 | * @throws NegativeArraySizeException if <tt>newLength</tt> is negative | ||
| 2387 | * @throws NullPointerException if <tt>original</tt> is null | ||
| 2388 | * @since 1.6 | ||
| 2389 | */ | ||
| 2390 | public static float[] copyOf(float[] original, int newLength) { | ||
| 2391 | float[] copy = new float[newLength]; | ||
| 2392 | System.arraycopy(original, 0, copy, 0, | ||
| 2393 | Math.min(original.length, newLength)); | ||
| 2394 | return copy; | ||
| 2395 | } | ||
| 2396 | |||
| 2397 | /** | ||
| 2398 | * Copies the specified array, truncating or padding with zeros (if necessary) | ||
| 2399 | * so the copy has the specified length. For all indices that are | ||
| 2400 | * valid in both the original array and the copy, the two arrays will | ||
| 2401 | * contain identical values. For any indices that are valid in the | ||
| 2402 | * copy but not the original, the copy will contain <tt>0d</tt>. | ||
| 2403 | * Such indices will exist if and only if the specified length | ||
| 2404 | * is greater than that of the original array. | ||
| 2405 | * | ||
| 2406 | * @param original the array to be copied | ||
| 2407 | * @param newLength the length of the copy to be returned | ||
| 2408 | * @return a copy of the original array, truncated or padded with zeros | ||
| 2409 | * to obtain the specified length | ||
| 2410 | * @throws NegativeArraySizeException if <tt>newLength</tt> is negative | ||
| 2411 | * @throws NullPointerException if <tt>original</tt> is null | ||
| 2412 | * @since 1.6 | ||
| 2413 | */ | ||
| 2414 | public static double[] copyOf(double[] original, int newLength) { | ||
| 2415 | double[] copy = new double[newLength]; | ||
| 2416 | System.arraycopy(original, 0, copy, 0, | ||
| 2417 | Math.min(original.length, newLength)); | ||
| 2418 | return copy; | ||
| 2419 | } | ||
| 2420 | |||
| 2421 | /** | ||
| 2422 | * Copies the specified array, truncating or padding with <tt>false</tt> (if necessary) | ||
| 2423 | * so the copy has the specified length. For all indices that are | ||
| 2424 | * valid in both the original array and the copy, the two arrays will | ||
| 2425 | * contain identical values. For any indices that are valid in the | ||
| 2426 | * copy but not the original, the copy will contain <tt>false</tt>. | ||
| 2427 | * Such indices will exist if and only if the specified length | ||
| 2428 | * is greater than that of the original array. | ||
| 2429 | * | ||
| 2430 | * @param original the array to be copied | ||
| 2431 | * @param newLength the length of the copy to be returned | ||
| 2432 | * @return a copy of the original array, truncated or padded with false elements | ||
| 2433 | * to obtain the specified length | ||
| 2434 | * @throws NegativeArraySizeException if <tt>newLength</tt> is negative | ||
| 2435 | * @throws NullPointerException if <tt>original</tt> is null | ||
| 2436 | * @since 1.6 | ||
| 2437 | */ | ||
| 2438 | public static boolean[] copyOf(boolean[] original, int newLength) { | ||
| 2439 | boolean[] copy = new boolean[newLength]; | ||
| 2440 | System.arraycopy(original, 0, copy, 0, | ||
| 2441 | Math.min(original.length, newLength)); | ||
| 2442 | return copy; | ||
| 2443 | } | ||
| 2444 | |||
| 2445 | /** | ||
| 2446 | * Copies the specified range of the specified array into a new array. | ||
| 2447 | * The initial index of the range (<tt>from</tt>) must lie between zero | ||
| 2448 | * and <tt>original.length</tt>, inclusive. The value at | ||
| 2449 | * <tt>original[from]</tt> is placed into the initial element of the copy | ||
| 2450 | * (unless <tt>from == original.length</tt> or <tt>from == to</tt>). | ||
| 2451 | * Values from subsequent elements in the original array are placed into | ||
| 2452 | * subsequent elements in the copy. The final index of the range | ||
| 2453 | * (<tt>to</tt>), which must be greater than or equal to <tt>from</tt>, | ||
| 2454 | * may be greater than <tt>original.length</tt>, in which case | ||
| 2455 | * <tt>null</tt> is placed in all elements of the copy whose index is | ||
| 2456 | * greater than or equal to <tt>original.length - from</tt>. The length | ||
| 2457 | * of the returned array will be <tt>to - from</tt>. | ||
| 2458 | * <p> | ||
| 2459 | * The resulting array is of exactly the same class as the original array. | ||
| 2460 | * | ||
| 2461 | * @param original the array from which a range is to be copied | ||
| 2462 | * @param from the initial index of the range to be copied, inclusive | ||
| 2463 | * @param to the final index of the range to be copied, exclusive. | ||
| 2464 | * (This index may lie outside the array.) | ||
| 2465 | * @return a new array containing the specified range from the original array, | ||
| 2466 | * truncated or padded with nulls to obtain the required length | ||
| 2467 | * @throws ArrayIndexOutOfBoundsException if {@code from < 0} | ||
| 2468 | * or {@code from > original.length} | ||
| 2469 | * @throws IllegalArgumentException if <tt>from > to</tt> | ||
| 2470 | * @throws NullPointerException if <tt>original</tt> is null | ||
| 2471 | * @since 1.6 | ||
| 2472 | */ | ||
| 2473 | public static <T> T[] copyOfRange(T[] original, int from, int to) { | ||
| 2474 | return copyOfRange(original, from, to, (Class<T[]>) original.getClass()); | ||
| 2475 | } | ||
| 2476 | |||
| 2477 | /** | ||
| 2478 | * Copies the specified range of the specified array into a new array. | ||
| 2479 | * The initial index of the range (<tt>from</tt>) must lie between zero | ||
| 2480 | * and <tt>original.length</tt>, inclusive. The value at | ||
| 2481 | * <tt>original[from]</tt> is placed into the initial element of the copy | ||
| 2482 | * (unless <tt>from == original.length</tt> or <tt>from == to</tt>). | ||
| 2483 | * Values from subsequent elements in the original array are placed into | ||
| 2484 | * subsequent elements in the copy. The final index of the range | ||
| 2485 | * (<tt>to</tt>), which must be greater than or equal to <tt>from</tt>, | ||
| 2486 | * may be greater than <tt>original.length</tt>, in which case | ||
| 2487 | * <tt>null</tt> is placed in all elements of the copy whose index is | ||
| 2488 | * greater than or equal to <tt>original.length - from</tt>. The length | ||
| 2489 | * of the returned array will be <tt>to - from</tt>. | ||
| 2490 | * The resulting array is of the class <tt>newType</tt>. | ||
| 2491 | * | ||
| 2492 | * @param original the array from which a range is to be copied | ||
| 2493 | * @param from the initial index of the range to be copied, inclusive | ||
| 2494 | * @param to the final index of the range to be copied, exclusive. | ||
| 2495 | * (This index may lie outside the array.) | ||
| 2496 | * @param newType the class of the copy to be returned | ||
| 2497 | * @return a new array containing the specified range from the original array, | ||
| 2498 | * truncated or padded with nulls to obtain the required length | ||
| 2499 | * @throws ArrayIndexOutOfBoundsException if {@code from < 0} | ||
| 2500 | * or {@code from > original.length} | ||
| 2501 | * @throws IllegalArgumentException if <tt>from > to</tt> | ||
| 2502 | * @throws NullPointerException if <tt>original</tt> is null | ||
| 2503 | * @throws ArrayStoreException if an element copied from | ||
| 2504 | * <tt>original</tt> is not of a runtime type that can be stored in | ||
| 2505 | * an array of class <tt>newType</tt>. | ||
| 2506 | * @since 1.6 | ||
| 2507 | */ | ||
| 2508 | public static <T,U> T[] copyOfRange(U[] original, int from, int to, Class<? extends T[]> newType) { | ||
| 2509 | int newLength = to - from; | ||
| 2510 | if (newLength < 0) | ||
| 2511 | throw new IllegalArgumentException(from + " > " + to); | ||
| 2512 | T[] copy = ((Object)newType == (Object)Object[].class) | ||
| 2513 | ? (T[]) new Object[newLength] | ||
| 2514 | : (T[]) Array.newInstance(newType.getComponentType(), newLength); | ||
| 2515 | System.arraycopy(original, from, copy, 0, | ||
| 2516 | Math.min(original.length - from, newLength)); | ||
| 2517 | return copy; | ||
| 2518 | } | ||
| 2519 | |||
| 2520 | /** | ||
| 2521 | * Copies the specified range of the specified array into a new array. | ||
| 2522 | * The initial index of the range (<tt>from</tt>) must lie between zero | ||
| 2523 | * and <tt>original.length</tt>, inclusive. The value at | ||
| 2524 | * <tt>original[from]</tt> is placed into the initial element of the copy | ||
| 2525 | * (unless <tt>from == original.length</tt> or <tt>from == to</tt>). | ||
| 2526 | * Values from subsequent elements in the original array are placed into | ||
| 2527 | * subsequent elements in the copy. The final index of the range | ||
| 2528 | * (<tt>to</tt>), which must be greater than or equal to <tt>from</tt>, | ||
| 2529 | * may be greater than <tt>original.length</tt>, in which case | ||
| 2530 | * <tt>(byte)0</tt> is placed in all elements of the copy whose index is | ||
| 2531 | * greater than or equal to <tt>original.length - from</tt>. The length | ||
| 2532 | * of the returned array will be <tt>to - from</tt>. | ||
| 2533 | * | ||
| 2534 | * @param original the array from which a range is to be copied | ||
| 2535 | * @param from the initial index of the range to be copied, inclusive | ||
| 2536 | * @param to the final index of the range to be copied, exclusive. | ||
| 2537 | * (This index may lie outside the array.) | ||
| 2538 | * @return a new array containing the specified range from the original array, | ||
| 2539 | * truncated or padded with zeros to obtain the required length | ||
| 2540 | * @throws ArrayIndexOutOfBoundsException if {@code from < 0} | ||
| 2541 | * or {@code from > original.length} | ||
| 2542 | * @throws IllegalArgumentException if <tt>from > to</tt> | ||
| 2543 | * @throws NullPointerException if <tt>original</tt> is null | ||
| 2544 | * @since 1.6 | ||
| 2545 | */ | ||
| 2546 | public static byte[] copyOfRange(byte[] original, int from, int to) { | ||
| 2547 | int newLength = to - from; | ||
| 2548 | if (newLength < 0) | ||
| 2549 | throw new IllegalArgumentException(from + " > " + to); | ||
| 2550 | byte[] copy = new byte[newLength]; | ||
| 2551 | System.arraycopy(original, from, copy, 0, | ||
| 2552 | Math.min(original.length - from, newLength)); | ||
| 2553 | return copy; | ||
| 2554 | } | ||
| 2555 | |||
| 2556 | /** | ||
| 2557 | * Copies the specified range of the specified array into a new array. | ||
| 2558 | * The initial index of the range (<tt>from</tt>) must lie between zero | ||
| 2559 | * and <tt>original.length</tt>, inclusive. The value at | ||
| 2560 | * <tt>original[from]</tt> is placed into the initial element of the copy | ||
| 2561 | * (unless <tt>from == original.length</tt> or <tt>from == to</tt>). | ||
| 2562 | * Values from subsequent elements in the original array are placed into | ||
| 2563 | * subsequent elements in the copy. The final index of the range | ||
| 2564 | * (<tt>to</tt>), which must be greater than or equal to <tt>from</tt>, | ||
| 2565 | * may be greater than <tt>original.length</tt>, in which case | ||
| 2566 | * <tt>(short)0</tt> is placed in all elements of the copy whose index is | ||
| 2567 | * greater than or equal to <tt>original.length - from</tt>. The length | ||
| 2568 | * of the returned array will be <tt>to - from</tt>. | ||
| 2569 | * | ||
| 2570 | * @param original the array from which a range is to be copied | ||
| 2571 | * @param from the initial index of the range to be copied, inclusive | ||
| 2572 | * @param to the final index of the range to be copied, exclusive. | ||
| 2573 | * (This index may lie outside the array.) | ||
| 2574 | * @return a new array containing the specified range from the original array, | ||
| 2575 | * truncated or padded with zeros to obtain the required length | ||
| 2576 | * @throws ArrayIndexOutOfBoundsException if {@code from < 0} | ||
| 2577 | * or {@code from > original.length} | ||
| 2578 | * @throws IllegalArgumentException if <tt>from > to</tt> | ||
| 2579 | * @throws NullPointerException if <tt>original</tt> is null | ||
| 2580 | * @since 1.6 | ||
| 2581 | */ | ||
| 2582 | public static short[] copyOfRange(short[] original, int from, int to) { | ||
| 2583 | int newLength = to - from; | ||
| 2584 | if (newLength < 0) | ||
| 2585 | throw new IllegalArgumentException(from + " > " + to); | ||
| 2586 | short[] copy = new short[newLength]; | ||
| 2587 | System.arraycopy(original, from, copy, 0, | ||
| 2588 | Math.min(original.length - from, newLength)); | ||
| 2589 | return copy; | ||
| 2590 | } | ||
| 2591 | |||
| 2592 | /** | ||
| 2593 | * Copies the specified range of the specified array into a new array. | ||
| 2594 | * The initial index of the range (<tt>from</tt>) must lie between zero | ||
| 2595 | * and <tt>original.length</tt>, inclusive. The value at | ||
| 2596 | * <tt>original[from]</tt> is placed into the initial element of the copy | ||
| 2597 | * (unless <tt>from == original.length</tt> or <tt>from == to</tt>). | ||
| 2598 | * Values from subsequent elements in the original array are placed into | ||
| 2599 | * subsequent elements in the copy. The final index of the range | ||
| 2600 | * (<tt>to</tt>), which must be greater than or equal to <tt>from</tt>, | ||
| 2601 | * may be greater than <tt>original.length</tt>, in which case | ||
| 2602 | * <tt>0</tt> is placed in all elements of the copy whose index is | ||
| 2603 | * greater than or equal to <tt>original.length - from</tt>. The length | ||
| 2604 | * of the returned array will be <tt>to - from</tt>. | ||
| 2605 | * | ||
| 2606 | * @param original the array from which a range is to be copied | ||
| 2607 | * @param from the initial index of the range to be copied, inclusive | ||
| 2608 | * @param to the final index of the range to be copied, exclusive. | ||
| 2609 | * (This index may lie outside the array.) | ||
| 2610 | * @return a new array containing the specified range from the original array, | ||
| 2611 | * truncated or padded with zeros to obtain the required length | ||
| 2612 | * @throws ArrayIndexOutOfBoundsException if {@code from < 0} | ||
| 2613 | * or {@code from > original.length} | ||
| 2614 | * @throws IllegalArgumentException if <tt>from > to</tt> | ||
| 2615 | * @throws NullPointerException if <tt>original</tt> is null | ||
| 2616 | * @since 1.6 | ||
| 2617 | */ | ||
| 2618 | public static int[] copyOfRange(int[] original, int from, int to) { | ||
| 2619 | int newLength = to - from; | ||
| 2620 | if (newLength < 0) | ||
| 2621 | throw new IllegalArgumentException(from + " > " + to); | ||
| 2622 | int[] copy = new int[newLength]; | ||
| 2623 | System.arraycopy(original, from, copy, 0, | ||
| 2624 | Math.min(original.length - from, newLength)); | ||
| 2625 | return copy; | ||
| 2626 | } | ||
| 2627 | |||
| 2628 | /** | ||
| 2629 | * Copies the specified range of the specified array into a new array. | ||
| 2630 | * The initial index of the range (<tt>from</tt>) must lie between zero | ||
| 2631 | * and <tt>original.length</tt>, inclusive. The value at | ||
| 2632 | * <tt>original[from]</tt> is placed into the initial element of the copy | ||
| 2633 | * (unless <tt>from == original.length</tt> or <tt>from == to</tt>). | ||
| 2634 | * Values from subsequent elements in the original array are placed into | ||
| 2635 | * subsequent elements in the copy. The final index of the range | ||
| 2636 | * (<tt>to</tt>), which must be greater than or equal to <tt>from</tt>, | ||
| 2637 | * may be greater than <tt>original.length</tt>, in which case | ||
| 2638 | * <tt>0L</tt> is placed in all elements of the copy whose index is | ||
| 2639 | * greater than or equal to <tt>original.length - from</tt>. The length | ||
| 2640 | * of the returned array will be <tt>to - from</tt>. | ||
| 2641 | * | ||
| 2642 | * @param original the array from which a range is to be copied | ||
| 2643 | * @param from the initial index of the range to be copied, inclusive | ||
| 2644 | * @param to the final index of the range to be copied, exclusive. | ||
| 2645 | * (This index may lie outside the array.) | ||
| 2646 | * @return a new array containing the specified range from the original array, | ||
| 2647 | * truncated or padded with zeros to obtain the required length | ||
| 2648 | * @throws ArrayIndexOutOfBoundsException if {@code from < 0} | ||
| 2649 | * or {@code from > original.length} | ||
| 2650 | * @throws IllegalArgumentException if <tt>from > to</tt> | ||
| 2651 | * @throws NullPointerException if <tt>original</tt> is null | ||
| 2652 | * @since 1.6 | ||
| 2653 | */ | ||
| 2654 | public static long[] copyOfRange(long[] original, int from, int to) { | ||
| 2655 | int newLength = to - from; | ||
| 2656 | if (newLength < 0) | ||
| 2657 | throw new IllegalArgumentException(from + " > " + to); | ||
| 2658 | long[] copy = new long[newLength]; | ||
| 2659 | System.arraycopy(original, from, copy, 0, | ||
| 2660 | Math.min(original.length - from, newLength)); | ||
| 2661 | return copy; | ||
| 2662 | } | ||
| 2663 | |||
| 2664 | /** | ||
| 2665 | * Copies the specified range of the specified array into a new array. | ||
| 2666 | * The initial index of the range (<tt>from</tt>) must lie between zero | ||
| 2667 | * and <tt>original.length</tt>, inclusive. The value at | ||
| 2668 | * <tt>original[from]</tt> is placed into the initial element of the copy | ||
| 2669 | * (unless <tt>from == original.length</tt> or <tt>from == to</tt>). | ||
| 2670 | * Values from subsequent elements in the original array are placed into | ||
| 2671 | * subsequent elements in the copy. The final index of the range | ||
| 2672 | * (<tt>to</tt>), which must be greater than or equal to <tt>from</tt>, | ||
| 2673 | * may be greater than <tt>original.length</tt>, in which case | ||
| 2674 | * <tt>'\\u000'</tt> is placed in all elements of the copy whose index is | ||
| 2675 | * greater than or equal to <tt>original.length - from</tt>. The length | ||
| 2676 | * of the returned array will be <tt>to - from</tt>. | ||
| 2677 | * | ||
| 2678 | * @param original the array from which a range is to be copied | ||
| 2679 | * @param from the initial index of the range to be copied, inclusive | ||
| 2680 | * @param to the final index of the range to be copied, exclusive. | ||
| 2681 | * (This index may lie outside the array.) | ||
| 2682 | * @return a new array containing the specified range from the original array, | ||
| 2683 | * truncated or padded with null characters to obtain the required length | ||
| 2684 | * @throws ArrayIndexOutOfBoundsException if {@code from < 0} | ||
| 2685 | * or {@code from > original.length} | ||
| 2686 | * @throws IllegalArgumentException if <tt>from > to</tt> | ||
| 2687 | * @throws NullPointerException if <tt>original</tt> is null | ||
| 2688 | * @since 1.6 | ||
| 2689 | */ | ||
| 2690 | public static char[] copyOfRange(char[] original, int from, int to) { | ||
| 2691 | int newLength = to - from; | ||
| 2692 | if (newLength < 0) | ||
| 2693 | throw new IllegalArgumentException(from + " > " + to); | ||
| 2694 | char[] copy = new char[newLength]; | ||
| 2695 | System.arraycopy(original, from, copy, 0, | ||
| 2696 | Math.min(original.length - from, newLength)); | ||
| 2697 | return copy; | ||
| 2698 | } | ||
| 2699 | |||
| 2700 | /** | ||
| 2701 | * Copies the specified range of the specified array into a new array. | ||
| 2702 | * The initial index of the range (<tt>from</tt>) must lie between zero | ||
| 2703 | * and <tt>original.length</tt>, inclusive. The value at | ||
| 2704 | * <tt>original[from]</tt> is placed into the initial element of the copy | ||
| 2705 | * (unless <tt>from == original.length</tt> or <tt>from == to</tt>). | ||
| 2706 | * Values from subsequent elements in the original array are placed into | ||
| 2707 | * subsequent elements in the copy. The final index of the range | ||
| 2708 | * (<tt>to</tt>), which must be greater than or equal to <tt>from</tt>, | ||
| 2709 | * may be greater than <tt>original.length</tt>, in which case | ||
| 2710 | * <tt>0f</tt> is placed in all elements of the copy whose index is | ||
| 2711 | * greater than or equal to <tt>original.length - from</tt>. The length | ||
| 2712 | * of the returned array will be <tt>to - from</tt>. | ||
| 2713 | * | ||
| 2714 | * @param original the array from which a range is to be copied | ||
| 2715 | * @param from the initial index of the range to be copied, inclusive | ||
| 2716 | * @param to the final index of the range to be copied, exclusive. | ||
| 2717 | * (This index may lie outside the array.) | ||
| 2718 | * @return a new array containing the specified range from the original array, | ||
| 2719 | * truncated or padded with zeros to obtain the required length | ||
| 2720 | * @throws ArrayIndexOutOfBoundsException if {@code from < 0} | ||
| 2721 | * or {@code from > original.length} | ||
| 2722 | * @throws IllegalArgumentException if <tt>from > to</tt> | ||
| 2723 | * @throws NullPointerException if <tt>original</tt> is null | ||
| 2724 | * @since 1.6 | ||
| 2725 | */ | ||
| 2726 | public static float[] copyOfRange(float[] original, int from, int to) { | ||
| 2727 | int newLength = to - from; | ||
| 2728 | if (newLength < 0) | ||
| 2729 | throw new IllegalArgumentException(from + " > " + to); | ||
| 2730 | float[] copy = new float[newLength]; | ||
| 2731 | System.arraycopy(original, from, copy, 0, | ||
| 2732 | Math.min(original.length - from, newLength)); | ||
| 2733 | return copy; | ||
| 2734 | } | ||
| 2735 | |||
| 2736 | /** | ||
| 2737 | * Copies the specified range of the specified array into a new array. | ||
| 2738 | * The initial index of the range (<tt>from</tt>) must lie between zero | ||
| 2739 | * and <tt>original.length</tt>, inclusive. The value at | ||
| 2740 | * <tt>original[from]</tt> is placed into the initial element of the copy | ||
| 2741 | * (unless <tt>from == original.length</tt> or <tt>from == to</tt>). | ||
| 2742 | * Values from subsequent elements in the original array are placed into | ||
| 2743 | * subsequent elements in the copy. The final index of the range | ||
| 2744 | * (<tt>to</tt>), which must be greater than or equal to <tt>from</tt>, | ||
| 2745 | * may be greater than <tt>original.length</tt>, in which case | ||
| 2746 | * <tt>0d</tt> is placed in all elements of the copy whose index is | ||
| 2747 | * greater than or equal to <tt>original.length - from</tt>. The length | ||
| 2748 | * of the returned array will be <tt>to - from</tt>. | ||
| 2749 | * | ||
| 2750 | * @param original the array from which a range is to be copied | ||
| 2751 | * @param from the initial index of the range to be copied, inclusive | ||
| 2752 | * @param to the final index of the range to be copied, exclusive. | ||
| 2753 | * (This index may lie outside the array.) | ||
| 2754 | * @return a new array containing the specified range from the original array, | ||
| 2755 | * truncated or padded with zeros to obtain the required length | ||
| 2756 | * @throws ArrayIndexOutOfBoundsException if {@code from < 0} | ||
| 2757 | * or {@code from > original.length} | ||
| 2758 | * @throws IllegalArgumentException if <tt>from > to</tt> | ||
| 2759 | * @throws NullPointerException if <tt>original</tt> is null | ||
| 2760 | * @since 1.6 | ||
| 2761 | */ | ||
| 2762 | public static double[] copyOfRange(double[] original, int from, int to) { | ||
| 2763 | int newLength = to - from; | ||
| 2764 | if (newLength < 0) | ||
| 2765 | throw new IllegalArgumentException(from + " > " + to); | ||
| 2766 | double[] copy = new double[newLength]; | ||
| 2767 | System.arraycopy(original, from, copy, 0, | ||
| 2768 | Math.min(original.length - from, newLength)); | ||
| 2769 | return copy; | ||
| 2770 | } | ||
| 2771 | |||
| 2772 | /** | ||
| 2773 | * Copies the specified range of the specified array into a new array. | ||
| 2774 | * The initial index of the range (<tt>from</tt>) must lie between zero | ||
| 2775 | * and <tt>original.length</tt>, inclusive. The value at | ||
| 2776 | * <tt>original[from]</tt> is placed into the initial element of the copy | ||
| 2777 | * (unless <tt>from == original.length</tt> or <tt>from == to</tt>). | ||
| 2778 | * Values from subsequent elements in the original array are placed into | ||
| 2779 | * subsequent elements in the copy. The final index of the range | ||
| 2780 | * (<tt>to</tt>), which must be greater than or equal to <tt>from</tt>, | ||
| 2781 | * may be greater than <tt>original.length</tt>, in which case | ||
| 2782 | * <tt>false</tt> is placed in all elements of the copy whose index is | ||
| 2783 | * greater than or equal to <tt>original.length - from</tt>. The length | ||
| 2784 | * of the returned array will be <tt>to - from</tt>. | ||
| 2785 | * | ||
| 2786 | * @param original the array from which a range is to be copied | ||
| 2787 | * @param from the initial index of the range to be copied, inclusive | ||
| 2788 | * @param to the final index of the range to be copied, exclusive. | ||
| 2789 | * (This index may lie outside the array.) | ||
| 2790 | * @return a new array containing the specified range from the original array, | ||
| 2791 | * truncated or padded with false elements to obtain the required length | ||
| 2792 | * @throws ArrayIndexOutOfBoundsException if {@code from < 0} | ||
| 2793 | * or {@code from > original.length} | ||
| 2794 | * @throws IllegalArgumentException if <tt>from > to</tt> | ||
| 2795 | * @throws NullPointerException if <tt>original</tt> is null | ||
| 2796 | * @since 1.6 | ||
| 2797 | */ | ||
| 2798 | public static boolean[] copyOfRange(boolean[] original, int from, int to) { | ||
| 2799 | int newLength = to - from; | ||
| 2800 | if (newLength < 0) | ||
| 2801 | throw new IllegalArgumentException(from + " > " + to); | ||
| 2802 | boolean[] copy = new boolean[newLength]; | ||
| 2803 | System.arraycopy(original, from, copy, 0, | ||
| 2804 | Math.min(original.length - from, newLength)); | ||
| 2805 | return copy; | ||
| 2806 | } | ||
| 2807 | |||
| 2808 | // Misc | ||
| 2809 | |||
| 2810 | /** | ||
| 2811 | * Returns a fixed-size list backed by the specified array. (Changes to | ||
| 2812 | * the returned list "write through" to the array.) This method acts | ||
| 2813 | * as bridge between array-based and collection-based APIs, in | ||
| 2814 | * combination with {@link Collection#toArray}. The returned list is | ||
| 2815 | * serializable and implements {@link RandomAccess}. | ||
| 2816 | * | ||
| 2817 | * <p>This method also provides a convenient way to create a fixed-size | ||
| 2818 | * list initialized to contain several elements: | ||
| 2819 | * <pre> | ||
| 2820 | * List<String> stooges = Arrays.asList("Larry", "Moe", "Curly"); | ||
| 2821 | * </pre> | ||
| 2822 | * | ||
| 2823 | * @param a the array by which the list will be backed | ||
| 2824 | * @return a list view of the specified array | ||
| 2825 | */ | ||
| 2826 | @SafeVarargs | ||
| 2827 | public static <T> List<T> asList(T... a) { | ||
| 2828 | return new ArrayList<>(a); | ||
| 2829 | } | ||
| 2830 | |||
| 2831 | /** | ||
| 2832 | * @serial include | ||
| 2833 | */ | ||
| 2834 | private static class ArrayList<E> extends AbstractList<E> | ||
| 2835 | implements RandomAccess, java.io.Serializable | ||
| 2836 | { | ||
| 2837 | private static final long serialVersionUID = -2764017481108945198L; | ||
| 2838 | private final E[] a; | ||
| 2839 | |||
| 2840 | ArrayList(E[] array) { | ||
| 2841 | if (array==null) | ||
| 2842 | throw new NullPointerException(); | ||
| 2843 | a = array; | ||
| 2844 | } | ||
| 2845 | |||
| 2846 | public int size() { | ||
| 2847 | return a.length; | ||
| 2848 | } | ||
| 2849 | |||
| 2850 | public Object[] toArray() { | ||
| 2851 | return a.clone(); | ||
| 2852 | } | ||
| 2853 | |||
| 2854 | public <T> T[] toArray(T[] a) { | ||
| 2855 | int size = size(); | ||
| 2856 | if (a.length < size) | ||
| 2857 | return Arrays.copyOf(this.a, size, | ||
| 2858 | (Class<? extends T[]>) a.getClass()); | ||
| 2859 | System.arraycopy(this.a, 0, a, 0, size); | ||
| 2860 | if (a.length > size) | ||
| 2861 | a[size] = null; | ||
| 2862 | return a; | ||
| 2863 | } | ||
| 2864 | |||
| 2865 | public E get(int index) { | ||
| 2866 | return a[index]; | ||
| 2867 | } | ||
| 2868 | |||
| 2869 | public E set(int index, E element) { | ||
| 2870 | E oldValue = a[index]; | ||
| 2871 | a[index] = element; | ||
| 2872 | return oldValue; | ||
| 2873 | } | ||
| 2874 | |||
| 2875 | public int indexOf(Object o) { | ||
| 2876 | if (o==null) { | ||
| 2877 | for (int i=0; i<a.length; i++) | ||
| 2878 | if (a[i]==null) | ||
| 2879 | return i; | ||
| 2880 | } else { | ||
| 2881 | for (int i=0; i<a.length; i++) | ||
| 2882 | if (o.equals(a[i])) | ||
| 2883 | return i; | ||
| 2884 | } | ||
| 2885 | return -1; | ||
| 2886 | } | ||
| 2887 | |||
| 2888 | public boolean contains(Object o) { | ||
| 2889 | return indexOf(o) != -1; | ||
| 2890 | } | ||
| 2891 | } | ||
| 2892 | |||
| 2893 | /** | ||
| 2894 | * Returns a hash code based on the contents of the specified array. | ||
| 2895 | * For any two <tt>long</tt> arrays <tt>a</tt> and <tt>b</tt> | ||
| 2896 | * such that <tt>Arrays.equals(a, b)</tt>, it is also the case that | ||
| 2897 | * <tt>Arrays.hashCode(a) == Arrays.hashCode(b)</tt>. | ||
| 2898 | * | ||
| 2899 | * <p>The value returned by this method is the same value that would be | ||
| 2900 | * obtained by invoking the {@link List#hashCode() <tt>hashCode</tt>} | ||
| 2901 | * method on a {@link List} containing a sequence of {@link Long} | ||
| 2902 | * instances representing the elements of <tt>a</tt> in the same order. | ||
| 2903 | * If <tt>a</tt> is <tt>null</tt>, this method returns 0. | ||
| 2904 | * | ||
| 2905 | * @param a the array whose hash value to compute | ||
| 2906 | * @return a content-based hash code for <tt>a</tt> | ||
| 2907 | * @since 1.5 | ||
| 2908 | */ | ||
| 2909 | public static int hashCode(long a[]) { | ||
| 2910 | if (a == null) | ||
| 2911 | return 0; | ||
| 2912 | |||
| 2913 | int result = 1; | ||
| 2914 | for (long element : a) { | ||
| 2915 | int elementHash = (int)(element ^ (element >>> 32)); | ||
| 2916 | result = 31 * result + elementHash; | ||
| 2917 | } | ||
| 2918 | |||
| 2919 | return result; | ||
| 2920 | } | ||
| 2921 | |||
| 2922 | /** | ||
| 2923 | * Returns a hash code based on the contents of the specified array. | ||
| 2924 | * For any two non-null <tt>int</tt> arrays <tt>a</tt> and <tt>b</tt> | ||
| 2925 | * such that <tt>Arrays.equals(a, b)</tt>, it is also the case that | ||
| 2926 | * <tt>Arrays.hashCode(a) == Arrays.hashCode(b)</tt>. | ||
| 2927 | * | ||
| 2928 | * <p>The value returned by this method is the same value that would be | ||
| 2929 | * obtained by invoking the {@link List#hashCode() <tt>hashCode</tt>} | ||
| 2930 | * method on a {@link List} containing a sequence of {@link Integer} | ||
| 2931 | * instances representing the elements of <tt>a</tt> in the same order. | ||
| 2932 | * If <tt>a</tt> is <tt>null</tt>, this method returns 0. | ||
| 2933 | * | ||
| 2934 | * @param a the array whose hash value to compute | ||
| 2935 | * @return a content-based hash code for <tt>a</tt> | ||
| 2936 | * @since 1.5 | ||
| 2937 | */ | ||
| 2938 | public static int hashCode(int a[]) { | ||
| 2939 | if (a == null) | ||
| 2940 | return 0; | ||
| 2941 | |||
| 2942 | int result = 1; | ||
| 2943 | for (int element : a) | ||
| 2944 | result = 31 * result + element; | ||
| 2945 | |||
| 2946 | return result; | ||
| 2947 | } | ||
| 2948 | |||
| 2949 | /** | ||
| 2950 | * Returns a hash code based on the contents of the specified array. | ||
| 2951 | * For any two <tt>short</tt> arrays <tt>a</tt> and <tt>b</tt> | ||
| 2952 | * such that <tt>Arrays.equals(a, b)</tt>, it is also the case that | ||
| 2953 | * <tt>Arrays.hashCode(a) == Arrays.hashCode(b)</tt>. | ||
| 2954 | * | ||
| 2955 | * <p>The value returned by this method is the same value that would be | ||
| 2956 | * obtained by invoking the {@link List#hashCode() <tt>hashCode</tt>} | ||
| 2957 | * method on a {@link List} containing a sequence of {@link Short} | ||
| 2958 | * instances representing the elements of <tt>a</tt> in the same order. | ||
| 2959 | * If <tt>a</tt> is <tt>null</tt>, this method returns 0. | ||
| 2960 | * | ||
| 2961 | * @param a the array whose hash value to compute | ||
| 2962 | * @return a content-based hash code for <tt>a</tt> | ||
| 2963 | * @since 1.5 | ||
| 2964 | */ | ||
| 2965 | public static int hashCode(short a[]) { | ||
| 2966 | if (a == null) | ||
| 2967 | return 0; | ||
| 2968 | |||
| 2969 | int result = 1; | ||
| 2970 | for (short element : a) | ||
| 2971 | result = 31 * result + element; | ||
| 2972 | |||
| 2973 | return result; | ||
| 2974 | } | ||
| 2975 | |||
| 2976 | /** | ||
| 2977 | * Returns a hash code based on the contents of the specified array. | ||
| 2978 | * For any two <tt>char</tt> arrays <tt>a</tt> and <tt>b</tt> | ||
| 2979 | * such that <tt>Arrays.equals(a, b)</tt>, it is also the case that | ||
| 2980 | * <tt>Arrays.hashCode(a) == Arrays.hashCode(b)</tt>. | ||
| 2981 | * | ||
| 2982 | * <p>The value returned by this method is the same value that would be | ||
| 2983 | * obtained by invoking the {@link List#hashCode() <tt>hashCode</tt>} | ||
| 2984 | * method on a {@link List} containing a sequence of {@link Character} | ||
| 2985 | * instances representing the elements of <tt>a</tt> in the same order. | ||
| 2986 | * If <tt>a</tt> is <tt>null</tt>, this method returns 0. | ||
| 2987 | * | ||
| 2988 | * @param a the array whose hash value to compute | ||
| 2989 | * @return a content-based hash code for <tt>a</tt> | ||
| 2990 | * @since 1.5 | ||
| 2991 | */ | ||
| 2992 | public static int hashCode(char a[]) { | ||
| 2993 | if (a == null) | ||
| 2994 | return 0; | ||
| 2995 | |||
| 2996 | int result = 1; | ||
| 2997 | for (char element : a) | ||
| 2998 | result = 31 * result + element; | ||
| 2999 | |||
| 3000 | return result; | ||
| 3001 | } | ||
| 3002 | |||
| 3003 | /** | ||
| 3004 | * Returns a hash code based on the contents of the specified array. | ||
| 3005 | * For any two <tt>byte</tt> arrays <tt>a</tt> and <tt>b</tt> | ||
| 3006 | * such that <tt>Arrays.equals(a, b)</tt>, it is also the case that | ||
| 3007 | * <tt>Arrays.hashCode(a) == Arrays.hashCode(b)</tt>. | ||
| 3008 | * | ||
| 3009 | * <p>The value returned by this method is the same value that would be | ||
| 3010 | * obtained by invoking the {@link List#hashCode() <tt>hashCode</tt>} | ||
| 3011 | * method on a {@link List} containing a sequence of {@link Byte} | ||
| 3012 | * instances representing the elements of <tt>a</tt> in the same order. | ||
| 3013 | * If <tt>a</tt> is <tt>null</tt>, this method returns 0. | ||
| 3014 | * | ||
| 3015 | * @param a the array whose hash value to compute | ||
| 3016 | * @return a content-based hash code for <tt>a</tt> | ||
| 3017 | * @since 1.5 | ||
| 3018 | */ | ||
| 3019 | public static int hashCode(byte a[]) { | ||
| 3020 | if (a == null) | ||
| 3021 | return 0; | ||
| 3022 | |||
| 3023 | int result = 1; | ||
| 3024 | for (byte element : a) | ||
| 3025 | result = 31 * result + element; | ||
| 3026 | |||
| 3027 | return result; | ||
| 3028 | } | ||
| 3029 | |||
| 3030 | /** | ||
| 3031 | * Returns a hash code based on the contents of the specified array. | ||
| 3032 | * For any two <tt>boolean</tt> arrays <tt>a</tt> and <tt>b</tt> | ||
| 3033 | * such that <tt>Arrays.equals(a, b)</tt>, it is also the case that | ||
| 3034 | * <tt>Arrays.hashCode(a) == Arrays.hashCode(b)</tt>. | ||
| 3035 | * | ||
| 3036 | * <p>The value returned by this method is the same value that would be | ||
| 3037 | * obtained by invoking the {@link List#hashCode() <tt>hashCode</tt>} | ||
| 3038 | * method on a {@link List} containing a sequence of {@link Boolean} | ||
| 3039 | * instances representing the elements of <tt>a</tt> in the same order. | ||
| 3040 | * If <tt>a</tt> is <tt>null</tt>, this method returns 0. | ||
| 3041 | * | ||
| 3042 | * @param a the array whose hash value to compute | ||
| 3043 | * @return a content-based hash code for <tt>a</tt> | ||
| 3044 | * @since 1.5 | ||
| 3045 | */ | ||
| 3046 | public static int hashCode(boolean a[]) { | ||
| 3047 | if (a == null) | ||
| 3048 | return 0; | ||
| 3049 | |||
| 3050 | int result = 1; | ||
| 3051 | for (boolean element : a) | ||
| 3052 | result = 31 * result + (element ? 1231 : 1237); | ||
| 3053 | |||
| 3054 | return result; | ||
| 3055 | } | ||
| 3056 | |||
| 3057 | /** | ||
| 3058 | * Returns a hash code based on the contents of the specified array. | ||
| 3059 | * For any two <tt>float</tt> arrays <tt>a</tt> and <tt>b</tt> | ||
| 3060 | * such that <tt>Arrays.equals(a, b)</tt>, it is also the case that | ||
| 3061 | * <tt>Arrays.hashCode(a) == Arrays.hashCode(b)</tt>. | ||
| 3062 | * | ||
| 3063 | * <p>The value returned by this method is the same value that would be | ||
| 3064 | * obtained by invoking the {@link List#hashCode() <tt>hashCode</tt>} | ||
| 3065 | * method on a {@link List} containing a sequence of {@link Float} | ||
| 3066 | * instances representing the elements of <tt>a</tt> in the same order. | ||
| 3067 | * If <tt>a</tt> is <tt>null</tt>, this method returns 0. | ||
| 3068 | * | ||
| 3069 | * @param a the array whose hash value to compute | ||
| 3070 | * @return a content-based hash code for <tt>a</tt> | ||
| 3071 | * @since 1.5 | ||
| 3072 | */ | ||
| 3073 | public static int hashCode(float a[]) { | ||
| 3074 | if (a == null) | ||
| 3075 | return 0; | ||
| 3076 | |||
| 3077 | int result = 1; | ||
| 3078 | for (float element : a) | ||
| 3079 | result = 31 * result + Float.floatToIntBits(element); | ||
| 3080 | |||
| 3081 | return result; | ||
| 3082 | } | ||
| 3083 | |||
| 3084 | /** | ||
| 3085 | * Returns a hash code based on the contents of the specified array. | ||
| 3086 | * For any two <tt>double</tt> arrays <tt>a</tt> and <tt>b</tt> | ||
| 3087 | * such that <tt>Arrays.equals(a, b)</tt>, it is also the case that | ||
| 3088 | * <tt>Arrays.hashCode(a) == Arrays.hashCode(b)</tt>. | ||
| 3089 | * | ||
| 3090 | * <p>The value returned by this method is the same value that would be | ||
| 3091 | * obtained by invoking the {@link List#hashCode() <tt>hashCode</tt>} | ||
| 3092 | * method on a {@link List} containing a sequence of {@link Double} | ||
| 3093 | * instances representing the elements of <tt>a</tt> in the same order. | ||
| 3094 | * If <tt>a</tt> is <tt>null</tt>, this method returns 0. | ||
| 3095 | * | ||
| 3096 | * @param a the array whose hash value to compute | ||
| 3097 | * @return a content-based hash code for <tt>a</tt> | ||
| 3098 | * @since 1.5 | ||
| 3099 | */ | ||
| 3100 | public static int hashCode(double a[]) { | ||
| 3101 | if (a == null) | ||
| 3102 | return 0; | ||
| 3103 | |||
| 3104 | int result = 1; | ||
| 3105 | for (double element : a) { | ||
| 3106 | long bits = Double.doubleToLongBits(element); | ||
| 3107 | result = 31 * result + (int)(bits ^ (bits >>> 32)); | ||
| 3108 | } | ||
| 3109 | return result; | ||
| 3110 | } | ||
| 3111 | |||
| 3112 | /** | ||
| 3113 | * Returns a hash code based on the contents of the specified array. If | ||
| 3114 | * the array contains other arrays as elements, the hash code is based on | ||
| 3115 | * their identities rather than their contents. It is therefore | ||
| 3116 | * acceptable to invoke this method on an array that contains itself as an | ||
| 3117 | * element, either directly or indirectly through one or more levels of | ||
| 3118 | * arrays. | ||
| 3119 | * | ||
| 3120 | * <p>For any two arrays <tt>a</tt> and <tt>b</tt> such that | ||
| 3121 | * <tt>Arrays.equals(a, b)</tt>, it is also the case that | ||
| 3122 | * <tt>Arrays.hashCode(a) == Arrays.hashCode(b)</tt>. | ||
| 3123 | * | ||
| 3124 | * <p>The value returned by this method is equal to the value that would | ||
| 3125 | * be returned by <tt>Arrays.asList(a).hashCode()</tt>, unless <tt>a</tt> | ||
| 3126 | * is <tt>null</tt>, in which case <tt>0</tt> is returned. | ||
| 3127 | * | ||
| 3128 | * @param a the array whose content-based hash code to compute | ||
| 3129 | * @return a content-based hash code for <tt>a</tt> | ||
| 3130 | * @see #deepHashCode(Object[]) | ||
| 3131 | * @since 1.5 | ||
| 3132 | */ | ||
| 3133 | public static int hashCode(Object a[]) { | ||
| 3134 | if (a == null) | ||
| 3135 | return 0; | ||
| 3136 | |||
| 3137 | int result = 1; | ||
| 3138 | |||
| 3139 | for (Object element : a) | ||
| 3140 | result = 31 * result + (element == null ? 0 : element.hashCode()); | ||
| 3141 | |||
| 3142 | return result; | ||
| 3143 | } | ||
| 3144 | |||
| 3145 | /** | ||
| 3146 | * Returns a hash code based on the "deep contents" of the specified | ||
| 3147 | * array. If the array contains other arrays as elements, the | ||
| 3148 | * hash code is based on their contents and so on, ad infinitum. | ||
| 3149 | * It is therefore unacceptable to invoke this method on an array that | ||
| 3150 | * contains itself as an element, either directly or indirectly through | ||
| 3151 | * one or more levels of arrays. The behavior of such an invocation is | ||
| 3152 | * undefined. | ||
| 3153 | * | ||
| 3154 | * <p>For any two arrays <tt>a</tt> and <tt>b</tt> such that | ||
| 3155 | * <tt>Arrays.deepEquals(a, b)</tt>, it is also the case that | ||
| 3156 | * <tt>Arrays.deepHashCode(a) == Arrays.deepHashCode(b)</tt>. | ||
| 3157 | * | ||
| 3158 | * <p>The computation of the value returned by this method is similar to | ||
| 3159 | * that of the value returned by {@link List#hashCode()} on a list | ||
| 3160 | * containing the same elements as <tt>a</tt> in the same order, with one | ||
| 3161 | * difference: If an element <tt>e</tt> of <tt>a</tt> is itself an array, | ||
| 3162 | * its hash code is computed not by calling <tt>e.hashCode()</tt>, but as | ||
| 3163 | * by calling the appropriate overloading of <tt>Arrays.hashCode(e)</tt> | ||
| 3164 | * if <tt>e</tt> is an array of a primitive type, or as by calling | ||
| 3165 | * <tt>Arrays.deepHashCode(e)</tt> recursively if <tt>e</tt> is an array | ||
| 3166 | * of a reference type. If <tt>a</tt> is <tt>null</tt>, this method | ||
| 3167 | * returns 0. | ||
| 3168 | * | ||
| 3169 | * @param a the array whose deep-content-based hash code to compute | ||
| 3170 | * @return a deep-content-based hash code for <tt>a</tt> | ||
| 3171 | * @see #hashCode(Object[]) | ||
| 3172 | * @since 1.5 | ||
| 3173 | */ | ||
| 3174 | public static int deepHashCode(Object a[]) { | ||
| 3175 | if (a == null) | ||
| 3176 | return 0; | ||
| 3177 | |||
| 3178 | int result = 1; | ||
| 3179 | |||
| 3180 | for (Object element : a) { | ||
| 3181 | int elementHash = 0; | ||
| 3182 | if (element instanceof Object[]) | ||
| 3183 | elementHash = deepHashCode((Object[]) element); | ||
| 3184 | else if (element instanceof byte[]) | ||
| 3185 | elementHash = hashCode((byte[]) element); | ||
| 3186 | else if (element instanceof short[]) | ||
| 3187 | elementHash = hashCode((short[]) element); | ||
| 3188 | else if (element instanceof int[]) | ||
| 3189 | elementHash = hashCode((int[]) element); | ||
| 3190 | else if (element instanceof long[]) | ||
| 3191 | elementHash = hashCode((long[]) element); | ||
| 3192 | else if (element instanceof char[]) | ||
| 3193 | elementHash = hashCode((char[]) element); | ||
| 3194 | else if (element instanceof float[]) | ||
| 3195 | elementHash = hashCode((float[]) element); | ||
| 3196 | else if (element instanceof double[]) | ||
| 3197 | elementHash = hashCode((double[]) element); | ||
| 3198 | else if (element instanceof boolean[]) | ||
| 3199 | elementHash = hashCode((boolean[]) element); | ||
| 3200 | else if (element != null) | ||
| 3201 | elementHash = element.hashCode(); | ||
| 3202 | |||
| 3203 | result = 31 * result + elementHash; | ||
| 3204 | } | ||
| 3205 | |||
| 3206 | return result; | ||
| 3207 | } | ||
| 3208 | |||
| 3209 | /** | ||
| 3210 | * Returns <tt>true</tt> if the two specified arrays are <i>deeply | ||
| 3211 | * equal</i> to one another. Unlike the {@link #equals(Object[],Object[])} | ||
| 3212 | * method, this method is appropriate for use with nested arrays of | ||
| 3213 | * arbitrary depth. | ||
| 3214 | * | ||
| 3215 | * <p>Two array references are considered deeply equal if both | ||
| 3216 | * are <tt>null</tt>, or if they refer to arrays that contain the same | ||
| 3217 | * number of elements and all corresponding pairs of elements in the two | ||
| 3218 | * arrays are deeply equal. | ||
| 3219 | * | ||
| 3220 | * <p>Two possibly <tt>null</tt> elements <tt>e1</tt> and <tt>e2</tt> are | ||
| 3221 | * deeply equal if any of the following conditions hold: | ||
| 3222 | * <ul> | ||
| 3223 | * <li> <tt>e1</tt> and <tt>e2</tt> are both arrays of object reference | ||
| 3224 | * types, and <tt>Arrays.deepEquals(e1, e2) would return true</tt> | ||
| 3225 | * <li> <tt>e1</tt> and <tt>e2</tt> are arrays of the same primitive | ||
| 3226 | * type, and the appropriate overloading of | ||
| 3227 | * <tt>Arrays.equals(e1, e2)</tt> would return true. | ||
| 3228 | * <li> <tt>e1 == e2</tt> | ||
| 3229 | * <li> <tt>e1.equals(e2)</tt> would return true. | ||
| 3230 | * </ul> | ||
| 3231 | * Note that this definition permits <tt>null</tt> elements at any depth. | ||
| 3232 | * | ||
| 3233 | * <p>If either of the specified arrays contain themselves as elements | ||
| 3234 | * either directly or indirectly through one or more levels of arrays, | ||
| 3235 | * the behavior of this method is undefined. | ||
| 3236 | * | ||
| 3237 | * @param a1 one array to be tested for equality | ||
| 3238 | * @param a2 the other array to be tested for equality | ||
| 3239 | * @return <tt>true</tt> if the two arrays are equal | ||
| 3240 | * @see #equals(Object[],Object[]) | ||
| 3241 | * @see Objects#deepEquals(Object, Object) | ||
| 3242 | * @since 1.5 | ||
| 3243 | */ | ||
| 3244 | public static boolean deepEquals(Object[] a1, Object[] a2) { | ||
| 3245 | if (a1 == a2) | ||
| 3246 | return true; | ||
| 3247 | if (a1 == null || a2==null) | ||
| 3248 | return false; | ||
| 3249 | int length = a1.length; | ||
| 3250 | if (a2.length != length) | ||
| 3251 | return false; | ||
| 3252 | |||
| 3253 | for (int i = 0; i < length; i++) { | ||
| 3254 | Object e1 = a1[i]; | ||
| 3255 | Object e2 = a2[i]; | ||
| 3256 | |||
| 3257 | if (e1 == e2) | ||
| 3258 | continue; | ||
| 3259 | if (e1 == null) | ||
| 3260 | return false; | ||
| 3261 | |||
| 3262 | // Figure out whether the two elements are equal | ||
| 3263 | boolean eq = deepEquals0(e1, e2); | ||
| 3264 | |||
| 3265 | if (!eq) | ||
| 3266 | return false; | ||
| 3267 | } | ||
| 3268 | return true; | ||
| 3269 | } | ||
| 3270 | |||
| 3271 | static boolean deepEquals0(Object e1, Object e2) { | ||
| 3272 | assert e1 != null; | ||
| 3273 | boolean eq; | ||
| 3274 | if (e1 instanceof Object[] && e2 instanceof Object[]) | ||
| 3275 | eq = deepEquals ((Object[]) e1, (Object[]) e2); | ||
| 3276 | else if (e1 instanceof byte[] && e2 instanceof byte[]) | ||
| 3277 | eq = equals((byte[]) e1, (byte[]) e2); | ||
| 3278 | else if (e1 instanceof short[] && e2 instanceof short[]) | ||
| 3279 | eq = equals((short[]) e1, (short[]) e2); | ||
| 3280 | else if (e1 instanceof int[] && e2 instanceof int[]) | ||
| 3281 | eq = equals((int[]) e1, (int[]) e2); | ||
| 3282 | else if (e1 instanceof long[] && e2 instanceof long[]) | ||
| 3283 | eq = equals((long[]) e1, (long[]) e2); | ||
| 3284 | else if (e1 instanceof char[] && e2 instanceof char[]) | ||
| 3285 | eq = equals((char[]) e1, (char[]) e2); | ||
| 3286 | else if (e1 instanceof float[] && e2 instanceof float[]) | ||
| 3287 | eq = equals((float[]) e1, (float[]) e2); | ||
| 3288 | else if (e1 instanceof double[] && e2 instanceof double[]) | ||
| 3289 | eq = equals((double[]) e1, (double[]) e2); | ||
| 3290 | else if (e1 instanceof boolean[] && e2 instanceof boolean[]) | ||
| 3291 | eq = equals((boolean[]) e1, (boolean[]) e2); | ||
| 3292 | else | ||
| 3293 | eq = e1.equals(e2); | ||
| 3294 | return eq; | ||
| 3295 | } | ||
| 3296 | |||
| 3297 | /** | ||
| 3298 | * Returns a string representation of the contents of the specified array. | ||
| 3299 | * The string representation consists of a list of the array's elements, | ||
| 3300 | * enclosed in square brackets (<tt>"[]"</tt>). Adjacent elements are | ||
| 3301 | * separated by the characters <tt>", "</tt> (a comma followed by a | ||
| 3302 | * space). Elements are converted to strings as by | ||
| 3303 | * <tt>String.valueOf(long)</tt>. Returns <tt>"null"</tt> if <tt>a</tt> | ||
| 3304 | * is <tt>null</tt>. | ||
| 3305 | * | ||
| 3306 | * @param a the array whose string representation to return | ||
| 3307 | * @return a string representation of <tt>a</tt> | ||
| 3308 | * @since 1.5 | ||
| 3309 | */ | ||
| 3310 | public static String toString(long[] a) { | ||
| 3311 | if (a == null) | ||
| 3312 | return "null"; | ||
| 3313 | int iMax = a.length - 1; | ||
| 3314 | if (iMax == -1) | ||
| 3315 | return "[]"; | ||
| 3316 | |||
| 3317 | StringBuilder b = new StringBuilder(); | ||
| 3318 | b.append('['); | ||
| 3319 | for (int i = 0; ; i++) { | ||
| 3320 | b.append(a[i]); | ||
| 3321 | if (i == iMax) | ||
| 3322 | return b.append(']').toString(); | ||
| 3323 | b.append(", "); | ||
| 3324 | } | ||
| 3325 | } | ||
| 3326 | |||
| 3327 | /** | ||
| 3328 | * Returns a string representation of the contents of the specified array. | ||
| 3329 | * The string representation consists of a list of the array's elements, | ||
| 3330 | * enclosed in square brackets (<tt>"[]"</tt>). Adjacent elements are | ||
| 3331 | * separated by the characters <tt>", "</tt> (a comma followed by a | ||
| 3332 | * space). Elements are converted to strings as by | ||
| 3333 | * <tt>String.valueOf(int)</tt>. Returns <tt>"null"</tt> if <tt>a</tt> is | ||
| 3334 | * <tt>null</tt>. | ||
| 3335 | * | ||
| 3336 | * @param a the array whose string representation to return | ||
| 3337 | * @return a string representation of <tt>a</tt> | ||
| 3338 | * @since 1.5 | ||
| 3339 | */ | ||
| 3340 | public static String toString(int[] a) { | ||
| 3341 | if (a == null) | ||
| 3342 | return "null"; | ||
| 3343 | int iMax = a.length - 1; | ||
| 3344 | if (iMax == -1) | ||
| 3345 | return "[]"; | ||
| 3346 | |||
| 3347 | StringBuilder b = new StringBuilder(); | ||
| 3348 | b.append('['); | ||
| 3349 | for (int i = 0; ; i++) { | ||
| 3350 | b.append(a[i]); | ||
| 3351 | if (i == iMax) | ||
| 3352 | return b.append(']').toString(); | ||
| 3353 | b.append(", "); | ||
| 3354 | } | ||
| 3355 | } | ||
| 3356 | |||
| 3357 | /** | ||
| 3358 | * Returns a string representation of the contents of the specified array. | ||
| 3359 | * The string representation consists of a list of the array's elements, | ||
| 3360 | * enclosed in square brackets (<tt>"[]"</tt>). Adjacent elements are | ||
| 3361 | * separated by the characters <tt>", "</tt> (a comma followed by a | ||
| 3362 | * space). Elements are converted to strings as by | ||
| 3363 | * <tt>String.valueOf(short)</tt>. Returns <tt>"null"</tt> if <tt>a</tt> | ||
| 3364 | * is <tt>null</tt>. | ||
| 3365 | * | ||
| 3366 | * @param a the array whose string representation to return | ||
| 3367 | * @return a string representation of <tt>a</tt> | ||
| 3368 | * @since 1.5 | ||
| 3369 | */ | ||
| 3370 | public static String toString(short[] a) { | ||
| 3371 | if (a == null) | ||
| 3372 | return "null"; | ||
| 3373 | int iMax = a.length - 1; | ||
| 3374 | if (iMax == -1) | ||
| 3375 | return "[]"; | ||
| 3376 | |||
| 3377 | StringBuilder b = new StringBuilder(); | ||
| 3378 | b.append('['); | ||
| 3379 | for (int i = 0; ; i++) { | ||
| 3380 | b.append(a[i]); | ||
| 3381 | if (i == iMax) | ||
| 3382 | return b.append(']').toString(); | ||
| 3383 | b.append(", "); | ||
| 3384 | } | ||
| 3385 | } | ||
| 3386 | |||
| 3387 | /** | ||
| 3388 | * Returns a string representation of the contents of the specified array. | ||
| 3389 | * The string representation consists of a list of the array's elements, | ||
| 3390 | * enclosed in square brackets (<tt>"[]"</tt>). Adjacent elements are | ||
| 3391 | * separated by the characters <tt>", "</tt> (a comma followed by a | ||
| 3392 | * space). Elements are converted to strings as by | ||
| 3393 | * <tt>String.valueOf(char)</tt>. Returns <tt>"null"</tt> if <tt>a</tt> | ||
| 3394 | * is <tt>null</tt>. | ||
| 3395 | * | ||
| 3396 | * @param a the array whose string representation to return | ||
| 3397 | * @return a string representation of <tt>a</tt> | ||
| 3398 | * @since 1.5 | ||
| 3399 | */ | ||
| 3400 | public static String toString(char[] a) { | ||
| 3401 | if (a == null) | ||
| 3402 | return "null"; | ||
| 3403 | int iMax = a.length - 1; | ||
| 3404 | if (iMax == -1) | ||
| 3405 | return "[]"; | ||
| 3406 | |||
| 3407 | StringBuilder b = new StringBuilder(); | ||
| 3408 | b.append('['); | ||
| 3409 | for (int i = 0; ; i++) { | ||
| 3410 | b.append(a[i]); | ||
| 3411 | if (i == iMax) | ||
| 3412 | return b.append(']').toString(); | ||
| 3413 | b.append(", "); | ||
| 3414 | } | ||
| 3415 | } | ||
| 3416 | |||
| 3417 | /** | ||
| 3418 | * Returns a string representation of the contents of the specified array. | ||
| 3419 | * The string representation consists of a list of the array's elements, | ||
| 3420 | * enclosed in square brackets (<tt>"[]"</tt>). Adjacent elements | ||
| 3421 | * are separated by the characters <tt>", "</tt> (a comma followed | ||
| 3422 | * by a space). Elements are converted to strings as by | ||
| 3423 | * <tt>String.valueOf(byte)</tt>. Returns <tt>"null"</tt> if | ||
| 3424 | * <tt>a</tt> is <tt>null</tt>. | ||
| 3425 | * | ||
| 3426 | * @param a the array whose string representation to return | ||
| 3427 | * @return a string representation of <tt>a</tt> | ||
| 3428 | * @since 1.5 | ||
| 3429 | */ | ||
| 3430 | public static String toString(byte[] a) { | ||
| 3431 | if (a == null) | ||
| 3432 | return "null"; | ||
| 3433 | int iMax = a.length - 1; | ||
| 3434 | if (iMax == -1) | ||
| 3435 | return "[]"; | ||
| 3436 | |||
| 3437 | StringBuilder b = new StringBuilder(); | ||
| 3438 | b.append('['); | ||
| 3439 | for (int i = 0; ; i++) { | ||
| 3440 | b.append(a[i]); | ||
| 3441 | if (i == iMax) | ||
| 3442 | return b.append(']').toString(); | ||
| 3443 | b.append(", "); | ||
| 3444 | } | ||
| 3445 | } | ||
| 3446 | |||
| 3447 | /** | ||
| 3448 | * Returns a string representation of the contents of the specified array. | ||
| 3449 | * The string representation consists of a list of the array's elements, | ||
| 3450 | * enclosed in square brackets (<tt>"[]"</tt>). Adjacent elements are | ||
| 3451 | * separated by the characters <tt>", "</tt> (a comma followed by a | ||
| 3452 | * space). Elements are converted to strings as by | ||
| 3453 | * <tt>String.valueOf(boolean)</tt>. Returns <tt>"null"</tt> if | ||
| 3454 | * <tt>a</tt> is <tt>null</tt>. | ||
| 3455 | * | ||
| 3456 | * @param a the array whose string representation to return | ||
| 3457 | * @return a string representation of <tt>a</tt> | ||
| 3458 | * @since 1.5 | ||
| 3459 | */ | ||
| 3460 | public static String toString(boolean[] a) { | ||
| 3461 | if (a == null) | ||
| 3462 | return "null"; | ||
| 3463 | int iMax = a.length - 1; | ||
| 3464 | if (iMax == -1) | ||
| 3465 | return "[]"; | ||
| 3466 | |||
| 3467 | StringBuilder b = new StringBuilder(); | ||
| 3468 | b.append('['); | ||
| 3469 | for (int i = 0; ; i++) { | ||
| 3470 | b.append(a[i]); | ||
| 3471 | if (i == iMax) | ||
| 3472 | return b.append(']').toString(); | ||
| 3473 | b.append(", "); | ||
| 3474 | } | ||
| 3475 | } | ||
| 3476 | |||
| 3477 | /** | ||
| 3478 | * Returns a string representation of the contents of the specified array. | ||
| 3479 | * The string representation consists of a list of the array's elements, | ||
| 3480 | * enclosed in square brackets (<tt>"[]"</tt>). Adjacent elements are | ||
| 3481 | * separated by the characters <tt>", "</tt> (a comma followed by a | ||
| 3482 | * space). Elements are converted to strings as by | ||
| 3483 | * <tt>String.valueOf(float)</tt>. Returns <tt>"null"</tt> if <tt>a</tt> | ||
| 3484 | * is <tt>null</tt>. | ||
| 3485 | * | ||
| 3486 | * @param a the array whose string representation to return | ||
| 3487 | * @return a string representation of <tt>a</tt> | ||
| 3488 | * @since 1.5 | ||
| 3489 | */ | ||
| 3490 | public static String toString(float[] a) { | ||
| 3491 | if (a == null) | ||
| 3492 | return "null"; | ||
| 3493 | |||
| 3494 | int iMax = a.length - 1; | ||
| 3495 | if (iMax == -1) | ||
| 3496 | return "[]"; | ||
| 3497 | |||
| 3498 | StringBuilder b = new StringBuilder(); | ||
| 3499 | b.append('['); | ||
| 3500 | for (int i = 0; ; i++) { | ||
| 3501 | b.append(a[i]); | ||
| 3502 | if (i == iMax) | ||
| 3503 | return b.append(']').toString(); | ||
| 3504 | b.append(", "); | ||
| 3505 | } | ||
| 3506 | } | ||
| 3507 | |||
| 3508 | /** | ||
| 3509 | * Returns a string representation of the contents of the specified array. | ||
| 3510 | * The string representation consists of a list of the array's elements, | ||
| 3511 | * enclosed in square brackets (<tt>"[]"</tt>). Adjacent elements are | ||
| 3512 | * separated by the characters <tt>", "</tt> (a comma followed by a | ||
| 3513 | * space). Elements are converted to strings as by | ||
| 3514 | * <tt>String.valueOf(double)</tt>. Returns <tt>"null"</tt> if <tt>a</tt> | ||
| 3515 | * is <tt>null</tt>. | ||
| 3516 | * | ||
| 3517 | * @param a the array whose string representation to return | ||
| 3518 | * @return a string representation of <tt>a</tt> | ||
| 3519 | * @since 1.5 | ||
| 3520 | */ | ||
| 3521 | public static String toString(double[] a) { | ||
| 3522 | if (a == null) | ||
| 3523 | return "null"; | ||
| 3524 | int iMax = a.length - 1; | ||
| 3525 | if (iMax == -1) | ||
| 3526 | return "[]"; | ||
| 3527 | |||
| 3528 | StringBuilder b = new StringBuilder(); | ||
| 3529 | b.append('['); | ||
| 3530 | for (int i = 0; ; i++) { | ||
| 3531 | b.append(a[i]); | ||
| 3532 | if (i == iMax) | ||
| 3533 | return b.append(']').toString(); | ||
| 3534 | b.append(", "); | ||
| 3535 | } | ||
| 3536 | } | ||
| 3537 | |||
| 3538 | /** | ||
| 3539 | * Returns a string representation of the contents of the specified array. | ||
| 3540 | * If the array contains other arrays as elements, they are converted to | ||
| 3541 | * strings by the {@link Object#toString} method inherited from | ||
| 3542 | * <tt>Object</tt>, which describes their <i>identities</i> rather than | ||
| 3543 | * their contents. | ||
| 3544 | * | ||
| 3545 | * <p>The value returned by this method is equal to the value that would | ||
| 3546 | * be returned by <tt>Arrays.asList(a).toString()</tt>, unless <tt>a</tt> | ||
| 3547 | * is <tt>null</tt>, in which case <tt>"null"</tt> is returned. | ||
| 3548 | * | ||
| 3549 | * @param a the array whose string representation to return | ||
| 3550 | * @return a string representation of <tt>a</tt> | ||
| 3551 | * @see #deepToString(Object[]) | ||
| 3552 | * @since 1.5 | ||
| 3553 | */ | ||
| 3554 | public static String toString(Object[] a) { | ||
| 3555 | if (a == null) | ||
| 3556 | return "null"; | ||
| 3557 | |||
| 3558 | int iMax = a.length - 1; | ||
| 3559 | if (iMax == -1) | ||
| 3560 | return "[]"; | ||
| 3561 | |||
| 3562 | StringBuilder b = new StringBuilder(); | ||
| 3563 | b.append('['); | ||
| 3564 | for (int i = 0; ; i++) { | ||
| 3565 | b.append(String.valueOf(a[i])); | ||
| 3566 | if (i == iMax) | ||
| 3567 | return b.append(']').toString(); | ||
| 3568 | b.append(", "); | ||
| 3569 | } | ||
| 3570 | } | ||
| 3571 | |||
| 3572 | /** | ||
| 3573 | * Returns a string representation of the "deep contents" of the specified | ||
| 3574 | * array. If the array contains other arrays as elements, the string | ||
| 3575 | * representation contains their contents and so on. This method is | ||
| 3576 | * designed for converting multidimensional arrays to strings. | ||
| 3577 | * | ||
| 3578 | * <p>The string representation consists of a list of the array's | ||
| 3579 | * elements, enclosed in square brackets (<tt>"[]"</tt>). Adjacent | ||
| 3580 | * elements are separated by the characters <tt>", "</tt> (a comma | ||
| 3581 | * followed by a space). Elements are converted to strings as by | ||
| 3582 | * <tt>String.valueOf(Object)</tt>, unless they are themselves | ||
| 3583 | * arrays. | ||
| 3584 | * | ||
| 3585 | * <p>If an element <tt>e</tt> is an array of a primitive type, it is | ||
| 3586 | * converted to a string as by invoking the appropriate overloading of | ||
| 3587 | * <tt>Arrays.toString(e)</tt>. If an element <tt>e</tt> is an array of a | ||
| 3588 | * reference type, it is converted to a string as by invoking | ||
| 3589 | * this method recursively. | ||
| 3590 | * | ||
| 3591 | * <p>To avoid infinite recursion, if the specified array contains itself | ||
| 3592 | * as an element, or contains an indirect reference to itself through one | ||
| 3593 | * or more levels of arrays, the self-reference is converted to the string | ||
| 3594 | * <tt>"[...]"</tt>. For example, an array containing only a reference | ||
| 3595 | * to itself would be rendered as <tt>"[[...]]"</tt>. | ||
| 3596 | * | ||
| 3597 | * <p>This method returns <tt>"null"</tt> if the specified array | ||
| 3598 | * is <tt>null</tt>. | ||
| 3599 | * | ||
| 3600 | * @param a the array whose string representation to return | ||
| 3601 | * @return a string representation of <tt>a</tt> | ||
| 3602 | * @see #toString(Object[]) | ||
| 3603 | * @since 1.5 | ||
| 3604 | */ | ||
| 3605 | public static String deepToString(Object[] a) { | ||
| 3606 | if (a == null) | ||
| 3607 | return "null"; | ||
| 3608 | |||
| 3609 | int bufLen = 20 * a.length; | ||
| 3610 | if (a.length != 0 && bufLen <= 0) | ||
| 3611 | bufLen = Integer.MAX_VALUE; | ||
| 3612 | StringBuilder buf = new StringBuilder(bufLen); | ||
| 3613 | deepToString(a, buf, new HashSet<Object[]>()); | ||
| 3614 | return buf.toString(); | ||
| 3615 | } | ||
| 3616 | |||
| 3617 | private static void deepToString(Object[] a, StringBuilder buf, | ||
| 3618 | Set<Object[]> dejaVu) { | ||
| 3619 | if (a == null) { | ||
| 3620 | buf.append("null"); | ||
| 3621 | return; | ||
| 3622 | } | ||
| 3623 | int iMax = a.length - 1; | ||
| 3624 | if (iMax == -1) { | ||
| 3625 | buf.append("[]"); | ||
| 3626 | return; | ||
| 3627 | } | ||
| 3628 | |||
| 3629 | dejaVu.add(a); | ||
| 3630 | buf.append('['); | ||
| 3631 | for (int i = 0; ; i++) { | ||
| 3632 | |||
| 3633 | Object element = a[i]; | ||
| 3634 | if (element == null) { | ||
| 3635 | buf.append("null"); | ||
| 3636 | } else { | ||
| 3637 | Class eClass = element.getClass(); | ||
| 3638 | |||
| 3639 | if (eClass.isArray()) { | ||
| 3640 | if (eClass == byte[].class) | ||
| 3641 | buf.append(toString((byte[]) element)); | ||
| 3642 | else if (eClass == short[].class) | ||
| 3643 | buf.append(toString((short[]) element)); | ||
| 3644 | else if (eClass == int[].class) | ||
| 3645 | buf.append(toString((int[]) element)); | ||
| 3646 | else if (eClass == long[].class) | ||
| 3647 | buf.append(toString((long[]) element)); | ||
| 3648 | else if (eClass == char[].class) | ||
| 3649 | buf.append(toString((char[]) element)); | ||
| 3650 | else if (eClass == float[].class) | ||
| 3651 | buf.append(toString((float[]) element)); | ||
| 3652 | else if (eClass == double[].class) | ||
| 3653 | buf.append(toString((double[]) element)); | ||
| 3654 | else if (eClass == boolean[].class) | ||
| 3655 | buf.append(toString((boolean[]) element)); | ||
| 3656 | else { // element is an array of object references | ||
| 3657 | if (dejaVu.contains(element)) | ||
| 3658 | buf.append("[...]"); | ||
| 3659 | else | ||
| 3660 | deepToString((Object[])element, buf, dejaVu); | ||
| 3661 | } | ||
| 3662 | } else { // element is non-null and not an array | ||
| 3663 | buf.append(element.toString()); | ||
| 3664 | } | ||
| 3665 | } | ||
| 3666 | if (i == iMax) | ||
| 3667 | break; | ||
| 3668 | buf.append(", "); | ||
| 3669 | } | ||
| 3670 | buf.append(']'); | ||
| 3671 | dejaVu.remove(a); | ||
| 3672 | } | ||
| 3673 | } | ||
Binary file not shown.
| @@ -0,0 +1,1191 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1995, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package java.util; | ||
| 27 | |||
| 28 | import java.io.*; | ||
| 29 | import java.nio.ByteBuffer; | ||
| 30 | import java.nio.ByteOrder; | ||
| 31 | import java.nio.LongBuffer; | ||
| 32 | |||
| 33 | /** | ||
| 34 | * This class implements a vector of bits that grows as needed. Each | ||
| 35 | * component of the bit set has a {@code boolean} value. The | ||
| 36 | * bits of a {@code BitSet} are indexed by nonnegative integers. | ||
| 37 | * Individual indexed bits can be examined, set, or cleared. One | ||
| 38 | * {@code BitSet} may be used to modify the contents of another | ||
| 39 | * {@code BitSet} through logical AND, logical inclusive OR, and | ||
| 40 | * logical exclusive OR operations. | ||
| 41 | * | ||
| 42 | * <p>By default, all bits in the set initially have the value | ||
| 43 | * {@code false}. | ||
| 44 | * | ||
| 45 | * <p>Every bit set has a current size, which is the number of bits | ||
| 46 | * of space currently in use by the bit set. Note that the size is | ||
| 47 | * related to the implementation of a bit set, so it may change with | ||
| 48 | * implementation. The length of a bit set relates to logical length | ||
| 49 | * of a bit set and is defined independently of implementation. | ||
| 50 | * | ||
| 51 | * <p>Unless otherwise noted, passing a null parameter to any of the | ||
| 52 | * methods in a {@code BitSet} will result in a | ||
| 53 | * {@code NullPointerException}. | ||
| 54 | * | ||
| 55 | * <p>A {@code BitSet} is not safe for multithreaded use without | ||
| 56 | * external synchronization. | ||
| 57 | * | ||
| 58 | * @author Arthur van Hoff | ||
| 59 | * @author Michael McCloskey | ||
| 60 | * @author Martin Buchholz | ||
| 61 | * @since JDK1.0 | ||
| 62 | */ | ||
| 63 | public class BitSet implements Cloneable, java.io.Serializable { | ||
| 64 | /* | ||
| 65 | * BitSets are packed into arrays of "words." Currently a word is | ||
| 66 | * a long, which consists of 64 bits, requiring 6 address bits. | ||
| 67 | * The choice of word size is determined purely by performance concerns. | ||
| 68 | */ | ||
| 69 | private final static int ADDRESS_BITS_PER_WORD = 6; | ||
| 70 | private final static int BITS_PER_WORD = 1 << ADDRESS_BITS_PER_WORD; | ||
| 71 | private final static int BIT_INDEX_MASK = BITS_PER_WORD - 1; | ||
| 72 | |||
| 73 | /* Used to shift left or right for a partial word mask */ | ||
| 74 | private static final long WORD_MASK = 0xffffffffffffffffL; | ||
| 75 | |||
| 76 | /** | ||
| 77 | * @serialField bits long[] | ||
| 78 | * | ||
| 79 | * The bits in this BitSet. The ith bit is stored in bits[i/64] at | ||
| 80 | * bit position i % 64 (where bit position 0 refers to the least | ||
| 81 | * significant bit and 63 refers to the most significant bit). | ||
| 82 | */ | ||
| 83 | private static final ObjectStreamField[] serialPersistentFields = { | ||
| 84 | new ObjectStreamField("bits", long[].class), | ||
| 85 | }; | ||
| 86 | |||
| 87 | /** | ||
| 88 | * The internal field corresponding to the serialField "bits". | ||
| 89 | */ | ||
| 90 | private long[] words; | ||
| 91 | |||
| 92 | /** | ||
| 93 | * The number of words in the logical size of this BitSet. | ||
| 94 | */ | ||
| 95 | private transient int wordsInUse = 0; | ||
| 96 | |||
| 97 | /** | ||
| 98 | * Whether the size of "words" is user-specified. If so, we assume | ||
| 99 | * the user knows what he's doing and try harder to preserve it. | ||
| 100 | */ | ||
| 101 | private transient boolean sizeIsSticky = false; | ||
| 102 | |||
| 103 | /* use serialVersionUID from JDK 1.0.2 for interoperability */ | ||
| 104 | private static final long serialVersionUID = 7997698588986878753L; | ||
| 105 | |||
| 106 | /** | ||
| 107 | * Given a bit index, return word index containing it. | ||
| 108 | */ | ||
| 109 | private static int wordIndex(int bitIndex) { | ||
| 110 | return bitIndex >> ADDRESS_BITS_PER_WORD; | ||
| 111 | } | ||
| 112 | |||
| 113 | /** | ||
| 114 | * Every public method must preserve these invariants. | ||
| 115 | */ | ||
| 116 | private void checkInvariants() { | ||
| 117 | assert(wordsInUse == 0 || words[wordsInUse - 1] != 0); | ||
| 118 | assert(wordsInUse >= 0 && wordsInUse <= words.length); | ||
| 119 | assert(wordsInUse == words.length || words[wordsInUse] == 0); | ||
| 120 | } | ||
| 121 | |||
| 122 | /** | ||
| 123 | * Sets the field wordsInUse to the logical size in words of the bit set. | ||
| 124 | * WARNING:This method assumes that the number of words actually in use is | ||
| 125 | * less than or equal to the current value of wordsInUse! | ||
| 126 | */ | ||
| 127 | private void recalculateWordsInUse() { | ||
| 128 | // Traverse the bitset until a used word is found | ||
| 129 | int i; | ||
| 130 | for (i = wordsInUse-1; i >= 0; i--) | ||
| 131 | if (words[i] != 0) | ||
| 132 | break; | ||
| 133 | |||
| 134 | wordsInUse = i+1; // The new logical size | ||
| 135 | } | ||
| 136 | |||
| 137 | /** | ||
| 138 | * Creates a new bit set. All bits are initially {@code false}. | ||
| 139 | */ | ||
| 140 | public BitSet() { | ||
| 141 | initWords(BITS_PER_WORD); | ||
| 142 | sizeIsSticky = false; | ||
| 143 | } | ||
| 144 | |||
| 145 | /** | ||
| 146 | * Creates a bit set whose initial size is large enough to explicitly | ||
| 147 | * represent bits with indices in the range {@code 0} through | ||
| 148 | * {@code nbits-1}. All bits are initially {@code false}. | ||
| 149 | * | ||
| 150 | * @param nbits the initial size of the bit set | ||
| 151 | * @throws NegativeArraySizeException if the specified initial size | ||
| 152 | * is negative | ||
| 153 | */ | ||
| 154 | public BitSet(int nbits) { | ||
| 155 | // nbits can't be negative; size 0 is OK | ||
| 156 | if (nbits < 0) | ||
| 157 | throw new NegativeArraySizeException("nbits < 0: " + nbits); | ||
| 158 | |||
| 159 | initWords(nbits); | ||
| 160 | sizeIsSticky = true; | ||
| 161 | } | ||
| 162 | |||
| 163 | private void initWords(int nbits) { | ||
| 164 | words = new long[wordIndex(nbits-1) + 1]; | ||
| 165 | } | ||
| 166 | |||
| 167 | /** | ||
| 168 | * Creates a bit set using words as the internal representation. | ||
| 169 | * The last word (if there is one) must be non-zero. | ||
| 170 | */ | ||
| 171 | private BitSet(long[] words) { | ||
| 172 | this.words = words; | ||
| 173 | this.wordsInUse = words.length; | ||
| 174 | checkInvariants(); | ||
| 175 | } | ||
| 176 | |||
| 177 | /** | ||
| 178 | * Returns a new bit set containing all the bits in the given long array. | ||
| 179 | * | ||
| 180 | * <p>More precisely, | ||
| 181 | * <br>{@code BitSet.valueOf(longs).get(n) == ((longs[n/64] & (1L<<(n%64))) != 0)} | ||
| 182 | * <br>for all {@code n < 64 * longs.length}. | ||
| 183 | * | ||
| 184 | * <p>This method is equivalent to | ||
| 185 | * {@code BitSet.valueOf(LongBuffer.wrap(longs))}. | ||
| 186 | * | ||
| 187 | * @param longs a long array containing a little-endian representation | ||
| 188 | * of a sequence of bits to be used as the initial bits of the | ||
| 189 | * new bit set | ||
| 190 | * @since 1.7 | ||
| 191 | */ | ||
| 192 | public static BitSet valueOf(long[] longs) { | ||
| 193 | int n; | ||
| 194 | for (n = longs.length; n > 0 && longs[n - 1] == 0; n--) | ||
| 195 | ; | ||
| 196 | return new BitSet(Arrays.copyOf(longs, n)); | ||
| 197 | } | ||
| 198 | |||
| 199 | /** | ||
| 200 | * Returns a new bit set containing all the bits in the given long | ||
| 201 | * buffer between its position and limit. | ||
| 202 | * | ||
| 203 | * <p>More precisely, | ||
| 204 | * <br>{@code BitSet.valueOf(lb).get(n) == ((lb.get(lb.position()+n/64) & (1L<<(n%64))) != 0)} | ||
| 205 | * <br>for all {@code n < 64 * lb.remaining()}. | ||
| 206 | * | ||
| 207 | * <p>The long buffer is not modified by this method, and no | ||
| 208 | * reference to the buffer is retained by the bit set. | ||
| 209 | * | ||
| 210 | * @param lb a long buffer containing a little-endian representation | ||
| 211 | * of a sequence of bits between its position and limit, to be | ||
| 212 | * used as the initial bits of the new bit set | ||
| 213 | * @since 1.7 | ||
| 214 | */ | ||
| 215 | public static BitSet valueOf(LongBuffer lb) { | ||
| 216 | lb = lb.slice(); | ||
| 217 | int n; | ||
| 218 | for (n = lb.remaining(); n > 0 && lb.get(n - 1) == 0; n--) | ||
| 219 | ; | ||
| 220 | long[] words = new long[n]; | ||
| 221 | lb.get(words); | ||
| 222 | return new BitSet(words); | ||
| 223 | } | ||
| 224 | |||
| 225 | /** | ||
| 226 | * Returns a new bit set containing all the bits in the given byte array. | ||
| 227 | * | ||
| 228 | * <p>More precisely, | ||
| 229 | * <br>{@code BitSet.valueOf(bytes).get(n) == ((bytes[n/8] & (1<<(n%8))) != 0)} | ||
| 230 | * <br>for all {@code n < 8 * bytes.length}. | ||
| 231 | * | ||
| 232 | * <p>This method is equivalent to | ||
| 233 | * {@code BitSet.valueOf(ByteBuffer.wrap(bytes))}. | ||
| 234 | * | ||
| 235 | * @param bytes a byte array containing a little-endian | ||
| 236 | * representation of a sequence of bits to be used as the | ||
| 237 | * initial bits of the new bit set | ||
| 238 | * @since 1.7 | ||
| 239 | */ | ||
| 240 | public static BitSet valueOf(byte[] bytes) { | ||
| 241 | return BitSet.valueOf(ByteBuffer.wrap(bytes)); | ||
| 242 | } | ||
| 243 | |||
| 244 | /** | ||
| 245 | * Returns a new bit set containing all the bits in the given byte | ||
| 246 | * buffer between its position and limit. | ||
| 247 | * | ||
| 248 | * <p>More precisely, | ||
| 249 | * <br>{@code BitSet.valueOf(bb).get(n) == ((bb.get(bb.position()+n/8) & (1<<(n%8))) != 0)} | ||
| 250 | * <br>for all {@code n < 8 * bb.remaining()}. | ||
| 251 | * | ||
| 252 | * <p>The byte buffer is not modified by this method, and no | ||
| 253 | * reference to the buffer is retained by the bit set. | ||
| 254 | * | ||
| 255 | * @param bb a byte buffer containing a little-endian representation | ||
| 256 | * of a sequence of bits between its position and limit, to be | ||
| 257 | * used as the initial bits of the new bit set | ||
| 258 | * @since 1.7 | ||
| 259 | */ | ||
| 260 | public static BitSet valueOf(ByteBuffer bb) { | ||
| 261 | bb = bb.slice().order(ByteOrder.LITTLE_ENDIAN); | ||
| 262 | int n; | ||
| 263 | for (n = bb.remaining(); n > 0 && bb.get(n - 1) == 0; n--) | ||
| 264 | ; | ||
| 265 | long[] words = new long[(n + 7) / 8]; | ||
| 266 | bb.limit(n); | ||
| 267 | int i = 0; | ||
| 268 | while (bb.remaining() >= 8) | ||
| 269 | words[i++] = bb.getLong(); | ||
| 270 | for (int remaining = bb.remaining(), j = 0; j < remaining; j++) | ||
| 271 | words[i] |= (bb.get() & 0xffL) << (8 * j); | ||
| 272 | return new BitSet(words); | ||
| 273 | } | ||
| 274 | |||
| 275 | /** | ||
| 276 | * Returns a new byte array containing all the bits in this bit set. | ||
| 277 | * | ||
| 278 | * <p>More precisely, if | ||
| 279 | * <br>{@code byte[] bytes = s.toByteArray();} | ||
| 280 | * <br>then {@code bytes.length == (s.length()+7)/8} and | ||
| 281 | * <br>{@code s.get(n) == ((bytes[n/8] & (1<<(n%8))) != 0)} | ||
| 282 | * <br>for all {@code n < 8 * bytes.length}. | ||
| 283 | * | ||
| 284 | * @return a byte array containing a little-endian representation | ||
| 285 | * of all the bits in this bit set | ||
| 286 | * @since 1.7 | ||
| 287 | */ | ||
| 288 | public byte[] toByteArray() { | ||
| 289 | int n = wordsInUse; | ||
| 290 | if (n == 0) | ||
| 291 | return new byte[0]; | ||
| 292 | int len = 8 * (n-1); | ||
| 293 | for (long x = words[n - 1]; x != 0; x >>>= 8) | ||
| 294 | len++; | ||
| 295 | byte[] bytes = new byte[len]; | ||
| 296 | ByteBuffer bb = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN); | ||
| 297 | for (int i = 0; i < n - 1; i++) | ||
| 298 | bb.putLong(words[i]); | ||
| 299 | for (long x = words[n - 1]; x != 0; x >>>= 8) | ||
| 300 | bb.put((byte) (x & 0xff)); | ||
| 301 | return bytes; | ||
| 302 | } | ||
| 303 | |||
| 304 | /** | ||
| 305 | * Returns a new long array containing all the bits in this bit set. | ||
| 306 | * | ||
| 307 | * <p>More precisely, if | ||
| 308 | * <br>{@code long[] longs = s.toLongArray();} | ||
| 309 | * <br>then {@code longs.length == (s.length()+63)/64} and | ||
| 310 | * <br>{@code s.get(n) == ((longs[n/64] & (1L<<(n%64))) != 0)} | ||
| 311 | * <br>for all {@code n < 64 * longs.length}. | ||
| 312 | * | ||
| 313 | * @return a long array containing a little-endian representation | ||
| 314 | * of all the bits in this bit set | ||
| 315 | * @since 1.7 | ||
| 316 | */ | ||
| 317 | public long[] toLongArray() { | ||
| 318 | return Arrays.copyOf(words, wordsInUse); | ||
| 319 | } | ||
| 320 | |||
| 321 | /** | ||
| 322 | * Ensures that the BitSet can hold enough words. | ||
| 323 | * @param wordsRequired the minimum acceptable number of words. | ||
| 324 | */ | ||
| 325 | private void ensureCapacity(int wordsRequired) { | ||
| 326 | if (words.length < wordsRequired) { | ||
| 327 | // Allocate larger of doubled size or required size | ||
| 328 | int request = Math.max(2 * words.length, wordsRequired); | ||
| 329 | words = Arrays.copyOf(words, request); | ||
| 330 | sizeIsSticky = false; | ||
| 331 | } | ||
| 332 | } | ||
| 333 | |||
| 334 | /** | ||
| 335 | * Ensures that the BitSet can accommodate a given wordIndex, | ||
| 336 | * temporarily violating the invariants. The caller must | ||
| 337 | * restore the invariants before returning to the user, | ||
| 338 | * possibly using recalculateWordsInUse(). | ||
| 339 | * @param wordIndex the index to be accommodated. | ||
| 340 | */ | ||
| 341 | private void expandTo(int wordIndex) { | ||
| 342 | int wordsRequired = wordIndex+1; | ||
| 343 | if (wordsInUse < wordsRequired) { | ||
| 344 | ensureCapacity(wordsRequired); | ||
| 345 | wordsInUse = wordsRequired; | ||
| 346 | } | ||
| 347 | } | ||
| 348 | |||
| 349 | /** | ||
| 350 | * Checks that fromIndex ... toIndex is a valid range of bit indices. | ||
| 351 | */ | ||
| 352 | private static void checkRange(int fromIndex, int toIndex) { | ||
| 353 | if (fromIndex < 0) | ||
| 354 | throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex); | ||
| 355 | if (toIndex < 0) | ||
| 356 | throw new IndexOutOfBoundsException("toIndex < 0: " + toIndex); | ||
| 357 | if (fromIndex > toIndex) | ||
| 358 | throw new IndexOutOfBoundsException("fromIndex: " + fromIndex + | ||
| 359 | " > toIndex: " + toIndex); | ||
| 360 | } | ||
| 361 | |||
| 362 | /** | ||
| 363 | * Sets the bit at the specified index to the complement of its | ||
| 364 | * current value. | ||
| 365 | * | ||
| 366 | * @param bitIndex the index of the bit to flip | ||
| 367 | * @throws IndexOutOfBoundsException if the specified index is negative | ||
| 368 | * @since 1.4 | ||
| 369 | */ | ||
| 370 | public void flip(int bitIndex) { | ||
| 371 | if (bitIndex < 0) | ||
| 372 | throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex); | ||
| 373 | |||
| 374 | int wordIndex = wordIndex(bitIndex); | ||
| 375 | expandTo(wordIndex); | ||
| 376 | |||
| 377 | words[wordIndex] ^= (1L << bitIndex); | ||
| 378 | |||
| 379 | recalculateWordsInUse(); | ||
| 380 | checkInvariants(); | ||
| 381 | } | ||
| 382 | |||
| 383 | /** | ||
| 384 | * Sets each bit from the specified {@code fromIndex} (inclusive) to the | ||
| 385 | * specified {@code toIndex} (exclusive) to the complement of its current | ||
| 386 | * value. | ||
| 387 | * | ||
| 388 | * @param fromIndex index of the first bit to flip | ||
| 389 | * @param toIndex index after the last bit to flip | ||
| 390 | * @throws IndexOutOfBoundsException if {@code fromIndex} is negative, | ||
| 391 | * or {@code toIndex} is negative, or {@code fromIndex} is | ||
| 392 | * larger than {@code toIndex} | ||
| 393 | * @since 1.4 | ||
| 394 | */ | ||
| 395 | public void flip(int fromIndex, int toIndex) { | ||
| 396 | checkRange(fromIndex, toIndex); | ||
| 397 | |||
| 398 | if (fromIndex == toIndex) | ||
| 399 | return; | ||
| 400 | |||
| 401 | int startWordIndex = wordIndex(fromIndex); | ||
| 402 | int endWordIndex = wordIndex(toIndex - 1); | ||
| 403 | expandTo(endWordIndex); | ||
| 404 | |||
| 405 | long firstWordMask = WORD_MASK << fromIndex; | ||
| 406 | long lastWordMask = WORD_MASK >>> -toIndex; | ||
| 407 | if (startWordIndex == endWordIndex) { | ||
| 408 | // Case 1: One word | ||
| 409 | words[startWordIndex] ^= (firstWordMask & lastWordMask); | ||
| 410 | } else { | ||
| 411 | // Case 2: Multiple words | ||
| 412 | // Handle first word | ||
| 413 | words[startWordIndex] ^= firstWordMask; | ||
| 414 | |||
| 415 | // Handle intermediate words, if any | ||
| 416 | for (int i = startWordIndex+1; i < endWordIndex; i++) | ||
| 417 | words[i] ^= WORD_MASK; | ||
| 418 | |||
| 419 | // Handle last word | ||
| 420 | words[endWordIndex] ^= lastWordMask; | ||
| 421 | } | ||
| 422 | |||
| 423 | recalculateWordsInUse(); | ||
| 424 | checkInvariants(); | ||
| 425 | } | ||
| 426 | |||
| 427 | /** | ||
| 428 | * Sets the bit at the specified index to {@code true}. | ||
| 429 | * | ||
| 430 | * @param bitIndex a bit index | ||
| 431 | * @throws IndexOutOfBoundsException if the specified index is negative | ||
| 432 | * @since JDK1.0 | ||
| 433 | */ | ||
| 434 | public void set(int bitIndex) { | ||
| 435 | if (bitIndex < 0) | ||
| 436 | throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex); | ||
| 437 | |||
| 438 | int wordIndex = wordIndex(bitIndex); | ||
| 439 | expandTo(wordIndex); | ||
| 440 | |||
| 441 | words[wordIndex] |= (1L << bitIndex); // Restores invariants | ||
| 442 | |||
| 443 | checkInvariants(); | ||
| 444 | } | ||
| 445 | |||
| 446 | /** | ||
| 447 | * Sets the bit at the specified index to the specified value. | ||
| 448 | * | ||
| 449 | * @param bitIndex a bit index | ||
| 450 | * @param value a boolean value to set | ||
| 451 | * @throws IndexOutOfBoundsException if the specified index is negative | ||
| 452 | * @since 1.4 | ||
| 453 | */ | ||
| 454 | public void set(int bitIndex, boolean value) { | ||
| 455 | if (value) | ||
| 456 | set(bitIndex); | ||
| 457 | else | ||
| 458 | clear(bitIndex); | ||
| 459 | } | ||
| 460 | |||
| 461 | /** | ||
| 462 | * Sets the bits from the specified {@code fromIndex} (inclusive) to the | ||
| 463 | * specified {@code toIndex} (exclusive) to {@code true}. | ||
| 464 | * | ||
| 465 | * @param fromIndex index of the first bit to be set | ||
| 466 | * @param toIndex index after the last bit to be set | ||
| 467 | * @throws IndexOutOfBoundsException if {@code fromIndex} is negative, | ||
| 468 | * or {@code toIndex} is negative, or {@code fromIndex} is | ||
| 469 | * larger than {@code toIndex} | ||
| 470 | * @since 1.4 | ||
| 471 | */ | ||
| 472 | public void set(int fromIndex, int toIndex) { | ||
| 473 | checkRange(fromIndex, toIndex); | ||
| 474 | |||
| 475 | if (fromIndex == toIndex) | ||
| 476 | return; | ||
| 477 | |||
| 478 | // Increase capacity if necessary | ||
| 479 | int startWordIndex = wordIndex(fromIndex); | ||
| 480 | int endWordIndex = wordIndex(toIndex - 1); | ||
| 481 | expandTo(endWordIndex); | ||
| 482 | |||
| 483 | long firstWordMask = WORD_MASK << fromIndex; | ||
| 484 | long lastWordMask = WORD_MASK >>> -toIndex; | ||
| 485 | if (startWordIndex == endWordIndex) { | ||
| 486 | // Case 1: One word | ||
| 487 | words[startWordIndex] |= (firstWordMask & lastWordMask); | ||
| 488 | } else { | ||
| 489 | // Case 2: Multiple words | ||
| 490 | // Handle first word | ||
| 491 | words[startWordIndex] |= firstWordMask; | ||
| 492 | |||
| 493 | // Handle intermediate words, if any | ||
| 494 | for (int i = startWordIndex+1; i < endWordIndex; i++) | ||
| 495 | words[i] = WORD_MASK; | ||
| 496 | |||
| 497 | // Handle last word (restores invariants) | ||
| 498 | words[endWordIndex] |= lastWordMask; | ||
| 499 | } | ||
| 500 | |||
| 501 | checkInvariants(); | ||
| 502 | } | ||
| 503 | |||
| 504 | /** | ||
| 505 | * Sets the bits from the specified {@code fromIndex} (inclusive) to the | ||
| 506 | * specified {@code toIndex} (exclusive) to the specified value. | ||
| 507 | * | ||
| 508 | * @param fromIndex index of the first bit to be set | ||
| 509 | * @param toIndex index after the last bit to be set | ||
| 510 | * @param value value to set the selected bits to | ||
| 511 | * @throws IndexOutOfBoundsException if {@code fromIndex} is negative, | ||
| 512 | * or {@code toIndex} is negative, or {@code fromIndex} is | ||
| 513 | * larger than {@code toIndex} | ||
| 514 | * @since 1.4 | ||
| 515 | */ | ||
| 516 | public void set(int fromIndex, int toIndex, boolean value) { | ||
| 517 | if (value) | ||
| 518 | set(fromIndex, toIndex); | ||
| 519 | else | ||
| 520 | clear(fromIndex, toIndex); | ||
| 521 | } | ||
| 522 | |||
| 523 | /** | ||
| 524 | * Sets the bit specified by the index to {@code false}. | ||
| 525 | * | ||
| 526 | * @param bitIndex the index of the bit to be cleared | ||
| 527 | * @throws IndexOutOfBoundsException if the specified index is negative | ||
| 528 | * @since JDK1.0 | ||
| 529 | */ | ||
| 530 | public void clear(int bitIndex) { | ||
| 531 | if (bitIndex < 0) | ||
| 532 | throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex); | ||
| 533 | |||
| 534 | int wordIndex = wordIndex(bitIndex); | ||
| 535 | if (wordIndex >= wordsInUse) | ||
| 536 | return; | ||
| 537 | |||
| 538 | words[wordIndex] &= ~(1L << bitIndex); | ||
| 539 | |||
| 540 | recalculateWordsInUse(); | ||
| 541 | checkInvariants(); | ||
| 542 | } | ||
| 543 | |||
| 544 | /** | ||
| 545 | * Sets the bits from the specified {@code fromIndex} (inclusive) to the | ||
| 546 | * specified {@code toIndex} (exclusive) to {@code false}. | ||
| 547 | * | ||
| 548 | * @param fromIndex index of the first bit to be cleared | ||
| 549 | * @param toIndex index after the last bit to be cleared | ||
| 550 | * @throws IndexOutOfBoundsException if {@code fromIndex} is negative, | ||
| 551 | * or {@code toIndex} is negative, or {@code fromIndex} is | ||
| 552 | * larger than {@code toIndex} | ||
| 553 | * @since 1.4 | ||
| 554 | */ | ||
| 555 | public void clear(int fromIndex, int toIndex) { | ||
| 556 | checkRange(fromIndex, toIndex); | ||
| 557 | |||
| 558 | if (fromIndex == toIndex) | ||
| 559 | return; | ||
| 560 | |||
| 561 | int startWordIndex = wordIndex(fromIndex); | ||
| 562 | if (startWordIndex >= wordsInUse) | ||
| 563 | return; | ||
| 564 | |||
| 565 | int endWordIndex = wordIndex(toIndex - 1); | ||
| 566 | if (endWordIndex >= wordsInUse) { | ||
| 567 | toIndex = length(); | ||
| 568 | endWordIndex = wordsInUse - 1; | ||
| 569 | } | ||
| 570 | |||
| 571 | long firstWordMask = WORD_MASK << fromIndex; | ||
| 572 | long lastWordMask = WORD_MASK >>> -toIndex; | ||
| 573 | if (startWordIndex == endWordIndex) { | ||
| 574 | // Case 1: One word | ||
| 575 | words[startWordIndex] &= ~(firstWordMask & lastWordMask); | ||
| 576 | } else { | ||
| 577 | // Case 2: Multiple words | ||
| 578 | // Handle first word | ||
| 579 | words[startWordIndex] &= ~firstWordMask; | ||
| 580 | |||
| 581 | // Handle intermediate words, if any | ||
| 582 | for (int i = startWordIndex+1; i < endWordIndex; i++) | ||
| 583 | words[i] = 0; | ||
| 584 | |||
| 585 | // Handle last word | ||
| 586 | words[endWordIndex] &= ~lastWordMask; | ||
| 587 | } | ||
| 588 | |||
| 589 | recalculateWordsInUse(); | ||
| 590 | checkInvariants(); | ||
| 591 | } | ||
| 592 | |||
| 593 | /** | ||
| 594 | * Sets all of the bits in this BitSet to {@code false}. | ||
| 595 | * | ||
| 596 | * @since 1.4 | ||
| 597 | */ | ||
| 598 | public void clear() { | ||
| 599 | while (wordsInUse > 0) | ||
| 600 | words[--wordsInUse] = 0; | ||
| 601 | } | ||
| 602 | |||
| 603 | /** | ||
| 604 | * Returns the value of the bit with the specified index. The value | ||
| 605 | * is {@code true} if the bit with the index {@code bitIndex} | ||
| 606 | * is currently set in this {@code BitSet}; otherwise, the result | ||
| 607 | * is {@code false}. | ||
| 608 | * | ||
| 609 | * @param bitIndex the bit index | ||
| 610 | * @return the value of the bit with the specified index | ||
| 611 | * @throws IndexOutOfBoundsException if the specified index is negative | ||
| 612 | */ | ||
| 613 | public boolean get(int bitIndex) { | ||
| 614 | if (bitIndex < 0) | ||
| 615 | throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex); | ||
| 616 | |||
| 617 | checkInvariants(); | ||
| 618 | |||
| 619 | int wordIndex = wordIndex(bitIndex); | ||
| 620 | return (wordIndex < wordsInUse) | ||
| 621 | && ((words[wordIndex] & (1L << bitIndex)) != 0); | ||
| 622 | } | ||
| 623 | |||
| 624 | /** | ||
| 625 | * Returns a new {@code BitSet} composed of bits from this {@code BitSet} | ||
| 626 | * from {@code fromIndex} (inclusive) to {@code toIndex} (exclusive). | ||
| 627 | * | ||
| 628 | * @param fromIndex index of the first bit to include | ||
| 629 | * @param toIndex index after the last bit to include | ||
| 630 | * @return a new {@code BitSet} from a range of this {@code BitSet} | ||
| 631 | * @throws IndexOutOfBoundsException if {@code fromIndex} is negative, | ||
| 632 | * or {@code toIndex} is negative, or {@code fromIndex} is | ||
| 633 | * larger than {@code toIndex} | ||
| 634 | * @since 1.4 | ||
| 635 | */ | ||
| 636 | public BitSet get(int fromIndex, int toIndex) { | ||
| 637 | checkRange(fromIndex, toIndex); | ||
| 638 | |||
| 639 | checkInvariants(); | ||
| 640 | |||
| 641 | int len = length(); | ||
| 642 | |||
| 643 | // If no set bits in range return empty bitset | ||
| 644 | if (len <= fromIndex || fromIndex == toIndex) | ||
| 645 | return new BitSet(0); | ||
| 646 | |||
| 647 | // An optimization | ||
| 648 | if (toIndex > len) | ||
| 649 | toIndex = len; | ||
| 650 | |||
| 651 | BitSet result = new BitSet(toIndex - fromIndex); | ||
| 652 | int targetWords = wordIndex(toIndex - fromIndex - 1) + 1; | ||
| 653 | int sourceIndex = wordIndex(fromIndex); | ||
| 654 | boolean wordAligned = ((fromIndex & BIT_INDEX_MASK) == 0); | ||
| 655 | |||
| 656 | // Process all words but the last word | ||
| 657 | for (int i = 0; i < targetWords - 1; i++, sourceIndex++) | ||
| 658 | result.words[i] = wordAligned ? words[sourceIndex] : | ||
| 659 | (words[sourceIndex] >>> fromIndex) | | ||
| 660 | (words[sourceIndex+1] << -fromIndex); | ||
| 661 | |||
| 662 | // Process the last word | ||
| 663 | long lastWordMask = WORD_MASK >>> -toIndex; | ||
| 664 | result.words[targetWords - 1] = | ||
| 665 | ((toIndex-1) & BIT_INDEX_MASK) < (fromIndex & BIT_INDEX_MASK) | ||
| 666 | ? /* straddles source words */ | ||
| 667 | ((words[sourceIndex] >>> fromIndex) | | ||
| 668 | (words[sourceIndex+1] & lastWordMask) << -fromIndex) | ||
| 669 | : | ||
| 670 | ((words[sourceIndex] & lastWordMask) >>> fromIndex); | ||
| 671 | |||
| 672 | // Set wordsInUse correctly | ||
| 673 | result.wordsInUse = targetWords; | ||
| 674 | result.recalculateWordsInUse(); | ||
| 675 | result.checkInvariants(); | ||
| 676 | |||
| 677 | return result; | ||
| 678 | } | ||
| 679 | |||
| 680 | /** | ||
| 681 | * Returns the index of the first bit that is set to {@code true} | ||
| 682 | * that occurs on or after the specified starting index. If no such | ||
| 683 | * bit exists then {@code -1} is returned. | ||
| 684 | * | ||
| 685 | * <p>To iterate over the {@code true} bits in a {@code BitSet}, | ||
| 686 | * use the following loop: | ||
| 687 | * | ||
| 688 | * <pre> {@code | ||
| 689 | * for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) { | ||
| 690 | * // operate on index i here | ||
| 691 | * }}</pre> | ||
| 692 | * | ||
| 693 | * @param fromIndex the index to start checking from (inclusive) | ||
| 694 | * @return the index of the next set bit, or {@code -1} if there | ||
| 695 | * is no such bit | ||
| 696 | * @throws IndexOutOfBoundsException if the specified index is negative | ||
| 697 | * @since 1.4 | ||
| 698 | */ | ||
| 699 | public int nextSetBit(int fromIndex) { | ||
| 700 | if (fromIndex < 0) | ||
| 701 | throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex); | ||
| 702 | |||
| 703 | checkInvariants(); | ||
| 704 | |||
| 705 | int u = wordIndex(fromIndex); | ||
| 706 | if (u >= wordsInUse) | ||
| 707 | return -1; | ||
| 708 | |||
| 709 | long word = words[u] & (WORD_MASK << fromIndex); | ||
| 710 | |||
| 711 | while (true) { | ||
| 712 | if (word != 0) | ||
| 713 | return (u * BITS_PER_WORD) + Long.numberOfTrailingZeros(word); | ||
| 714 | if (++u == wordsInUse) | ||
| 715 | return -1; | ||
| 716 | word = words[u]; | ||
| 717 | } | ||
| 718 | } | ||
| 719 | |||
| 720 | /** | ||
| 721 | * Returns the index of the first bit that is set to {@code false} | ||
| 722 | * that occurs on or after the specified starting index. | ||
| 723 | * | ||
| 724 | * @param fromIndex the index to start checking from (inclusive) | ||
| 725 | * @return the index of the next clear bit | ||
| 726 | * @throws IndexOutOfBoundsException if the specified index is negative | ||
| 727 | * @since 1.4 | ||
| 728 | */ | ||
| 729 | public int nextClearBit(int fromIndex) { | ||
| 730 | // Neither spec nor implementation handle bitsets of maximal length. | ||
| 731 | // See 4816253. | ||
| 732 | if (fromIndex < 0) | ||
| 733 | throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex); | ||
| 734 | |||
| 735 | checkInvariants(); | ||
| 736 | |||
| 737 | int u = wordIndex(fromIndex); | ||
| 738 | if (u >= wordsInUse) | ||
| 739 | return fromIndex; | ||
| 740 | |||
| 741 | long word = ~words[u] & (WORD_MASK << fromIndex); | ||
| 742 | |||
| 743 | while (true) { | ||
| 744 | if (word != 0) | ||
| 745 | return (u * BITS_PER_WORD) + Long.numberOfTrailingZeros(word); | ||
| 746 | if (++u == wordsInUse) | ||
| 747 | return wordsInUse * BITS_PER_WORD; | ||
| 748 | word = ~words[u]; | ||
| 749 | } | ||
| 750 | } | ||
| 751 | |||
| 752 | /** | ||
| 753 | * Returns the index of the nearest bit that is set to {@code true} | ||
| 754 | * that occurs on or before the specified starting index. | ||
| 755 | * If no such bit exists, or if {@code -1} is given as the | ||
| 756 | * starting index, then {@code -1} is returned. | ||
| 757 | * | ||
| 758 | * <p>To iterate over the {@code true} bits in a {@code BitSet}, | ||
| 759 | * use the following loop: | ||
| 760 | * | ||
| 761 | * <pre> {@code | ||
| 762 | * for (int i = bs.length(); (i = bs.previousSetBit(i-1)) >= 0; ) { | ||
| 763 | * // operate on index i here | ||
| 764 | * }}</pre> | ||
| 765 | * | ||
| 766 | * @param fromIndex the index to start checking from (inclusive) | ||
| 767 | * @return the index of the previous set bit, or {@code -1} if there | ||
| 768 | * is no such bit | ||
| 769 | * @throws IndexOutOfBoundsException if the specified index is less | ||
| 770 | * than {@code -1} | ||
| 771 | * @since 1.7 | ||
| 772 | */ | ||
| 773 | public int previousSetBit(int fromIndex) { | ||
| 774 | if (fromIndex < 0) { | ||
| 775 | if (fromIndex == -1) | ||
| 776 | return -1; | ||
| 777 | throw new IndexOutOfBoundsException( | ||
| 778 | "fromIndex < -1: " + fromIndex); | ||
| 779 | } | ||
| 780 | |||
| 781 | checkInvariants(); | ||
| 782 | |||
| 783 | int u = wordIndex(fromIndex); | ||
| 784 | if (u >= wordsInUse) | ||
| 785 | return length() - 1; | ||
| 786 | |||
| 787 | long word = words[u] & (WORD_MASK >>> -(fromIndex+1)); | ||
| 788 | |||
| 789 | while (true) { | ||
| 790 | if (word != 0) | ||
| 791 | return (u+1) * BITS_PER_WORD - 1 - Long.numberOfLeadingZeros(word); | ||
| 792 | if (u-- == 0) | ||
| 793 | return -1; | ||
| 794 | word = words[u]; | ||
| 795 | } | ||
| 796 | } | ||
| 797 | |||
| 798 | /** | ||
| 799 | * Returns the index of the nearest bit that is set to {@code false} | ||
| 800 | * that occurs on or before the specified starting index. | ||
| 801 | * If no such bit exists, or if {@code -1} is given as the | ||
| 802 | * starting index, then {@code -1} is returned. | ||
| 803 | * | ||
| 804 | * @param fromIndex the index to start checking from (inclusive) | ||
| 805 | * @return the index of the previous clear bit, or {@code -1} if there | ||
| 806 | * is no such bit | ||
| 807 | * @throws IndexOutOfBoundsException if the specified index is less | ||
| 808 | * than {@code -1} | ||
| 809 | * @since 1.7 | ||
| 810 | */ | ||
| 811 | public int previousClearBit(int fromIndex) { | ||
| 812 | if (fromIndex < 0) { | ||
| 813 | if (fromIndex == -1) | ||
| 814 | return -1; | ||
| 815 | throw new IndexOutOfBoundsException( | ||
| 816 | "fromIndex < -1: " + fromIndex); | ||
| 817 | } | ||
| 818 | |||
| 819 | checkInvariants(); | ||
| 820 | |||
| 821 | int u = wordIndex(fromIndex); | ||
| 822 | if (u >= wordsInUse) | ||
| 823 | return fromIndex; | ||
| 824 | |||
| 825 | long word = ~words[u] & (WORD_MASK >>> -(fromIndex+1)); | ||
| 826 | |||
| 827 | while (true) { | ||
| 828 | if (word != 0) | ||
| 829 | return (u+1) * BITS_PER_WORD -1 - Long.numberOfLeadingZeros(word); | ||
| 830 | if (u-- == 0) | ||
| 831 | return -1; | ||
| 832 | word = ~words[u]; | ||
| 833 | } | ||
| 834 | } | ||
| 835 | |||
| 836 | /** | ||
| 837 | * Returns the "logical size" of this {@code BitSet}: the index of | ||
| 838 | * the highest set bit in the {@code BitSet} plus one. Returns zero | ||
| 839 | * if the {@code BitSet} contains no set bits. | ||
| 840 | * | ||
| 841 | * @return the logical size of this {@code BitSet} | ||
| 842 | * @since 1.2 | ||
| 843 | */ | ||
| 844 | public int length() { | ||
| 845 | if (wordsInUse == 0) | ||
| 846 | return 0; | ||
| 847 | |||
| 848 | return BITS_PER_WORD * (wordsInUse - 1) + | ||
| 849 | (BITS_PER_WORD - Long.numberOfLeadingZeros(words[wordsInUse - 1])); | ||
| 850 | } | ||
| 851 | |||
| 852 | /** | ||
| 853 | * Returns true if this {@code BitSet} contains no bits that are set | ||
| 854 | * to {@code true}. | ||
| 855 | * | ||
| 856 | * @return boolean indicating whether this {@code BitSet} is empty | ||
| 857 | * @since 1.4 | ||
| 858 | */ | ||
| 859 | public boolean isEmpty() { | ||
| 860 | return wordsInUse == 0; | ||
| 861 | } | ||
| 862 | |||
| 863 | /** | ||
| 864 | * Returns true if the specified {@code BitSet} has any bits set to | ||
| 865 | * {@code true} that are also set to {@code true} in this {@code BitSet}. | ||
| 866 | * | ||
| 867 | * @param set {@code BitSet} to intersect with | ||
| 868 | * @return boolean indicating whether this {@code BitSet} intersects | ||
| 869 | * the specified {@code BitSet} | ||
| 870 | * @since 1.4 | ||
| 871 | */ | ||
| 872 | public boolean intersects(BitSet set) { | ||
| 873 | for (int i = Math.min(wordsInUse, set.wordsInUse) - 1; i >= 0; i--) | ||
| 874 | if ((words[i] & set.words[i]) != 0) | ||
| 875 | return true; | ||
| 876 | return false; | ||
| 877 | } | ||
| 878 | |||
| 879 | /** | ||
| 880 | * Returns the number of bits set to {@code true} in this {@code BitSet}. | ||
| 881 | * | ||
| 882 | * @return the number of bits set to {@code true} in this {@code BitSet} | ||
| 883 | * @since 1.4 | ||
| 884 | */ | ||
| 885 | public int cardinality() { | ||
| 886 | int sum = 0; | ||
| 887 | for (int i = 0; i < wordsInUse; i++) | ||
| 888 | sum += Long.bitCount(words[i]); | ||
| 889 | return sum; | ||
| 890 | } | ||
| 891 | |||
| 892 | /** | ||
| 893 | * Performs a logical <b>AND</b> of this target bit set with the | ||
| 894 | * argument bit set. This bit set is modified so that each bit in it | ||
| 895 | * has the value {@code true} if and only if it both initially | ||
| 896 | * had the value {@code true} and the corresponding bit in the | ||
| 897 | * bit set argument also had the value {@code true}. | ||
| 898 | * | ||
| 899 | * @param set a bit set | ||
| 900 | */ | ||
| 901 | public void and(BitSet set) { | ||
| 902 | if (this == set) | ||
| 903 | return; | ||
| 904 | |||
| 905 | while (wordsInUse > set.wordsInUse) | ||
| 906 | words[--wordsInUse] = 0; | ||
| 907 | |||
| 908 | // Perform logical AND on words in common | ||
| 909 | for (int i = 0; i < wordsInUse; i++) | ||
| 910 | words[i] &= set.words[i]; | ||
| 911 | |||
| 912 | recalculateWordsInUse(); | ||
| 913 | checkInvariants(); | ||
| 914 | } | ||
| 915 | |||
| 916 | /** | ||
| 917 | * Performs a logical <b>OR</b> of this bit set with the bit set | ||
| 918 | * argument. This bit set is modified so that a bit in it has the | ||
| 919 | * value {@code true} if and only if it either already had the | ||
| 920 | * value {@code true} or the corresponding bit in the bit set | ||
| 921 | * argument has the value {@code true}. | ||
| 922 | * | ||
| 923 | * @param set a bit set | ||
| 924 | */ | ||
| 925 | public void or(BitSet set) { | ||
| 926 | if (this == set) | ||
| 927 | return; | ||
| 928 | |||
| 929 | int wordsInCommon = Math.min(wordsInUse, set.wordsInUse); | ||
| 930 | |||
| 931 | if (wordsInUse < set.wordsInUse) { | ||
| 932 | ensureCapacity(set.wordsInUse); | ||
| 933 | wordsInUse = set.wordsInUse; | ||
| 934 | } | ||
| 935 | |||
| 936 | // Perform logical OR on words in common | ||
| 937 | for (int i = 0; i < wordsInCommon; i++) | ||
| 938 | words[i] |= set.words[i]; | ||
| 939 | |||
| 940 | // Copy any remaining words | ||
| 941 | if (wordsInCommon < set.wordsInUse) | ||
| 942 | System.arraycopy(set.words, wordsInCommon, | ||
| 943 | words, wordsInCommon, | ||
| 944 | wordsInUse - wordsInCommon); | ||
| 945 | |||
| 946 | // recalculateWordsInUse() is unnecessary | ||
| 947 | checkInvariants(); | ||
| 948 | } | ||
| 949 | |||
| 950 | /** | ||
| 951 | * Performs a logical <b>XOR</b> of this bit set with the bit set | ||
| 952 | * argument. This bit set is modified so that a bit in it has the | ||
| 953 | * value {@code true} if and only if one of the following | ||
| 954 | * statements holds: | ||
| 955 | * <ul> | ||
| 956 | * <li>The bit initially has the value {@code true}, and the | ||
| 957 | * corresponding bit in the argument has the value {@code false}. | ||
| 958 | * <li>The bit initially has the value {@code false}, and the | ||
| 959 | * corresponding bit in the argument has the value {@code true}. | ||
| 960 | * </ul> | ||
| 961 | * | ||
| 962 | * @param set a bit set | ||
| 963 | */ | ||
| 964 | public void xor(BitSet set) { | ||
| 965 | int wordsInCommon = Math.min(wordsInUse, set.wordsInUse); | ||
| 966 | |||
| 967 | if (wordsInUse < set.wordsInUse) { | ||
| 968 | ensureCapacity(set.wordsInUse); | ||
| 969 | wordsInUse = set.wordsInUse; | ||
| 970 | } | ||
| 971 | |||
| 972 | // Perform logical XOR on words in common | ||
| 973 | for (int i = 0; i < wordsInCommon; i++) | ||
| 974 | words[i] ^= set.words[i]; | ||
| 975 | |||
| 976 | // Copy any remaining words | ||
| 977 | if (wordsInCommon < set.wordsInUse) | ||
| 978 | System.arraycopy(set.words, wordsInCommon, | ||
| 979 | words, wordsInCommon, | ||
| 980 | set.wordsInUse - wordsInCommon); | ||
| 981 | |||
| 982 | recalculateWordsInUse(); | ||
| 983 | checkInvariants(); | ||
| 984 | } | ||
| 985 | |||
| 986 | /** | ||
| 987 | * Clears all of the bits in this {@code BitSet} whose corresponding | ||
| 988 | * bit is set in the specified {@code BitSet}. | ||
| 989 | * | ||
| 990 | * @param set the {@code BitSet} with which to mask this | ||
| 991 | * {@code BitSet} | ||
| 992 | * @since 1.2 | ||
| 993 | */ | ||
| 994 | public void andNot(BitSet set) { | ||
| 995 | // Perform logical (a & !b) on words in common | ||
| 996 | for (int i = Math.min(wordsInUse, set.wordsInUse) - 1; i >= 0; i--) | ||
| 997 | words[i] &= ~set.words[i]; | ||
| 998 | |||
| 999 | recalculateWordsInUse(); | ||
| 1000 | checkInvariants(); | ||
| 1001 | } | ||
| 1002 | |||
| 1003 | /** | ||
| 1004 | * Returns the hash code value for this bit set. The hash code depends | ||
| 1005 | * only on which bits are set within this {@code BitSet}. | ||
| 1006 | * | ||
| 1007 | * <p>The hash code is defined to be the result of the following | ||
| 1008 | * calculation: | ||
| 1009 | * <pre> {@code | ||
| 1010 | * public int hashCode() { | ||
| 1011 | * long h = 1234; | ||
| 1012 | * long[] words = toLongArray(); | ||
| 1013 | * for (int i = words.length; --i >= 0; ) | ||
| 1014 | * h ^= words[i] * (i + 1); | ||
| 1015 | * return (int)((h >> 32) ^ h); | ||
| 1016 | * }}</pre> | ||
| 1017 | * Note that the hash code changes if the set of bits is altered. | ||
| 1018 | * | ||
| 1019 | * @return the hash code value for this bit set | ||
| 1020 | */ | ||
| 1021 | public int hashCode() { | ||
| 1022 | long h = 1234; | ||
| 1023 | for (int i = wordsInUse; --i >= 0; ) | ||
| 1024 | h ^= words[i] * (i + 1); | ||
| 1025 | |||
| 1026 | return (int)((h >> 32) ^ h); | ||
| 1027 | } | ||
| 1028 | |||
| 1029 | /** | ||
| 1030 | * Returns the number of bits of space actually in use by this | ||
| 1031 | * {@code BitSet} to represent bit values. | ||
| 1032 | * The maximum element in the set is the size - 1st element. | ||
| 1033 | * | ||
| 1034 | * @return the number of bits currently in this bit set | ||
| 1035 | */ | ||
| 1036 | public int size() { | ||
| 1037 | return words.length * BITS_PER_WORD; | ||
| 1038 | } | ||
| 1039 | |||
| 1040 | /** | ||
| 1041 | * Compares this object against the specified object. | ||
| 1042 | * The result is {@code true} if and only if the argument is | ||
| 1043 | * not {@code null} and is a {@code Bitset} object that has | ||
| 1044 | * exactly the same set of bits set to {@code true} as this bit | ||
| 1045 | * set. That is, for every nonnegative {@code int} index {@code k}, | ||
| 1046 | * <pre>((BitSet)obj).get(k) == this.get(k)</pre> | ||
| 1047 | * must be true. The current sizes of the two bit sets are not compared. | ||
| 1048 | * | ||
| 1049 | * @param obj the object to compare with | ||
| 1050 | * @return {@code true} if the objects are the same; | ||
| 1051 | * {@code false} otherwise | ||
| 1052 | * @see #size() | ||
| 1053 | */ | ||
| 1054 | public boolean equals(Object obj) { | ||
| 1055 | if (!(obj instanceof BitSet)) | ||
| 1056 | return false; | ||
| 1057 | if (this == obj) | ||
| 1058 | return true; | ||
| 1059 | |||
| 1060 | BitSet set = (BitSet) obj; | ||
| 1061 | |||
| 1062 | checkInvariants(); | ||
| 1063 | set.checkInvariants(); | ||
| 1064 | |||
| 1065 | if (wordsInUse != set.wordsInUse) | ||
| 1066 | return false; | ||
| 1067 | |||
| 1068 | // Check words in use by both BitSets | ||
| 1069 | for (int i = 0; i < wordsInUse; i++) | ||
| 1070 | if (words[i] != set.words[i]) | ||
| 1071 | return false; | ||
| 1072 | |||
| 1073 | return true; | ||
| 1074 | } | ||
| 1075 | |||
| 1076 | /** | ||
| 1077 | * Cloning this {@code BitSet} produces a new {@code BitSet} | ||
| 1078 | * that is equal to it. | ||
| 1079 | * The clone of the bit set is another bit set that has exactly the | ||
| 1080 | * same bits set to {@code true} as this bit set. | ||
| 1081 | * | ||
| 1082 | * @return a clone of this bit set | ||
| 1083 | * @see #size() | ||
| 1084 | */ | ||
| 1085 | public Object clone() { | ||
| 1086 | if (! sizeIsSticky) | ||
| 1087 | trimToSize(); | ||
| 1088 | |||
| 1089 | try { | ||
| 1090 | BitSet result = (BitSet) super.clone(); | ||
| 1091 | result.words = words.clone(); | ||
| 1092 | result.checkInvariants(); | ||
| 1093 | return result; | ||
| 1094 | } catch (CloneNotSupportedException e) { | ||
| 1095 | throw new InternalError(); | ||
| 1096 | } | ||
| 1097 | } | ||
| 1098 | |||
| 1099 | /** | ||
| 1100 | * Attempts to reduce internal storage used for the bits in this bit set. | ||
| 1101 | * Calling this method may, but is not required to, affect the value | ||
| 1102 | * returned by a subsequent call to the {@link #size()} method. | ||
| 1103 | */ | ||
| 1104 | private void trimToSize() { | ||
| 1105 | if (wordsInUse != words.length) { | ||
| 1106 | words = Arrays.copyOf(words, wordsInUse); | ||
| 1107 | checkInvariants(); | ||
| 1108 | } | ||
| 1109 | } | ||
| 1110 | |||
| 1111 | /** | ||
| 1112 | * Save the state of the {@code BitSet} instance to a stream (i.e., | ||
| 1113 | * serialize it). | ||
| 1114 | */ | ||
| 1115 | private void writeObject(ObjectOutputStream s) | ||
| 1116 | throws IOException { | ||
| 1117 | |||
| 1118 | checkInvariants(); | ||
| 1119 | |||
| 1120 | if (! sizeIsSticky) | ||
| 1121 | trimToSize(); | ||
| 1122 | |||
| 1123 | ObjectOutputStream.PutField fields = s.putFields(); | ||
| 1124 | fields.put("bits", words); | ||
| 1125 | s.writeFields(); | ||
| 1126 | } | ||
| 1127 | |||
| 1128 | /** | ||
| 1129 | * Reconstitute the {@code BitSet} instance from a stream (i.e., | ||
| 1130 | * deserialize it). | ||
| 1131 | */ | ||
| 1132 | private void readObject(ObjectInputStream s) | ||
| 1133 | throws IOException, ClassNotFoundException { | ||
| 1134 | |||
| 1135 | ObjectInputStream.GetField fields = s.readFields(); | ||
| 1136 | words = (long[]) fields.get("bits", null); | ||
| 1137 | |||
| 1138 | // Assume maximum length then find real length | ||
| 1139 | // because recalculateWordsInUse assumes maintenance | ||
| 1140 | // or reduction in logical size | ||
| 1141 | wordsInUse = words.length; | ||
| 1142 | recalculateWordsInUse(); | ||
| 1143 | sizeIsSticky = (words.length > 0 && words[words.length-1] == 0L); // heuristic | ||
| 1144 | checkInvariants(); | ||
| 1145 | } | ||
| 1146 | |||
| 1147 | /** | ||
| 1148 | * Returns a string representation of this bit set. For every index | ||
| 1149 | * for which this {@code BitSet} contains a bit in the set | ||
| 1150 | * state, the decimal representation of that index is included in | ||
| 1151 | * the result. Such indices are listed in order from lowest to | ||
| 1152 | * highest, separated by ", " (a comma and a space) and | ||
| 1153 | * surrounded by braces, resulting in the usual mathematical | ||
| 1154 | * notation for a set of integers. | ||
| 1155 | * | ||
| 1156 | * <p>Example: | ||
| 1157 | * <pre> | ||
| 1158 | * BitSet drPepper = new BitSet();</pre> | ||
| 1159 | * Now {@code drPepper.toString()} returns "{@code {}}".<p> | ||
| 1160 | * <pre> | ||
| 1161 | * drPepper.set(2);</pre> | ||
| 1162 | * Now {@code drPepper.toString()} returns "{@code {2}}".<p> | ||
| 1163 | * <pre> | ||
| 1164 | * drPepper.set(4); | ||
| 1165 | * drPepper.set(10);</pre> | ||
| 1166 | * Now {@code drPepper.toString()} returns "{@code {2, 4, 10}}". | ||
| 1167 | * | ||
| 1168 | * @return a string representation of this bit set | ||
| 1169 | */ | ||
| 1170 | public String toString() { | ||
| 1171 | checkInvariants(); | ||
| 1172 | |||
| 1173 | int numBits = (wordsInUse > 128) ? | ||
| 1174 | cardinality() : wordsInUse * BITS_PER_WORD; | ||
| 1175 | StringBuilder b = new StringBuilder(6*numBits + 2); | ||
| 1176 | b.append('{'); | ||
| 1177 | |||
| 1178 | int i = nextSetBit(0); | ||
| 1179 | if (i != -1) { | ||
| 1180 | b.append(i); | ||
| 1181 | for (i = nextSetBit(i+1); i >= 0; i = nextSetBit(i+1)) { | ||
| 1182 | int endOfRun = nextClearBit(i); | ||
| 1183 | do { b.append(", ").append(i); } | ||
| 1184 | while (++i < endOfRun); | ||
| 1185 | } | ||
| 1186 | } | ||
| 1187 | |||
| 1188 | b.append('}'); | ||
| 1189 | return b.toString(); | ||
| 1190 | } | ||
| 1191 | } | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,2824 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | /* | ||
| 27 | * (C) Copyright Taligent, Inc. 1996-1998 - All Rights Reserved | ||
| 28 | * (C) Copyright IBM Corp. 1996-1998 - All Rights Reserved | ||
| 29 | * | ||
| 30 | * The original version of this source code and documentation is copyrighted | ||
| 31 | * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These | ||
| 32 | * materials are provided under terms of a License Agreement between Taligent | ||
| 33 | * and Sun. This technology is protected by multiple US and International | ||
| 34 | * patents. This notice and attribution to Taligent may not be removed. | ||
| 35 | * Taligent is a registered trademark of Taligent, Inc. | ||
| 36 | * | ||
| 37 | */ | ||
| 38 | |||
| 39 | package java.util; | ||
| 40 | |||
| 41 | import java.io.IOException; | ||
| 42 | import java.io.ObjectInputStream; | ||
| 43 | import java.io.ObjectOutputStream; | ||
| 44 | import java.io.OptionalDataException; | ||
| 45 | import java.io.Serializable; | ||
| 46 | import java.security.AccessControlContext; | ||
| 47 | import java.security.AccessController; | ||
| 48 | import java.security.PermissionCollection; | ||
| 49 | import java.security.PrivilegedActionException; | ||
| 50 | import java.security.PrivilegedExceptionAction; | ||
| 51 | import java.security.ProtectionDomain; | ||
| 52 | import java.text.DateFormat; | ||
| 53 | import java.text.DateFormatSymbols; | ||
| 54 | import java.util.concurrent.ConcurrentHashMap; | ||
| 55 | import java.util.concurrent.ConcurrentMap; | ||
| 56 | import sun.util.BuddhistCalendar; | ||
| 57 | import sun.util.calendar.ZoneInfo; | ||
| 58 | import sun.util.resources.LocaleData; | ||
| 59 | |||
| 60 | /** | ||
| 61 | * The <code>Calendar</code> class is an abstract class that provides methods | ||
| 62 | * for converting between a specific instant in time and a set of {@link | ||
| 63 | * #fields calendar fields} such as <code>YEAR</code>, <code>MONTH</code>, | ||
| 64 | * <code>DAY_OF_MONTH</code>, <code>HOUR</code>, and so on, and for | ||
| 65 | * manipulating the calendar fields, such as getting the date of the next | ||
| 66 | * week. An instant in time can be represented by a millisecond value that is | ||
| 67 | * an offset from the <a name="Epoch"><em>Epoch</em></a>, January 1, 1970 | ||
| 68 | * 00:00:00.000 GMT (Gregorian). | ||
| 69 | * | ||
| 70 | * <p>The class also provides additional fields and methods for | ||
| 71 | * implementing a concrete calendar system outside the package. Those | ||
| 72 | * fields and methods are defined as <code>protected</code>. | ||
| 73 | * | ||
| 74 | * <p> | ||
| 75 | * Like other locale-sensitive classes, <code>Calendar</code> provides a | ||
| 76 | * class method, <code>getInstance</code>, for getting a generally useful | ||
| 77 | * object of this type. <code>Calendar</code>'s <code>getInstance</code> method | ||
| 78 | * returns a <code>Calendar</code> object whose | ||
| 79 | * calendar fields have been initialized with the current date and time: | ||
| 80 | * <blockquote> | ||
| 81 | * <pre> | ||
| 82 | * Calendar rightNow = Calendar.getInstance(); | ||
| 83 | * </pre> | ||
| 84 | * </blockquote> | ||
| 85 | * | ||
| 86 | * <p>A <code>Calendar</code> object can produce all the calendar field values | ||
| 87 | * needed to implement the date-time formatting for a particular language and | ||
| 88 | * calendar style (for example, Japanese-Gregorian, Japanese-Traditional). | ||
| 89 | * <code>Calendar</code> defines the range of values returned by | ||
| 90 | * certain calendar fields, as well as their meaning. For example, | ||
| 91 | * the first month of the calendar system has value <code>MONTH == | ||
| 92 | * JANUARY</code> for all calendars. Other values are defined by the | ||
| 93 | * concrete subclass, such as <code>ERA</code>. See individual field | ||
| 94 | * documentation and subclass documentation for details. | ||
| 95 | * | ||
| 96 | * <h4>Getting and Setting Calendar Field Values</h4> | ||
| 97 | * | ||
| 98 | * <p>The calendar field values can be set by calling the <code>set</code> | ||
| 99 | * methods. Any field values set in a <code>Calendar</code> will not be | ||
| 100 | * interpreted until it needs to calculate its time value (milliseconds from | ||
| 101 | * the Epoch) or values of the calendar fields. Calling the | ||
| 102 | * <code>get</code>, <code>getTimeInMillis</code>, <code>getTime</code>, | ||
| 103 | * <code>add</code> and <code>roll</code> involves such calculation. | ||
| 104 | * | ||
| 105 | * <h4>Leniency</h4> | ||
| 106 | * | ||
| 107 | * <p><code>Calendar</code> has two modes for interpreting the calendar | ||
| 108 | * fields, <em>lenient</em> and <em>non-lenient</em>. When a | ||
| 109 | * <code>Calendar</code> is in lenient mode, it accepts a wider range of | ||
| 110 | * calendar field values than it produces. When a <code>Calendar</code> | ||
| 111 | * recomputes calendar field values for return by <code>get()</code>, all of | ||
| 112 | * the calendar fields are normalized. For example, a lenient | ||
| 113 | * <code>GregorianCalendar</code> interprets <code>MONTH == JANUARY</code>, | ||
| 114 | * <code>DAY_OF_MONTH == 32</code> as February 1. | ||
| 115 | |||
| 116 | * <p>When a <code>Calendar</code> is in non-lenient mode, it throws an | ||
| 117 | * exception if there is any inconsistency in its calendar fields. For | ||
| 118 | * example, a <code>GregorianCalendar</code> always produces | ||
| 119 | * <code>DAY_OF_MONTH</code> values between 1 and the length of the month. A | ||
| 120 | * non-lenient <code>GregorianCalendar</code> throws an exception upon | ||
| 121 | * calculating its time or calendar field values if any out-of-range field | ||
| 122 | * value has been set. | ||
| 123 | * | ||
| 124 | * <h4><a name="first_week">First Week</a></h4> | ||
| 125 | * | ||
| 126 | * <code>Calendar</code> defines a locale-specific seven day week using two | ||
| 127 | * parameters: the first day of the week and the minimal days in first week | ||
| 128 | * (from 1 to 7). These numbers are taken from the locale resource data when a | ||
| 129 | * <code>Calendar</code> is constructed. They may also be specified explicitly | ||
| 130 | * through the methods for setting their values. | ||
| 131 | * | ||
| 132 | * <p>When setting or getting the <code>WEEK_OF_MONTH</code> or | ||
| 133 | * <code>WEEK_OF_YEAR</code> fields, <code>Calendar</code> must determine the | ||
| 134 | * first week of the month or year as a reference point. The first week of a | ||
| 135 | * month or year is defined as the earliest seven day period beginning on | ||
| 136 | * <code>getFirstDayOfWeek()</code> and containing at least | ||
| 137 | * <code>getMinimalDaysInFirstWeek()</code> days of that month or year. Weeks | ||
| 138 | * numbered ..., -1, 0 precede the first week; weeks numbered 2, 3,... follow | ||
| 139 | * it. Note that the normalized numbering returned by <code>get()</code> may be | ||
| 140 | * different. For example, a specific <code>Calendar</code> subclass may | ||
| 141 | * designate the week before week 1 of a year as week <code><i>n</i></code> of | ||
| 142 | * the previous year. | ||
| 143 | * | ||
| 144 | * <h4>Calendar Fields Resolution</h4> | ||
| 145 | * | ||
| 146 | * When computing a date and time from the calendar fields, there | ||
| 147 | * may be insufficient information for the computation (such as only | ||
| 148 | * year and month with no day of month), or there may be inconsistent | ||
| 149 | * information (such as Tuesday, July 15, 1996 (Gregorian) -- July 15, | ||
| 150 | * 1996 is actually a Monday). <code>Calendar</code> will resolve | ||
| 151 | * calendar field values to determine the date and time in the | ||
| 152 | * following way. | ||
| 153 | * | ||
| 154 | * <p>If there is any conflict in calendar field values, | ||
| 155 | * <code>Calendar</code> gives priorities to calendar fields that have been set | ||
| 156 | * more recently. The following are the default combinations of the | ||
| 157 | * calendar fields. The most recent combination, as determined by the | ||
| 158 | * most recently set single field, will be used. | ||
| 159 | * | ||
| 160 | * <p><a name="date_resolution">For the date fields</a>: | ||
| 161 | * <blockquote> | ||
| 162 | * <pre> | ||
| 163 | * YEAR + MONTH + DAY_OF_MONTH | ||
| 164 | * YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK | ||
| 165 | * YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK | ||
| 166 | * YEAR + DAY_OF_YEAR | ||
| 167 | * YEAR + DAY_OF_WEEK + WEEK_OF_YEAR | ||
| 168 | * </pre></blockquote> | ||
| 169 | * | ||
| 170 | * <a name="time_resolution">For the time of day fields</a>: | ||
| 171 | * <blockquote> | ||
| 172 | * <pre> | ||
| 173 | * HOUR_OF_DAY | ||
| 174 | * AM_PM + HOUR | ||
| 175 | * </pre></blockquote> | ||
| 176 | * | ||
| 177 | * <p>If there are any calendar fields whose values haven't been set in the selected | ||
| 178 | * field combination, <code>Calendar</code> uses their default values. The default | ||
| 179 | * value of each field may vary by concrete calendar systems. For example, in | ||
| 180 | * <code>GregorianCalendar</code>, the default of a field is the same as that | ||
| 181 | * of the start of the Epoch: i.e., <code>YEAR = 1970</code>, <code>MONTH = | ||
| 182 | * JANUARY</code>, <code>DAY_OF_MONTH = 1</code>, etc. | ||
| 183 | * | ||
| 184 | * <p> | ||
| 185 | * <strong>Note:</strong> There are certain possible ambiguities in | ||
| 186 | * interpretation of certain singular times, which are resolved in the | ||
| 187 | * following ways: | ||
| 188 | * <ol> | ||
| 189 | * <li> 23:59 is the last minute of the day and 00:00 is the first | ||
| 190 | * minute of the next day. Thus, 23:59 on Dec 31, 1999 < 00:00 on | ||
| 191 | * Jan 1, 2000 < 00:01 on Jan 1, 2000. | ||
| 192 | * | ||
| 193 | * <li> Although historically not precise, midnight also belongs to "am", | ||
| 194 | * and noon belongs to "pm", so on the same day, | ||
| 195 | * 12:00 am (midnight) < 12:01 am, and 12:00 pm (noon) < 12:01 pm | ||
| 196 | * </ol> | ||
| 197 | * | ||
| 198 | * <p> | ||
| 199 | * The date or time format strings are not part of the definition of a | ||
| 200 | * calendar, as those must be modifiable or overridable by the user at | ||
| 201 | * runtime. Use {@link DateFormat} | ||
| 202 | * to format dates. | ||
| 203 | * | ||
| 204 | * <h4>Field Manipulation</h4> | ||
| 205 | * | ||
| 206 | * The calendar fields can be changed using three methods: | ||
| 207 | * <code>set()</code>, <code>add()</code>, and <code>roll()</code>.</p> | ||
| 208 | * | ||
| 209 | * <p><strong><code>set(f, value)</code></strong> changes calendar field | ||
| 210 | * <code>f</code> to <code>value</code>. In addition, it sets an | ||
| 211 | * internal member variable to indicate that calendar field <code>f</code> has | ||
| 212 | * been changed. Although calendar field <code>f</code> is changed immediately, | ||
| 213 | * the calendar's time value in milliseconds is not recomputed until the next call to | ||
| 214 | * <code>get()</code>, <code>getTime()</code>, <code>getTimeInMillis()</code>, | ||
| 215 | * <code>add()</code>, or <code>roll()</code> is made. Thus, multiple calls to | ||
| 216 | * <code>set()</code> do not trigger multiple, unnecessary | ||
| 217 | * computations. As a result of changing a calendar field using | ||
| 218 | * <code>set()</code>, other calendar fields may also change, depending on the | ||
| 219 | * calendar field, the calendar field value, and the calendar system. In addition, | ||
| 220 | * <code>get(f)</code> will not necessarily return <code>value</code> set by | ||
| 221 | * the call to the <code>set</code> method | ||
| 222 | * after the calendar fields have been recomputed. The specifics are determined by | ||
| 223 | * the concrete calendar class.</p> | ||
| 224 | * | ||
| 225 | * <p><em>Example</em>: Consider a <code>GregorianCalendar</code> | ||
| 226 | * originally set to August 31, 1999. Calling <code>set(Calendar.MONTH, | ||
| 227 | * Calendar.SEPTEMBER)</code> sets the date to September 31, | ||
| 228 | * 1999. This is a temporary internal representation that resolves to | ||
| 229 | * October 1, 1999 if <code>getTime()</code>is then called. However, a | ||
| 230 | * call to <code>set(Calendar.DAY_OF_MONTH, 30)</code> before the call to | ||
| 231 | * <code>getTime()</code> sets the date to September 30, 1999, since | ||
| 232 | * no recomputation occurs after <code>set()</code> itself.</p> | ||
| 233 | * | ||
| 234 | * <p><strong><code>add(f, delta)</code></strong> adds <code>delta</code> | ||
| 235 | * to field <code>f</code>. This is equivalent to calling <code>set(f, | ||
| 236 | * get(f) + delta)</code> with two adjustments:</p> | ||
| 237 | * | ||
| 238 | * <blockquote> | ||
| 239 | * <p><strong>Add rule 1</strong>. The value of field <code>f</code> | ||
| 240 | * after the call minus the value of field <code>f</code> before the | ||
| 241 | * call is <code>delta</code>, modulo any overflow that has occurred in | ||
| 242 | * field <code>f</code>. Overflow occurs when a field value exceeds its | ||
| 243 | * range and, as a result, the next larger field is incremented or | ||
| 244 | * decremented and the field value is adjusted back into its range.</p> | ||
| 245 | * | ||
| 246 | * <p><strong>Add rule 2</strong>. If a smaller field is expected to be | ||
| 247 | * invariant, but it is impossible for it to be equal to its | ||
| 248 | * prior value because of changes in its minimum or maximum after field | ||
| 249 | * <code>f</code> is changed or other constraints, such as time zone | ||
| 250 | * offset changes, then its value is adjusted to be as close | ||
| 251 | * as possible to its expected value. A smaller field represents a | ||
| 252 | * smaller unit of time. <code>HOUR</code> is a smaller field than | ||
| 253 | * <code>DAY_OF_MONTH</code>. No adjustment is made to smaller fields | ||
| 254 | * that are not expected to be invariant. The calendar system | ||
| 255 | * determines what fields are expected to be invariant.</p> | ||
| 256 | * </blockquote> | ||
| 257 | * | ||
| 258 | * <p>In addition, unlike <code>set()</code>, <code>add()</code> forces | ||
| 259 | * an immediate recomputation of the calendar's milliseconds and all | ||
| 260 | * fields.</p> | ||
| 261 | * | ||
| 262 | * <p><em>Example</em>: Consider a <code>GregorianCalendar</code> | ||
| 263 | * originally set to August 31, 1999. Calling <code>add(Calendar.MONTH, | ||
| 264 | * 13)</code> sets the calendar to September 30, 2000. <strong>Add rule | ||
| 265 | * 1</strong> sets the <code>MONTH</code> field to September, since | ||
| 266 | * adding 13 months to August gives September of the next year. Since | ||
| 267 | * <code>DAY_OF_MONTH</code> cannot be 31 in September in a | ||
| 268 | * <code>GregorianCalendar</code>, <strong>add rule 2</strong> sets the | ||
| 269 | * <code>DAY_OF_MONTH</code> to 30, the closest possible value. Although | ||
| 270 | * it is a smaller field, <code>DAY_OF_WEEK</code> is not adjusted by | ||
| 271 | * rule 2, since it is expected to change when the month changes in a | ||
| 272 | * <code>GregorianCalendar</code>.</p> | ||
| 273 | * | ||
| 274 | * <p><strong><code>roll(f, delta)</code></strong> adds | ||
| 275 | * <code>delta</code> to field <code>f</code> without changing larger | ||
| 276 | * fields. This is equivalent to calling <code>add(f, delta)</code> with | ||
| 277 | * the following adjustment:</p> | ||
| 278 | * | ||
| 279 | * <blockquote> | ||
| 280 | * <p><strong>Roll rule</strong>. Larger fields are unchanged after the | ||
| 281 | * call. A larger field represents a larger unit of | ||
| 282 | * time. <code>DAY_OF_MONTH</code> is a larger field than | ||
| 283 | * <code>HOUR</code>.</p> | ||
| 284 | * </blockquote> | ||
| 285 | * | ||
| 286 | * <p><em>Example</em>: See {@link java.util.GregorianCalendar#roll(int, int)}. | ||
| 287 | * | ||
| 288 | * <p><strong>Usage model</strong>. To motivate the behavior of | ||
| 289 | * <code>add()</code> and <code>roll()</code>, consider a user interface | ||
| 290 | * component with increment and decrement buttons for the month, day, and | ||
| 291 | * year, and an underlying <code>GregorianCalendar</code>. If the | ||
| 292 | * interface reads January 31, 1999 and the user presses the month | ||
| 293 | * increment button, what should it read? If the underlying | ||
| 294 | * implementation uses <code>set()</code>, it might read March 3, 1999. A | ||
| 295 | * better result would be February 28, 1999. Furthermore, if the user | ||
| 296 | * presses the month increment button again, it should read March 31, | ||
| 297 | * 1999, not March 28, 1999. By saving the original date and using either | ||
| 298 | * <code>add()</code> or <code>roll()</code>, depending on whether larger | ||
| 299 | * fields should be affected, the user interface can behave as most users | ||
| 300 | * will intuitively expect.</p> | ||
| 301 | * | ||
| 302 | * @see java.lang.System#currentTimeMillis() | ||
| 303 | * @see Date | ||
| 304 | * @see GregorianCalendar | ||
| 305 | * @see TimeZone | ||
| 306 | * @see java.text.DateFormat | ||
| 307 | * @author Mark Davis, David Goldsmith, Chen-Lieh Huang, Alan Liu | ||
| 308 | * @since JDK1.1 | ||
| 309 | */ | ||
| 310 | public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar> { | ||
| 311 | |||
| 312 | // Data flow in Calendar | ||
| 313 | // --------------------- | ||
| 314 | |||
| 315 | // The current time is represented in two ways by Calendar: as UTC | ||
| 316 | // milliseconds from the epoch (1 January 1970 0:00 UTC), and as local | ||
| 317 | // fields such as MONTH, HOUR, AM_PM, etc. It is possible to compute the | ||
| 318 | // millis from the fields, and vice versa. The data needed to do this | ||
| 319 | // conversion is encapsulated by a TimeZone object owned by the Calendar. | ||
| 320 | // The data provided by the TimeZone object may also be overridden if the | ||
| 321 | // user sets the ZONE_OFFSET and/or DST_OFFSET fields directly. The class | ||
| 322 | // keeps track of what information was most recently set by the caller, and | ||
| 323 | // uses that to compute any other information as needed. | ||
| 324 | |||
| 325 | // If the user sets the fields using set(), the data flow is as follows. | ||
| 326 | // This is implemented by the Calendar subclass's computeTime() method. | ||
| 327 | // During this process, certain fields may be ignored. The disambiguation | ||
| 328 | // algorithm for resolving which fields to pay attention to is described | ||
| 329 | // in the class documentation. | ||
| 330 | |||
| 331 | // local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.) | ||
| 332 | // | | ||
| 333 | // | Using Calendar-specific algorithm | ||
| 334 | // V | ||
| 335 | // local standard millis | ||
| 336 | // | | ||
| 337 | // | Using TimeZone or user-set ZONE_OFFSET / DST_OFFSET | ||
| 338 | // V | ||
| 339 | // UTC millis (in time data member) | ||
| 340 | |||
| 341 | // If the user sets the UTC millis using setTime() or setTimeInMillis(), | ||
| 342 | // the data flow is as follows. This is implemented by the Calendar | ||
| 343 | // subclass's computeFields() method. | ||
| 344 | |||
| 345 | // UTC millis (in time data member) | ||
| 346 | // | | ||
| 347 | // | Using TimeZone getOffset() | ||
| 348 | // V | ||
| 349 | // local standard millis | ||
| 350 | // | | ||
| 351 | // | Using Calendar-specific algorithm | ||
| 352 | // V | ||
| 353 | // local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.) | ||
| 354 | |||
| 355 | // In general, a round trip from fields, through local and UTC millis, and | ||
| 356 | // back out to fields is made when necessary. This is implemented by the | ||
| 357 | // complete() method. Resolving a partial set of fields into a UTC millis | ||
| 358 | // value allows all remaining fields to be generated from that value. If | ||
| 359 | // the Calendar is lenient, the fields are also renormalized to standard | ||
| 360 | // ranges when they are regenerated. | ||
| 361 | |||
| 362 | /** | ||
| 363 | * Field number for <code>get</code> and <code>set</code> indicating the | ||
| 364 | * era, e.g., AD or BC in the Julian calendar. This is a calendar-specific | ||
| 365 | * value; see subclass documentation. | ||
| 366 | * | ||
| 367 | * @see GregorianCalendar#AD | ||
| 368 | * @see GregorianCalendar#BC | ||
| 369 | */ | ||
| 370 | public final static int ERA = 0; | ||
| 371 | |||
| 372 | /** | ||
| 373 | * Field number for <code>get</code> and <code>set</code> indicating the | ||
| 374 | * year. This is a calendar-specific value; see subclass documentation. | ||
| 375 | */ | ||
| 376 | public final static int YEAR = 1; | ||
| 377 | |||
| 378 | /** | ||
| 379 | * Field number for <code>get</code> and <code>set</code> indicating the | ||
| 380 | * month. This is a calendar-specific value. The first month of | ||
| 381 | * the year in the Gregorian and Julian calendars is | ||
| 382 | * <code>JANUARY</code> which is 0; the last depends on the number | ||
| 383 | * of months in a year. | ||
| 384 | * | ||
| 385 | * @see #JANUARY | ||
| 386 | * @see #FEBRUARY | ||
| 387 | * @see #MARCH | ||
| 388 | * @see #APRIL | ||
| 389 | * @see #MAY | ||
| 390 | * @see #JUNE | ||
| 391 | * @see #JULY | ||
| 392 | * @see #AUGUST | ||
| 393 | * @see #SEPTEMBER | ||
| 394 | * @see #OCTOBER | ||
| 395 | * @see #NOVEMBER | ||
| 396 | * @see #DECEMBER | ||
| 397 | * @see #UNDECIMBER | ||
| 398 | */ | ||
| 399 | public final static int MONTH = 2; | ||
| 400 | |||
| 401 | /** | ||
| 402 | * Field number for <code>get</code> and <code>set</code> indicating the | ||
| 403 | * week number within the current year. The first week of the year, as | ||
| 404 | * defined by <code>getFirstDayOfWeek()</code> and | ||
| 405 | * <code>getMinimalDaysInFirstWeek()</code>, has value 1. Subclasses define | ||
| 406 | * the value of <code>WEEK_OF_YEAR</code> for days before the first week of | ||
| 407 | * the year. | ||
| 408 | * | ||
| 409 | * @see #getFirstDayOfWeek | ||
| 410 | * @see #getMinimalDaysInFirstWeek | ||
| 411 | */ | ||
| 412 | public final static int WEEK_OF_YEAR = 3; | ||
| 413 | |||
| 414 | /** | ||
| 415 | * Field number for <code>get</code> and <code>set</code> indicating the | ||
| 416 | * week number within the current month. The first week of the month, as | ||
| 417 | * defined by <code>getFirstDayOfWeek()</code> and | ||
| 418 | * <code>getMinimalDaysInFirstWeek()</code>, has value 1. Subclasses define | ||
| 419 | * the value of <code>WEEK_OF_MONTH</code> for days before the first week of | ||
| 420 | * the month. | ||
| 421 | * | ||
| 422 | * @see #getFirstDayOfWeek | ||
| 423 | * @see #getMinimalDaysInFirstWeek | ||
| 424 | */ | ||
| 425 | public final static int WEEK_OF_MONTH = 4; | ||
| 426 | |||
| 427 | /** | ||
| 428 | * Field number for <code>get</code> and <code>set</code> indicating the | ||
| 429 | * day of the month. This is a synonym for <code>DAY_OF_MONTH</code>. | ||
| 430 | * The first day of the month has value 1. | ||
| 431 | * | ||
| 432 | * @see #DAY_OF_MONTH | ||
| 433 | */ | ||
| 434 | public final static int DATE = 5; | ||
| 435 | |||
| 436 | /** | ||
| 437 | * Field number for <code>get</code> and <code>set</code> indicating the | ||
| 438 | * day of the month. This is a synonym for <code>DATE</code>. | ||
| 439 | * The first day of the month has value 1. | ||
| 440 | * | ||
| 441 | * @see #DATE | ||
| 442 | */ | ||
| 443 | public final static int DAY_OF_MONTH = 5; | ||
| 444 | |||
| 445 | /** | ||
| 446 | * Field number for <code>get</code> and <code>set</code> indicating the day | ||
| 447 | * number within the current year. The first day of the year has value 1. | ||
| 448 | */ | ||
| 449 | public final static int DAY_OF_YEAR = 6; | ||
| 450 | |||
| 451 | /** | ||
| 452 | * Field number for <code>get</code> and <code>set</code> indicating the day | ||
| 453 | * of the week. This field takes values <code>SUNDAY</code>, | ||
| 454 | * <code>MONDAY</code>, <code>TUESDAY</code>, <code>WEDNESDAY</code>, | ||
| 455 | * <code>THURSDAY</code>, <code>FRIDAY</code>, and <code>SATURDAY</code>. | ||
| 456 | * | ||
| 457 | * @see #SUNDAY | ||
| 458 | * @see #MONDAY | ||
| 459 | * @see #TUESDAY | ||
| 460 | * @see #WEDNESDAY | ||
| 461 | * @see #THURSDAY | ||
| 462 | * @see #FRIDAY | ||
| 463 | * @see #SATURDAY | ||
| 464 | */ | ||
| 465 | public final static int DAY_OF_WEEK = 7; | ||
| 466 | |||
| 467 | /** | ||
| 468 | * Field number for <code>get</code> and <code>set</code> indicating the | ||
| 469 | * ordinal number of the day of the week within the current month. Together | ||
| 470 | * with the <code>DAY_OF_WEEK</code> field, this uniquely specifies a day | ||
| 471 | * within a month. Unlike <code>WEEK_OF_MONTH</code> and | ||
| 472 | * <code>WEEK_OF_YEAR</code>, this field's value does <em>not</em> depend on | ||
| 473 | * <code>getFirstDayOfWeek()</code> or | ||
| 474 | * <code>getMinimalDaysInFirstWeek()</code>. <code>DAY_OF_MONTH 1</code> | ||
| 475 | * through <code>7</code> always correspond to <code>DAY_OF_WEEK_IN_MONTH | ||
| 476 | * 1</code>; <code>8</code> through <code>14</code> correspond to | ||
| 477 | * <code>DAY_OF_WEEK_IN_MONTH 2</code>, and so on. | ||
| 478 | * <code>DAY_OF_WEEK_IN_MONTH 0</code> indicates the week before | ||
| 479 | * <code>DAY_OF_WEEK_IN_MONTH 1</code>. Negative values count back from the | ||
| 480 | * end of the month, so the last Sunday of a month is specified as | ||
| 481 | * <code>DAY_OF_WEEK = SUNDAY, DAY_OF_WEEK_IN_MONTH = -1</code>. Because | ||
| 482 | * negative values count backward they will usually be aligned differently | ||
| 483 | * within the month than positive values. For example, if a month has 31 | ||
| 484 | * days, <code>DAY_OF_WEEK_IN_MONTH -1</code> will overlap | ||
| 485 | * <code>DAY_OF_WEEK_IN_MONTH 5</code> and the end of <code>4</code>. | ||
| 486 | * | ||
| 487 | * @see #DAY_OF_WEEK | ||
| 488 | * @see #WEEK_OF_MONTH | ||
| 489 | */ | ||
| 490 | public final static int DAY_OF_WEEK_IN_MONTH = 8; | ||
| 491 | |||
| 492 | /** | ||
| 493 | * Field number for <code>get</code> and <code>set</code> indicating | ||
| 494 | * whether the <code>HOUR</code> is before or after noon. | ||
| 495 | * E.g., at 10:04:15.250 PM the <code>AM_PM</code> is <code>PM</code>. | ||
| 496 | * | ||
| 497 | * @see #AM | ||
| 498 | * @see #PM | ||
| 499 | * @see #HOUR | ||
| 500 | */ | ||
| 501 | public final static int AM_PM = 9; | ||
| 502 | |||
| 503 | /** | ||
| 504 | * Field number for <code>get</code> and <code>set</code> indicating the | ||
| 505 | * hour of the morning or afternoon. <code>HOUR</code> is used for the | ||
| 506 | * 12-hour clock (0 - 11). Noon and midnight are represented by 0, not by 12. | ||
| 507 | * E.g., at 10:04:15.250 PM the <code>HOUR</code> is 10. | ||
| 508 | * | ||
| 509 | * @see #AM_PM | ||
| 510 | * @see #HOUR_OF_DAY | ||
| 511 | */ | ||
| 512 | public final static int HOUR = 10; | ||
| 513 | |||
| 514 | /** | ||
| 515 | * Field number for <code>get</code> and <code>set</code> indicating the | ||
| 516 | * hour of the day. <code>HOUR_OF_DAY</code> is used for the 24-hour clock. | ||
| 517 | * E.g., at 10:04:15.250 PM the <code>HOUR_OF_DAY</code> is 22. | ||
| 518 | * | ||
| 519 | * @see #HOUR | ||
| 520 | */ | ||
| 521 | public final static int HOUR_OF_DAY = 11; | ||
| 522 | |||
| 523 | /** | ||
| 524 | * Field number for <code>get</code> and <code>set</code> indicating the | ||
| 525 | * minute within the hour. | ||
| 526 | * E.g., at 10:04:15.250 PM the <code>MINUTE</code> is 4. | ||
| 527 | */ | ||
| 528 | public final static int MINUTE = 12; | ||
| 529 | |||
| 530 | /** | ||
| 531 | * Field number for <code>get</code> and <code>set</code> indicating the | ||
| 532 | * second within the minute. | ||
| 533 | * E.g., at 10:04:15.250 PM the <code>SECOND</code> is 15. | ||
| 534 | */ | ||
| 535 | public final static int SECOND = 13; | ||
| 536 | |||
| 537 | /** | ||
| 538 | * Field number for <code>get</code> and <code>set</code> indicating the | ||
| 539 | * millisecond within the second. | ||
| 540 | * E.g., at 10:04:15.250 PM the <code>MILLISECOND</code> is 250. | ||
| 541 | */ | ||
| 542 | public final static int MILLISECOND = 14; | ||
| 543 | |||
| 544 | /** | ||
| 545 | * Field number for <code>get</code> and <code>set</code> | ||
| 546 | * indicating the raw offset from GMT in milliseconds. | ||
| 547 | * <p> | ||
| 548 | * This field reflects the correct GMT offset value of the time | ||
| 549 | * zone of this <code>Calendar</code> if the | ||
| 550 | * <code>TimeZone</code> implementation subclass supports | ||
| 551 | * historical GMT offset changes. | ||
| 552 | */ | ||
| 553 | public final static int ZONE_OFFSET = 15; | ||
| 554 | |||
| 555 | /** | ||
| 556 | * Field number for <code>get</code> and <code>set</code> indicating the | ||
| 557 | * daylight saving offset in milliseconds. | ||
| 558 | * <p> | ||
| 559 | * This field reflects the correct daylight saving offset value of | ||
| 560 | * the time zone of this <code>Calendar</code> if the | ||
| 561 | * <code>TimeZone</code> implementation subclass supports | ||
| 562 | * historical Daylight Saving Time schedule changes. | ||
| 563 | */ | ||
| 564 | public final static int DST_OFFSET = 16; | ||
| 565 | |||
| 566 | /** | ||
| 567 | * The number of distinct fields recognized by <code>get</code> and <code>set</code>. | ||
| 568 | * Field numbers range from <code>0..FIELD_COUNT-1</code>. | ||
| 569 | */ | ||
| 570 | public final static int FIELD_COUNT = 17; | ||
| 571 | |||
| 572 | /** | ||
| 573 | * Value of the {@link #DAY_OF_WEEK} field indicating | ||
| 574 | * Sunday. | ||
| 575 | */ | ||
| 576 | public final static int SUNDAY = 1; | ||
| 577 | |||
| 578 | /** | ||
| 579 | * Value of the {@link #DAY_OF_WEEK} field indicating | ||
| 580 | * Monday. | ||
| 581 | */ | ||
| 582 | public final static int MONDAY = 2; | ||
| 583 | |||
| 584 | /** | ||
| 585 | * Value of the {@link #DAY_OF_WEEK} field indicating | ||
| 586 | * Tuesday. | ||
| 587 | */ | ||
| 588 | public final static int TUESDAY = 3; | ||
| 589 | |||
| 590 | /** | ||
| 591 | * Value of the {@link #DAY_OF_WEEK} field indicating | ||
| 592 | * Wednesday. | ||
| 593 | */ | ||
| 594 | public final static int WEDNESDAY = 4; | ||
| 595 | |||
| 596 | /** | ||
| 597 | * Value of the {@link #DAY_OF_WEEK} field indicating | ||
| 598 | * Thursday. | ||
| 599 | */ | ||
| 600 | public final static int THURSDAY = 5; | ||
| 601 | |||
| 602 | /** | ||
| 603 | * Value of the {@link #DAY_OF_WEEK} field indicating | ||
| 604 | * Friday. | ||
| 605 | */ | ||
| 606 | public final static int FRIDAY = 6; | ||
| 607 | |||
| 608 | /** | ||
| 609 | * Value of the {@link #DAY_OF_WEEK} field indicating | ||
| 610 | * Saturday. | ||
| 611 | */ | ||
| 612 | public final static int SATURDAY = 7; | ||
| 613 | |||
| 614 | /** | ||
| 615 | * Value of the {@link #MONTH} field indicating the | ||
| 616 | * first month of the year in the Gregorian and Julian calendars. | ||
| 617 | */ | ||
| 618 | public final static int JANUARY = 0; | ||
| 619 | |||
| 620 | /** | ||
| 621 | * Value of the {@link #MONTH} field indicating the | ||
| 622 | * second month of the year in the Gregorian and Julian calendars. | ||
| 623 | */ | ||
| 624 | public final static int FEBRUARY = 1; | ||
| 625 | |||
| 626 | /** | ||
| 627 | * Value of the {@link #MONTH} field indicating the | ||
| 628 | * third month of the year in the Gregorian and Julian calendars. | ||
| 629 | */ | ||
| 630 | public final static int MARCH = 2; | ||
| 631 | |||
| 632 | /** | ||
| 633 | * Value of the {@link #MONTH} field indicating the | ||
| 634 | * fourth month of the year in the Gregorian and Julian calendars. | ||
| 635 | */ | ||
| 636 | public final static int APRIL = 3; | ||
| 637 | |||
| 638 | /** | ||
| 639 | * Value of the {@link #MONTH} field indicating the | ||
| 640 | * fifth month of the year in the Gregorian and Julian calendars. | ||
| 641 | */ | ||
| 642 | public final static int MAY = 4; | ||
| 643 | |||
| 644 | /** | ||
| 645 | * Value of the {@link #MONTH} field indicating the | ||
| 646 | * sixth month of the year in the Gregorian and Julian calendars. | ||
| 647 | */ | ||
| 648 | public final static int JUNE = 5; | ||
| 649 | |||
| 650 | /** | ||
| 651 | * Value of the {@link #MONTH} field indicating the | ||
| 652 | * seventh month of the year in the Gregorian and Julian calendars. | ||
| 653 | */ | ||
| 654 | public final static int JULY = 6; | ||
| 655 | |||
| 656 | /** | ||
| 657 | * Value of the {@link #MONTH} field indicating the | ||
| 658 | * eighth month of the year in the Gregorian and Julian calendars. | ||
| 659 | */ | ||
| 660 | public final static int AUGUST = 7; | ||
| 661 | |||
| 662 | /** | ||
| 663 | * Value of the {@link #MONTH} field indicating the | ||
| 664 | * ninth month of the year in the Gregorian and Julian calendars. | ||
| 665 | */ | ||
| 666 | public final static int SEPTEMBER = 8; | ||
| 667 | |||
| 668 | /** | ||
| 669 | * Value of the {@link #MONTH} field indicating the | ||
| 670 | * tenth month of the year in the Gregorian and Julian calendars. | ||
| 671 | */ | ||
| 672 | public final static int OCTOBER = 9; | ||
| 673 | |||
| 674 | /** | ||
| 675 | * Value of the {@link #MONTH} field indicating the | ||
| 676 | * eleventh month of the year in the Gregorian and Julian calendars. | ||
| 677 | */ | ||
| 678 | public final static int NOVEMBER = 10; | ||
| 679 | |||
| 680 | /** | ||
| 681 | * Value of the {@link #MONTH} field indicating the | ||
| 682 | * twelfth month of the year in the Gregorian and Julian calendars. | ||
| 683 | */ | ||
| 684 | public final static int DECEMBER = 11; | ||
| 685 | |||
| 686 | /** | ||
| 687 | * Value of the {@link #MONTH} field indicating the | ||
| 688 | * thirteenth month of the year. Although <code>GregorianCalendar</code> | ||
| 689 | * does not use this value, lunar calendars do. | ||
| 690 | */ | ||
| 691 | public final static int UNDECIMBER = 12; | ||
| 692 | |||
| 693 | /** | ||
| 694 | * Value of the {@link #AM_PM} field indicating the | ||
| 695 | * period of the day from midnight to just before noon. | ||
| 696 | */ | ||
| 697 | public final static int AM = 0; | ||
| 698 | |||
| 699 | /** | ||
| 700 | * Value of the {@link #AM_PM} field indicating the | ||
| 701 | * period of the day from noon to just before midnight. | ||
| 702 | */ | ||
| 703 | public final static int PM = 1; | ||
| 704 | |||
| 705 | /** | ||
| 706 | * A style specifier for {@link #getDisplayNames(int, int, Locale) | ||
| 707 | * getDisplayNames} indicating names in all styles, such as | ||
| 708 | * "January" and "Jan". | ||
| 709 | * | ||
| 710 | * @see #SHORT | ||
| 711 | * @see #LONG | ||
| 712 | * @since 1.6 | ||
| 713 | */ | ||
| 714 | public static final int ALL_STYLES = 0; | ||
| 715 | |||
| 716 | /** | ||
| 717 | * A style specifier for {@link #getDisplayName(int, int, Locale) | ||
| 718 | * getDisplayName} and {@link #getDisplayNames(int, int, Locale) | ||
| 719 | * getDisplayNames} indicating a short name, such as "Jan". | ||
| 720 | * | ||
| 721 | * @see #LONG | ||
| 722 | * @since 1.6 | ||
| 723 | */ | ||
| 724 | public static final int SHORT = 1; | ||
| 725 | |||
| 726 | /** | ||
| 727 | * A style specifier for {@link #getDisplayName(int, int, Locale) | ||
| 728 | * getDisplayName} and {@link #getDisplayNames(int, int, Locale) | ||
| 729 | * getDisplayNames} indicating a long name, such as "January". | ||
| 730 | * | ||
| 731 | * @see #SHORT | ||
| 732 | * @since 1.6 | ||
| 733 | */ | ||
| 734 | public static final int LONG = 2; | ||
| 735 | |||
| 736 | // Internal notes: | ||
| 737 | // Calendar contains two kinds of time representations: current "time" in | ||
| 738 | // milliseconds, and a set of calendar "fields" representing the current time. | ||
| 739 | // The two representations are usually in sync, but can get out of sync | ||
| 740 | // as follows. | ||
| 741 | // 1. Initially, no fields are set, and the time is invalid. | ||
| 742 | // 2. If the time is set, all fields are computed and in sync. | ||
| 743 | // 3. If a single field is set, the time is invalid. | ||
| 744 | // Recomputation of the time and fields happens when the object needs | ||
| 745 | // to return a result to the user, or use a result for a computation. | ||
| 746 | |||
| 747 | /** | ||
| 748 | * The calendar field values for the currently set time for this calendar. | ||
| 749 | * This is an array of <code>FIELD_COUNT</code> integers, with index values | ||
| 750 | * <code>ERA</code> through <code>DST_OFFSET</code>. | ||
| 751 | * @serial | ||
| 752 | */ | ||
| 753 | protected int fields[]; | ||
| 754 | |||
| 755 | /** | ||
| 756 | * The flags which tell if a specified calendar field for the calendar is set. | ||
| 757 | * A new object has no fields set. After the first call to a method | ||
| 758 | * which generates the fields, they all remain set after that. | ||
| 759 | * This is an array of <code>FIELD_COUNT</code> booleans, with index values | ||
| 760 | * <code>ERA</code> through <code>DST_OFFSET</code>. | ||
| 761 | * @serial | ||
| 762 | */ | ||
| 763 | protected boolean isSet[]; | ||
| 764 | |||
| 765 | /** | ||
| 766 | * Pseudo-time-stamps which specify when each field was set. There | ||
| 767 | * are two special values, UNSET and COMPUTED. Values from | ||
| 768 | * MINIMUM_USER_SET to Integer.MAX_VALUE are legal user set values. | ||
| 769 | */ | ||
| 770 | transient private int stamp[]; | ||
| 771 | |||
| 772 | /** | ||
| 773 | * The currently set time for this calendar, expressed in milliseconds after | ||
| 774 | * January 1, 1970, 0:00:00 GMT. | ||
| 775 | * @see #isTimeSet | ||
| 776 | * @serial | ||
| 777 | */ | ||
| 778 | protected long time; | ||
| 779 | |||
| 780 | /** | ||
| 781 | * True if then the value of <code>time</code> is valid. | ||
| 782 | * The time is made invalid by a change to an item of <code>field[]</code>. | ||
| 783 | * @see #time | ||
| 784 | * @serial | ||
| 785 | */ | ||
| 786 | protected boolean isTimeSet; | ||
| 787 | |||
| 788 | /** | ||
| 789 | * True if <code>fields[]</code> are in sync with the currently set time. | ||
| 790 | * If false, then the next attempt to get the value of a field will | ||
| 791 | * force a recomputation of all fields from the current value of | ||
| 792 | * <code>time</code>. | ||
| 793 | * @serial | ||
| 794 | */ | ||
| 795 | protected boolean areFieldsSet; | ||
| 796 | |||
| 797 | /** | ||
| 798 | * True if all fields have been set. | ||
| 799 | * @serial | ||
| 800 | */ | ||
| 801 | transient boolean areAllFieldsSet; | ||
| 802 | |||
| 803 | /** | ||
| 804 | * <code>True</code> if this calendar allows out-of-range field values during computation | ||
| 805 | * of <code>time</code> from <code>fields[]</code>. | ||
| 806 | * @see #setLenient | ||
| 807 | * @see #isLenient | ||
| 808 | * @serial | ||
| 809 | */ | ||
| 810 | private boolean lenient = true; | ||
| 811 | |||
| 812 | /** | ||
| 813 | * The <code>TimeZone</code> used by this calendar. <code>Calendar</code> | ||
| 814 | * uses the time zone data to translate between locale and GMT time. | ||
| 815 | * @serial | ||
| 816 | */ | ||
| 817 | private TimeZone zone; | ||
| 818 | |||
| 819 | /** | ||
| 820 | * <code>True</code> if zone references to a shared TimeZone object. | ||
| 821 | */ | ||
| 822 | transient private boolean sharedZone = false; | ||
| 823 | |||
| 824 | /** | ||
| 825 | * The first day of the week, with possible values <code>SUNDAY</code>, | ||
| 826 | * <code>MONDAY</code>, etc. This is a locale-dependent value. | ||
| 827 | * @serial | ||
| 828 | */ | ||
| 829 | private int firstDayOfWeek; | ||
| 830 | |||
| 831 | /** | ||
| 832 | * The number of days required for the first week in a month or year, | ||
| 833 | * with possible values from 1 to 7. This is a locale-dependent value. | ||
| 834 | * @serial | ||
| 835 | */ | ||
| 836 | private int minimalDaysInFirstWeek; | ||
| 837 | |||
| 838 | /** | ||
| 839 | * Cache to hold the firstDayOfWeek and minimalDaysInFirstWeek | ||
| 840 | * of a Locale. | ||
| 841 | */ | ||
| 842 | private static final ConcurrentMap<Locale, int[]> cachedLocaleData | ||
| 843 | = new ConcurrentHashMap<Locale, int[]>(3); | ||
| 844 | |||
| 845 | // Special values of stamp[] | ||
| 846 | /** | ||
| 847 | * The corresponding fields[] has no value. | ||
| 848 | */ | ||
| 849 | private static final int UNSET = 0; | ||
| 850 | |||
| 851 | /** | ||
| 852 | * The value of the corresponding fields[] has been calculated internally. | ||
| 853 | */ | ||
| 854 | private static final int COMPUTED = 1; | ||
| 855 | |||
| 856 | /** | ||
| 857 | * The value of the corresponding fields[] has been set externally. Stamp | ||
| 858 | * values which are greater than 1 represents the (pseudo) time when the | ||
| 859 | * corresponding fields[] value was set. | ||
| 860 | */ | ||
| 861 | private static final int MINIMUM_USER_STAMP = 2; | ||
| 862 | |||
| 863 | /** | ||
| 864 | * The mask value that represents all of the fields. | ||
| 865 | */ | ||
| 866 | static final int ALL_FIELDS = (1 << FIELD_COUNT) - 1; | ||
| 867 | |||
| 868 | /** | ||
| 869 | * The next available value for <code>stamp[]</code>, an internal array. | ||
| 870 | * This actually should not be written out to the stream, and will probably | ||
| 871 | * be removed from the stream in the near future. In the meantime, | ||
| 872 | * a value of <code>MINIMUM_USER_STAMP</code> should be used. | ||
| 873 | * @serial | ||
| 874 | */ | ||
| 875 | private int nextStamp = MINIMUM_USER_STAMP; | ||
| 876 | |||
| 877 | // the internal serial version which says which version was written | ||
| 878 | // - 0 (default) for version up to JDK 1.1.5 | ||
| 879 | // - 1 for version from JDK 1.1.6, which writes a correct 'time' value | ||
| 880 | // as well as compatible values for other fields. This is a | ||
| 881 | // transitional format. | ||
| 882 | // - 2 (not implemented yet) a future version, in which fields[], | ||
| 883 | // areFieldsSet, and isTimeSet become transient, and isSet[] is | ||
| 884 | // removed. In JDK 1.1.6 we write a format compatible with version 2. | ||
| 885 | static final int currentSerialVersion = 1; | ||
| 886 | |||
| 887 | /** | ||
| 888 | * The version of the serialized data on the stream. Possible values: | ||
| 889 | * <dl> | ||
| 890 | * <dt><b>0</b> or not present on stream</dt> | ||
| 891 | * <dd> | ||
| 892 | * JDK 1.1.5 or earlier. | ||
| 893 | * </dd> | ||
| 894 | * <dt><b>1</b></dt> | ||
| 895 | * <dd> | ||
| 896 | * JDK 1.1.6 or later. Writes a correct 'time' value | ||
| 897 | * as well as compatible values for other fields. This is a | ||
| 898 | * transitional format. | ||
| 899 | * </dd> | ||
| 900 | * </dl> | ||
| 901 | * When streaming out this class, the most recent format | ||
| 902 | * and the highest allowable <code>serialVersionOnStream</code> | ||
| 903 | * is written. | ||
| 904 | * @serial | ||
| 905 | * @since JDK1.1.6 | ||
| 906 | */ | ||
| 907 | private int serialVersionOnStream = currentSerialVersion; | ||
| 908 | |||
| 909 | // Proclaim serialization compatibility with JDK 1.1 | ||
| 910 | static final long serialVersionUID = -1807547505821590642L; | ||
| 911 | |||
| 912 | // Mask values for calendar fields | ||
| 913 | final static int ERA_MASK = (1 << ERA); | ||
| 914 | final static int YEAR_MASK = (1 << YEAR); | ||
| 915 | final static int MONTH_MASK = (1 << MONTH); | ||
| 916 | final static int WEEK_OF_YEAR_MASK = (1 << WEEK_OF_YEAR); | ||
| 917 | final static int WEEK_OF_MONTH_MASK = (1 << WEEK_OF_MONTH); | ||
| 918 | final static int DAY_OF_MONTH_MASK = (1 << DAY_OF_MONTH); | ||
| 919 | final static int DATE_MASK = DAY_OF_MONTH_MASK; | ||
| 920 | final static int DAY_OF_YEAR_MASK = (1 << DAY_OF_YEAR); | ||
| 921 | final static int DAY_OF_WEEK_MASK = (1 << DAY_OF_WEEK); | ||
| 922 | final static int DAY_OF_WEEK_IN_MONTH_MASK = (1 << DAY_OF_WEEK_IN_MONTH); | ||
| 923 | final static int AM_PM_MASK = (1 << AM_PM); | ||
| 924 | final static int HOUR_MASK = (1 << HOUR); | ||
| 925 | final static int HOUR_OF_DAY_MASK = (1 << HOUR_OF_DAY); | ||
| 926 | final static int MINUTE_MASK = (1 << MINUTE); | ||
| 927 | final static int SECOND_MASK = (1 << SECOND); | ||
| 928 | final static int MILLISECOND_MASK = (1 << MILLISECOND); | ||
| 929 | final static int ZONE_OFFSET_MASK = (1 << ZONE_OFFSET); | ||
| 930 | final static int DST_OFFSET_MASK = (1 << DST_OFFSET); | ||
| 931 | |||
| 932 | /** | ||
| 933 | * Constructs a Calendar with the default time zone | ||
| 934 | * and locale. | ||
| 935 | * @see TimeZone#getDefault | ||
| 936 | */ | ||
| 937 | protected Calendar() | ||
| 938 | { | ||
| 939 | this(TimeZone.getDefaultRef(), Locale.getDefault(Locale.Category.FORMAT)); | ||
| 940 | sharedZone = true; | ||
| 941 | } | ||
| 942 | |||
| 943 | /** | ||
| 944 | * Constructs a calendar with the specified time zone and locale. | ||
| 945 | * | ||
| 946 | * @param zone the time zone to use | ||
| 947 | * @param aLocale the locale for the week data | ||
| 948 | */ | ||
| 949 | protected Calendar(TimeZone zone, Locale aLocale) | ||
| 950 | { | ||
| 951 | fields = new int[FIELD_COUNT]; | ||
| 952 | isSet = new boolean[FIELD_COUNT]; | ||
| 953 | stamp = new int[FIELD_COUNT]; | ||
| 954 | |||
| 955 | this.zone = zone; | ||
| 956 | setWeekCountData(aLocale); | ||
| 957 | } | ||
| 958 | |||
| 959 | /** | ||
| 960 | * Gets a calendar using the default time zone and locale. The | ||
| 961 | * <code>Calendar</code> returned is based on the current time | ||
| 962 | * in the default time zone with the default locale. | ||
| 963 | * | ||
| 964 | * @return a Calendar. | ||
| 965 | */ | ||
| 966 | public static Calendar getInstance() | ||
| 967 | { | ||
| 968 | Calendar cal = createCalendar(TimeZone.getDefaultRef(), Locale.getDefault(Locale.Category.FORMAT)); | ||
| 969 | cal.sharedZone = true; | ||
| 970 | return cal; | ||
| 971 | } | ||
| 972 | |||
| 973 | /** | ||
| 974 | * Gets a calendar using the specified time zone and default locale. | ||
| 975 | * The <code>Calendar</code> returned is based on the current time | ||
| 976 | * in the given time zone with the default locale. | ||
| 977 | * | ||
| 978 | * @param zone the time zone to use | ||
| 979 | * @return a Calendar. | ||
| 980 | */ | ||
| 981 | public static Calendar getInstance(TimeZone zone) | ||
| 982 | { | ||
| 983 | return createCalendar(zone, Locale.getDefault(Locale.Category.FORMAT)); | ||
| 984 | } | ||
| 985 | |||
| 986 | /** | ||
| 987 | * Gets a calendar using the default time zone and specified locale. | ||
| 988 | * The <code>Calendar</code> returned is based on the current time | ||
| 989 | * in the default time zone with the given locale. | ||
| 990 | * | ||
| 991 | * @param aLocale the locale for the week data | ||
| 992 | * @return a Calendar. | ||
| 993 | */ | ||
| 994 | public static Calendar getInstance(Locale aLocale) | ||
| 995 | { | ||
| 996 | Calendar cal = createCalendar(TimeZone.getDefaultRef(), aLocale); | ||
| 997 | cal.sharedZone = true; | ||
| 998 | return cal; | ||
| 999 | } | ||
| 1000 | |||
| 1001 | /** | ||
| 1002 | * Gets a calendar with the specified time zone and locale. | ||
| 1003 | * The <code>Calendar</code> returned is based on the current time | ||
| 1004 | * in the given time zone with the given locale. | ||
| 1005 | * | ||
| 1006 | * @param zone the time zone to use | ||
| 1007 | * @param aLocale the locale for the week data | ||
| 1008 | * @return a Calendar. | ||
| 1009 | */ | ||
| 1010 | public static Calendar getInstance(TimeZone zone, | ||
| 1011 | Locale aLocale) | ||
| 1012 | { | ||
| 1013 | return createCalendar(zone, aLocale); | ||
| 1014 | } | ||
| 1015 | |||
| 1016 | private static Calendar createCalendar(TimeZone zone, | ||
| 1017 | Locale aLocale) | ||
| 1018 | { | ||
| 1019 | Calendar cal = null; | ||
| 1020 | |||
| 1021 | String caltype = aLocale.getUnicodeLocaleType("ca"); | ||
| 1022 | if (caltype == null) { | ||
| 1023 | // Calendar type is not specified. | ||
| 1024 | // If the specified locale is a Thai locale, | ||
| 1025 | // returns a BuddhistCalendar instance. | ||
| 1026 | if ("th".equals(aLocale.getLanguage()) | ||
| 1027 | && ("TH".equals(aLocale.getCountry()))) { | ||
| 1028 | cal = new BuddhistCalendar(zone, aLocale); | ||
| 1029 | } else { | ||
| 1030 | cal = new GregorianCalendar(zone, aLocale); | ||
| 1031 | } | ||
| 1032 | } else if (caltype.equals("japanese")) { | ||
| 1033 | cal = new JapaneseImperialCalendar(zone, aLocale); | ||
| 1034 | } else if (caltype.equals("buddhist")) { | ||
| 1035 | cal = new BuddhistCalendar(zone, aLocale); | ||
| 1036 | } else { | ||
| 1037 | // Unsupported calendar type. | ||
| 1038 | // Use Gregorian calendar as a fallback. | ||
| 1039 | cal = new GregorianCalendar(zone, aLocale); | ||
| 1040 | } | ||
| 1041 | |||
| 1042 | return cal; | ||
| 1043 | } | ||
| 1044 | |||
| 1045 | /** | ||
| 1046 | * Returns an array of all locales for which the <code>getInstance</code> | ||
| 1047 | * methods of this class can return localized instances. | ||
| 1048 | * The array returned must contain at least a <code>Locale</code> | ||
| 1049 | * instance equal to {@link java.util.Locale#US Locale.US}. | ||
| 1050 | * | ||
| 1051 | * @return An array of locales for which localized | ||
| 1052 | * <code>Calendar</code> instances are available. | ||
| 1053 | */ | ||
| 1054 | public static synchronized Locale[] getAvailableLocales() | ||
| 1055 | { | ||
| 1056 | return DateFormat.getAvailableLocales(); | ||
| 1057 | } | ||
| 1058 | |||
| 1059 | /** | ||
| 1060 | * Converts the current calendar field values in {@link #fields fields[]} | ||
| 1061 | * to the millisecond time value | ||
| 1062 | * {@link #time}. | ||
| 1063 | * | ||
| 1064 | * @see #complete() | ||
| 1065 | * @see #computeFields() | ||
| 1066 | */ | ||
| 1067 | protected abstract void computeTime(); | ||
| 1068 | |||
| 1069 | /** | ||
| 1070 | * Converts the current millisecond time value {@link #time} | ||
| 1071 | * to calendar field values in {@link #fields fields[]}. | ||
| 1072 | * This allows you to sync up the calendar field values with | ||
| 1073 | * a new time that is set for the calendar. The time is <em>not</em> | ||
| 1074 | * recomputed first; to recompute the time, then the fields, call the | ||
| 1075 | * {@link #complete()} method. | ||
| 1076 | * | ||
| 1077 | * @see #computeTime() | ||
| 1078 | */ | ||
| 1079 | protected abstract void computeFields(); | ||
| 1080 | |||
| 1081 | /** | ||
| 1082 | * Returns a <code>Date</code> object representing this | ||
| 1083 | * <code>Calendar</code>'s time value (millisecond offset from the <a | ||
| 1084 | * href="#Epoch">Epoch</a>"). | ||
| 1085 | * | ||
| 1086 | * @return a <code>Date</code> representing the time value. | ||
| 1087 | * @see #setTime(Date) | ||
| 1088 | * @see #getTimeInMillis() | ||
| 1089 | */ | ||
| 1090 | public final Date getTime() { | ||
| 1091 | return new Date(getTimeInMillis()); | ||
| 1092 | } | ||
| 1093 | |||
| 1094 | /** | ||
| 1095 | * Sets this Calendar's time with the given <code>Date</code>. | ||
| 1096 | * <p> | ||
| 1097 | * Note: Calling <code>setTime()</code> with | ||
| 1098 | * <code>Date(Long.MAX_VALUE)</code> or <code>Date(Long.MIN_VALUE)</code> | ||
| 1099 | * may yield incorrect field values from <code>get()</code>. | ||
| 1100 | * | ||
| 1101 | * @param date the given Date. | ||
| 1102 | * @see #getTime() | ||
| 1103 | * @see #setTimeInMillis(long) | ||
| 1104 | */ | ||
| 1105 | public final void setTime(Date date) { | ||
| 1106 | setTimeInMillis(date.getTime()); | ||
| 1107 | } | ||
| 1108 | |||
| 1109 | /** | ||
| 1110 | * Returns this Calendar's time value in milliseconds. | ||
| 1111 | * | ||
| 1112 | * @return the current time as UTC milliseconds from the epoch. | ||
| 1113 | * @see #getTime() | ||
| 1114 | * @see #setTimeInMillis(long) | ||
| 1115 | */ | ||
| 1116 | public long getTimeInMillis() { | ||
| 1117 | if (!isTimeSet) { | ||
| 1118 | updateTime(); | ||
| 1119 | } | ||
| 1120 | return time; | ||
| 1121 | } | ||
| 1122 | |||
| 1123 | /** | ||
| 1124 | * Sets this Calendar's current time from the given long value. | ||
| 1125 | * | ||
| 1126 | * @param millis the new time in UTC milliseconds from the epoch. | ||
| 1127 | * @see #setTime(Date) | ||
| 1128 | * @see #getTimeInMillis() | ||
| 1129 | */ | ||
| 1130 | public void setTimeInMillis(long millis) { | ||
| 1131 | // If we don't need to recalculate the calendar field values, | ||
| 1132 | // do nothing. | ||
| 1133 | if (time == millis && isTimeSet && areFieldsSet && areAllFieldsSet | ||
| 1134 | && (zone instanceof ZoneInfo) && !((ZoneInfo)zone).isDirty()) { | ||
| 1135 | return; | ||
| 1136 | } | ||
| 1137 | time = millis; | ||
| 1138 | isTimeSet = true; | ||
| 1139 | areFieldsSet = false; | ||
| 1140 | computeFields(); | ||
| 1141 | areAllFieldsSet = areFieldsSet = true; | ||
| 1142 | } | ||
| 1143 | |||
| 1144 | /** | ||
| 1145 | * Returns the value of the given calendar field. In lenient mode, | ||
| 1146 | * all calendar fields are normalized. In non-lenient mode, all | ||
| 1147 | * calendar fields are validated and this method throws an | ||
| 1148 | * exception if any calendar fields have out-of-range values. The | ||
| 1149 | * normalization and validation are handled by the | ||
| 1150 | * {@link #complete()} method, which process is calendar | ||
| 1151 | * system dependent. | ||
| 1152 | * | ||
| 1153 | * @param field the given calendar field. | ||
| 1154 | * @return the value for the given calendar field. | ||
| 1155 | * @throws ArrayIndexOutOfBoundsException if the specified field is out of range | ||
| 1156 | * (<code>field < 0 || field >= FIELD_COUNT</code>). | ||
| 1157 | * @see #set(int,int) | ||
| 1158 | * @see #complete() | ||
| 1159 | */ | ||
| 1160 | public int get(int field) | ||
| 1161 | { | ||
| 1162 | complete(); | ||
| 1163 | return internalGet(field); | ||
| 1164 | } | ||
| 1165 | |||
| 1166 | /** | ||
| 1167 | * Returns the value of the given calendar field. This method does | ||
| 1168 | * not involve normalization or validation of the field value. | ||
| 1169 | * | ||
| 1170 | * @param field the given calendar field. | ||
| 1171 | * @return the value for the given calendar field. | ||
| 1172 | * @see #get(int) | ||
| 1173 | */ | ||
| 1174 | protected final int internalGet(int field) | ||
| 1175 | { | ||
| 1176 | return fields[field]; | ||
| 1177 | } | ||
| 1178 | |||
| 1179 | /** | ||
| 1180 | * Sets the value of the given calendar field. This method does | ||
| 1181 | * not affect any setting state of the field in this | ||
| 1182 | * <code>Calendar</code> instance. | ||
| 1183 | * | ||
| 1184 | * @throws IndexOutOfBoundsException if the specified field is out of range | ||
| 1185 | * (<code>field < 0 || field >= FIELD_COUNT</code>). | ||
| 1186 | * @see #areFieldsSet | ||
| 1187 | * @see #isTimeSet | ||
| 1188 | * @see #areAllFieldsSet | ||
| 1189 | * @see #set(int,int) | ||
| 1190 | */ | ||
| 1191 | final void internalSet(int field, int value) | ||
| 1192 | { | ||
| 1193 | fields[field] = value; | ||
| 1194 | } | ||
| 1195 | |||
| 1196 | /** | ||
| 1197 | * Sets the given calendar field to the given value. The value is not | ||
| 1198 | * interpreted by this method regardless of the leniency mode. | ||
| 1199 | * | ||
| 1200 | * @param field the given calendar field. | ||
| 1201 | * @param value the value to be set for the given calendar field. | ||
| 1202 | * @throws ArrayIndexOutOfBoundsException if the specified field is out of range | ||
| 1203 | * (<code>field < 0 || field >= FIELD_COUNT</code>). | ||
| 1204 | * in non-lenient mode. | ||
| 1205 | * @see #set(int,int,int) | ||
| 1206 | * @see #set(int,int,int,int,int) | ||
| 1207 | * @see #set(int,int,int,int,int,int) | ||
| 1208 | * @see #get(int) | ||
| 1209 | */ | ||
| 1210 | public void set(int field, int value) | ||
| 1211 | { | ||
| 1212 | // If the fields are partially normalized, calculate all the | ||
| 1213 | // fields before changing any fields. | ||
| 1214 | if (areFieldsSet && !areAllFieldsSet) { | ||
| 1215 | computeFields(); | ||
| 1216 | } | ||
| 1217 | internalSet(field, value); | ||
| 1218 | isTimeSet = false; | ||
| 1219 | areFieldsSet = false; | ||
| 1220 | isSet[field] = true; | ||
| 1221 | stamp[field] = nextStamp++; | ||
| 1222 | if (nextStamp == Integer.MAX_VALUE) { | ||
| 1223 | adjustStamp(); | ||
| 1224 | } | ||
| 1225 | } | ||
| 1226 | |||
| 1227 | /** | ||
| 1228 | * Sets the values for the calendar fields <code>YEAR</code>, | ||
| 1229 | * <code>MONTH</code>, and <code>DAY_OF_MONTH</code>. | ||
| 1230 | * Previous values of other calendar fields are retained. If this is not desired, | ||
| 1231 | * call {@link #clear()} first. | ||
| 1232 | * | ||
| 1233 | * @param year the value used to set the <code>YEAR</code> calendar field. | ||
| 1234 | * @param month the value used to set the <code>MONTH</code> calendar field. | ||
| 1235 | * Month value is 0-based. e.g., 0 for January. | ||
| 1236 | * @param date the value used to set the <code>DAY_OF_MONTH</code> calendar field. | ||
| 1237 | * @see #set(int,int) | ||
| 1238 | * @see #set(int,int,int,int,int) | ||
| 1239 | * @see #set(int,int,int,int,int,int) | ||
| 1240 | */ | ||
| 1241 | public final void set(int year, int month, int date) | ||
| 1242 | { | ||
| 1243 | set(YEAR, year); | ||
| 1244 | set(MONTH, month); | ||
| 1245 | set(DATE, date); | ||
| 1246 | } | ||
| 1247 | |||
| 1248 | /** | ||
| 1249 | * Sets the values for the calendar fields <code>YEAR</code>, | ||
| 1250 | * <code>MONTH</code>, <code>DAY_OF_MONTH</code>, | ||
| 1251 | * <code>HOUR_OF_DAY</code>, and <code>MINUTE</code>. | ||
| 1252 | * Previous values of other fields are retained. If this is not desired, | ||
| 1253 | * call {@link #clear()} first. | ||
| 1254 | * | ||
| 1255 | * @param year the value used to set the <code>YEAR</code> calendar field. | ||
| 1256 | * @param month the value used to set the <code>MONTH</code> calendar field. | ||
| 1257 | * Month value is 0-based. e.g., 0 for January. | ||
| 1258 | * @param date the value used to set the <code>DAY_OF_MONTH</code> calendar field. | ||
| 1259 | * @param hourOfDay the value used to set the <code>HOUR_OF_DAY</code> calendar field. | ||
| 1260 | * @param minute the value used to set the <code>MINUTE</code> calendar field. | ||
| 1261 | * @see #set(int,int) | ||
| 1262 | * @see #set(int,int,int) | ||
| 1263 | * @see #set(int,int,int,int,int,int) | ||
| 1264 | */ | ||
| 1265 | public final void set(int year, int month, int date, int hourOfDay, int minute) | ||
| 1266 | { | ||
| 1267 | set(YEAR, year); | ||
| 1268 | set(MONTH, month); | ||
| 1269 | set(DATE, date); | ||
| 1270 | set(HOUR_OF_DAY, hourOfDay); | ||
| 1271 | set(MINUTE, minute); | ||
| 1272 | } | ||
| 1273 | |||
| 1274 | /** | ||
| 1275 | * Sets the values for the fields <code>YEAR</code>, <code>MONTH</code>, | ||
| 1276 | * <code>DAY_OF_MONTH</code>, <code>HOUR</code>, <code>MINUTE</code>, and | ||
| 1277 | * <code>SECOND</code>. | ||
| 1278 | * Previous values of other fields are retained. If this is not desired, | ||
| 1279 | * call {@link #clear()} first. | ||
| 1280 | * | ||
| 1281 | * @param year the value used to set the <code>YEAR</code> calendar field. | ||
| 1282 | * @param month the value used to set the <code>MONTH</code> calendar field. | ||
| 1283 | * Month value is 0-based. e.g., 0 for January. | ||
| 1284 | * @param date the value used to set the <code>DAY_OF_MONTH</code> calendar field. | ||
| 1285 | * @param hourOfDay the value used to set the <code>HOUR_OF_DAY</code> calendar field. | ||
| 1286 | * @param minute the value used to set the <code>MINUTE</code> calendar field. | ||
| 1287 | * @param second the value used to set the <code>SECOND</code> calendar field. | ||
| 1288 | * @see #set(int,int) | ||
| 1289 | * @see #set(int,int,int) | ||
| 1290 | * @see #set(int,int,int,int,int) | ||
| 1291 | */ | ||
| 1292 | public final void set(int year, int month, int date, int hourOfDay, int minute, | ||
| 1293 | int second) | ||
| 1294 | { | ||
| 1295 | set(YEAR, year); | ||
| 1296 | set(MONTH, month); | ||
| 1297 | set(DATE, date); | ||
| 1298 | set(HOUR_OF_DAY, hourOfDay); | ||
| 1299 | set(MINUTE, minute); | ||
| 1300 | set(SECOND, second); | ||
| 1301 | } | ||
| 1302 | |||
| 1303 | /** | ||
| 1304 | * Sets all the calendar field values and the time value | ||
| 1305 | * (millisecond offset from the <a href="#Epoch">Epoch</a>) of | ||
| 1306 | * this <code>Calendar</code> undefined. This means that {@link | ||
| 1307 | * #isSet(int) isSet()} will return <code>false</code> for all the | ||
| 1308 | * calendar fields, and the date and time calculations will treat | ||
| 1309 | * the fields as if they had never been set. A | ||
| 1310 | * <code>Calendar</code> implementation class may use its specific | ||
| 1311 | * default field values for date/time calculations. For example, | ||
| 1312 | * <code>GregorianCalendar</code> uses 1970 if the | ||
| 1313 | * <code>YEAR</code> field value is undefined. | ||
| 1314 | * | ||
| 1315 | * @see #clear(int) | ||
| 1316 | */ | ||
| 1317 | public final void clear() | ||
| 1318 | { | ||
| 1319 | for (int i = 0; i < fields.length; ) { | ||
| 1320 | stamp[i] = fields[i] = 0; // UNSET == 0 | ||
| 1321 | isSet[i++] = false; | ||
| 1322 | } | ||
| 1323 | areAllFieldsSet = areFieldsSet = false; | ||
| 1324 | isTimeSet = false; | ||
| 1325 | } | ||
| 1326 | |||
| 1327 | /** | ||
| 1328 | * Sets the given calendar field value and the time value | ||
| 1329 | * (millisecond offset from the <a href="#Epoch">Epoch</a>) of | ||
| 1330 | * this <code>Calendar</code> undefined. This means that {@link | ||
| 1331 | * #isSet(int) isSet(field)} will return <code>false</code>, and | ||
| 1332 | * the date and time calculations will treat the field as if it | ||
| 1333 | * had never been set. A <code>Calendar</code> implementation | ||
| 1334 | * class may use the field's specific default value for date and | ||
| 1335 | * time calculations. | ||
| 1336 | * | ||
| 1337 | * <p>The {@link #HOUR_OF_DAY}, {@link #HOUR} and {@link #AM_PM} | ||
| 1338 | * fields are handled independently and the <a | ||
| 1339 | * href="#time_resolution">the resolution rule for the time of | ||
| 1340 | * day</a> is applied. Clearing one of the fields doesn't reset | ||
| 1341 | * the hour of day value of this <code>Calendar</code>. Use {@link | ||
| 1342 | * #set(int,int) set(Calendar.HOUR_OF_DAY, 0)} to reset the hour | ||
| 1343 | * value. | ||
| 1344 | * | ||
| 1345 | * @param field the calendar field to be cleared. | ||
| 1346 | * @see #clear() | ||
| 1347 | */ | ||
| 1348 | public final void clear(int field) | ||
| 1349 | { | ||
| 1350 | fields[field] = 0; | ||
| 1351 | stamp[field] = UNSET; | ||
| 1352 | isSet[field] = false; | ||
| 1353 | |||
| 1354 | areAllFieldsSet = areFieldsSet = false; | ||
| 1355 | isTimeSet = false; | ||
| 1356 | } | ||
| 1357 | |||
| 1358 | /** | ||
| 1359 | * Determines if the given calendar field has a value set, | ||
| 1360 | * including cases that the value has been set by internal fields | ||
| 1361 | * calculations triggered by a <code>get</code> method call. | ||
| 1362 | * | ||
| 1363 | * @return <code>true</code> if the given calendar field has a value set; | ||
| 1364 | * <code>false</code> otherwise. | ||
| 1365 | */ | ||
| 1366 | public final boolean isSet(int field) | ||
| 1367 | { | ||
| 1368 | return stamp[field] != UNSET; | ||
| 1369 | } | ||
| 1370 | |||
| 1371 | /** | ||
| 1372 | * Returns the string representation of the calendar | ||
| 1373 | * <code>field</code> value in the given <code>style</code> and | ||
| 1374 | * <code>locale</code>. If no string representation is | ||
| 1375 | * applicable, <code>null</code> is returned. This method calls | ||
| 1376 | * {@link Calendar#get(int) get(field)} to get the calendar | ||
| 1377 | * <code>field</code> value if the string representation is | ||
| 1378 | * applicable to the given calendar <code>field</code>. | ||
| 1379 | * | ||
| 1380 | * <p>For example, if this <code>Calendar</code> is a | ||
| 1381 | * <code>GregorianCalendar</code> and its date is 2005-01-01, then | ||
| 1382 | * the string representation of the {@link #MONTH} field would be | ||
| 1383 | * "January" in the long style in an English locale or "Jan" in | ||
| 1384 | * the short style. However, no string representation would be | ||
| 1385 | * available for the {@link #DAY_OF_MONTH} field, and this method | ||
| 1386 | * would return <code>null</code>. | ||
| 1387 | * | ||
| 1388 | * <p>The default implementation supports the calendar fields for | ||
| 1389 | * which a {@link DateFormatSymbols} has names in the given | ||
| 1390 | * <code>locale</code>. | ||
| 1391 | * | ||
| 1392 | * @param field | ||
| 1393 | * the calendar field for which the string representation | ||
| 1394 | * is returned | ||
| 1395 | * @param style | ||
| 1396 | * the style applied to the string representation; one of | ||
| 1397 | * {@link #SHORT} or {@link #LONG}. | ||
| 1398 | * @param locale | ||
| 1399 | * the locale for the string representation | ||
| 1400 | * @return the string representation of the given | ||
| 1401 | * <code>field</code> in the given <code>style</code>, or | ||
| 1402 | * <code>null</code> if no string representation is | ||
| 1403 | * applicable. | ||
| 1404 | * @exception IllegalArgumentException | ||
| 1405 | * if <code>field</code> or <code>style</code> is invalid, | ||
| 1406 | * or if this <code>Calendar</code> is non-lenient and any | ||
| 1407 | * of the calendar fields have invalid values | ||
| 1408 | * @exception NullPointerException | ||
| 1409 | * if <code>locale</code> is null | ||
| 1410 | * @since 1.6 | ||
| 1411 | */ | ||
| 1412 | public String getDisplayName(int field, int style, Locale locale) { | ||
| 1413 | if (!checkDisplayNameParams(field, style, ALL_STYLES, LONG, locale, | ||
| 1414 | ERA_MASK|MONTH_MASK|DAY_OF_WEEK_MASK|AM_PM_MASK)) { | ||
| 1415 | return null; | ||
| 1416 | } | ||
| 1417 | |||
| 1418 | DateFormatSymbols symbols = DateFormatSymbols.getInstance(locale); | ||
| 1419 | String[] strings = getFieldStrings(field, style, symbols); | ||
| 1420 | if (strings != null) { | ||
| 1421 | int fieldValue = get(field); | ||
| 1422 | if (fieldValue < strings.length) { | ||
| 1423 | return strings[fieldValue]; | ||
| 1424 | } | ||
| 1425 | } | ||
| 1426 | return null; | ||
| 1427 | } | ||
| 1428 | |||
| 1429 | /** | ||
| 1430 | * Returns a <code>Map</code> containing all names of the calendar | ||
| 1431 | * <code>field</code> in the given <code>style</code> and | ||
| 1432 | * <code>locale</code> and their corresponding field values. For | ||
| 1433 | * example, if this <code>Calendar</code> is a {@link | ||
| 1434 | * GregorianCalendar}, the returned map would contain "Jan" to | ||
| 1435 | * {@link #JANUARY}, "Feb" to {@link #FEBRUARY}, and so on, in the | ||
| 1436 | * {@linkplain #SHORT short} style in an English locale. | ||
| 1437 | * | ||
| 1438 | * <p>The values of other calendar fields may be taken into | ||
| 1439 | * account to determine a set of display names. For example, if | ||
| 1440 | * this <code>Calendar</code> is a lunisolar calendar system and | ||
| 1441 | * the year value given by the {@link #YEAR} field has a leap | ||
| 1442 | * month, this method would return month names containing the leap | ||
| 1443 | * month name, and month names are mapped to their values specific | ||
| 1444 | * for the year. | ||
| 1445 | * | ||
| 1446 | * <p>The default implementation supports display names contained in | ||
| 1447 | * a {@link DateFormatSymbols}. For example, if <code>field</code> | ||
| 1448 | * is {@link #MONTH} and <code>style</code> is {@link | ||
| 1449 | * #ALL_STYLES}, this method returns a <code>Map</code> containing | ||
| 1450 | * all strings returned by {@link DateFormatSymbols#getShortMonths()} | ||
| 1451 | * and {@link DateFormatSymbols#getMonths()}. | ||
| 1452 | * | ||
| 1453 | * @param field | ||
| 1454 | * the calendar field for which the display names are returned | ||
| 1455 | * @param style | ||
| 1456 | * the style applied to the display names; one of {@link | ||
| 1457 | * #SHORT}, {@link #LONG}, or {@link #ALL_STYLES}. | ||
| 1458 | * @param locale | ||
| 1459 | * the locale for the display names | ||
| 1460 | * @return a <code>Map</code> containing all display names in | ||
| 1461 | * <code>style</code> and <code>locale</code> and their | ||
| 1462 | * field values, or <code>null</code> if no display names | ||
| 1463 | * are defined for <code>field</code> | ||
| 1464 | * @exception IllegalArgumentException | ||
| 1465 | * if <code>field</code> or <code>style</code> is invalid, | ||
| 1466 | * or if this <code>Calendar</code> is non-lenient and any | ||
| 1467 | * of the calendar fields have invalid values | ||
| 1468 | * @exception NullPointerException | ||
| 1469 | * if <code>locale</code> is null | ||
| 1470 | * @since 1.6 | ||
| 1471 | */ | ||
| 1472 | public Map<String, Integer> getDisplayNames(int field, int style, Locale locale) { | ||
| 1473 | if (!checkDisplayNameParams(field, style, ALL_STYLES, LONG, locale, | ||
| 1474 | ERA_MASK|MONTH_MASK|DAY_OF_WEEK_MASK|AM_PM_MASK)) { | ||
| 1475 | return null; | ||
| 1476 | } | ||
| 1477 | |||
| 1478 | // ALL_STYLES | ||
| 1479 | if (style == ALL_STYLES) { | ||
| 1480 | Map<String,Integer> shortNames = getDisplayNamesImpl(field, SHORT, locale); | ||
| 1481 | if (field == ERA || field == AM_PM) { | ||
| 1482 | return shortNames; | ||
| 1483 | } | ||
| 1484 | Map<String,Integer> longNames = getDisplayNamesImpl(field, LONG, locale); | ||
| 1485 | if (shortNames == null) { | ||
| 1486 | return longNames; | ||
| 1487 | } | ||
| 1488 | if (longNames != null) { | ||
| 1489 | shortNames.putAll(longNames); | ||
| 1490 | } | ||
| 1491 | return shortNames; | ||
| 1492 | } | ||
| 1493 | |||
| 1494 | // SHORT or LONG | ||
| 1495 | return getDisplayNamesImpl(field, style, locale); | ||
| 1496 | } | ||
| 1497 | |||
| 1498 | private Map<String,Integer> getDisplayNamesImpl(int field, int style, Locale locale) { | ||
| 1499 | DateFormatSymbols symbols = DateFormatSymbols.getInstance(locale); | ||
| 1500 | String[] strings = getFieldStrings(field, style, symbols); | ||
| 1501 | if (strings != null) { | ||
| 1502 | Map<String,Integer> names = new HashMap<String,Integer>(); | ||
| 1503 | for (int i = 0; i < strings.length; i++) { | ||
| 1504 | if (strings[i].length() == 0) { | ||
| 1505 | continue; | ||
| 1506 | } | ||
| 1507 | names.put(strings[i], i); | ||
| 1508 | } | ||
| 1509 | return names; | ||
| 1510 | } | ||
| 1511 | return null; | ||
| 1512 | } | ||
| 1513 | |||
| 1514 | boolean checkDisplayNameParams(int field, int style, int minStyle, int maxStyle, | ||
| 1515 | Locale locale, int fieldMask) { | ||
| 1516 | if (field < 0 || field >= fields.length || | ||
| 1517 | style < minStyle || style > maxStyle) { | ||
| 1518 | throw new IllegalArgumentException(); | ||
| 1519 | } | ||
| 1520 | if (locale == null) { | ||
| 1521 | throw new NullPointerException(); | ||
| 1522 | } | ||
| 1523 | return isFieldSet(fieldMask, field); | ||
| 1524 | } | ||
| 1525 | |||
| 1526 | private String[] getFieldStrings(int field, int style, DateFormatSymbols symbols) { | ||
| 1527 | String[] strings = null; | ||
| 1528 | switch (field) { | ||
| 1529 | case ERA: | ||
| 1530 | strings = symbols.getEras(); | ||
| 1531 | break; | ||
| 1532 | |||
| 1533 | case MONTH: | ||
| 1534 | strings = (style == LONG) ? symbols.getMonths() : symbols.getShortMonths(); | ||
| 1535 | break; | ||
| 1536 | |||
| 1537 | case DAY_OF_WEEK: | ||
| 1538 | strings = (style == LONG) ? symbols.getWeekdays() : symbols.getShortWeekdays(); | ||
| 1539 | break; | ||
| 1540 | |||
| 1541 | case AM_PM: | ||
| 1542 | strings = symbols.getAmPmStrings(); | ||
| 1543 | break; | ||
| 1544 | } | ||
| 1545 | return strings; | ||
| 1546 | } | ||
| 1547 | |||
| 1548 | /** | ||
| 1549 | * Fills in any unset fields in the calendar fields. First, the {@link | ||
| 1550 | * #computeTime()} method is called if the time value (millisecond offset | ||
| 1551 | * from the <a href="#Epoch">Epoch</a>) has not been calculated from | ||
| 1552 | * calendar field values. Then, the {@link #computeFields()} method is | ||
| 1553 | * called to calculate all calendar field values. | ||
| 1554 | */ | ||
| 1555 | protected void complete() | ||
| 1556 | { | ||
| 1557 | if (!isTimeSet) | ||
| 1558 | updateTime(); | ||
| 1559 | if (!areFieldsSet || !areAllFieldsSet) { | ||
| 1560 | computeFields(); // fills in unset fields | ||
| 1561 | areAllFieldsSet = areFieldsSet = true; | ||
| 1562 | } | ||
| 1563 | } | ||
| 1564 | |||
| 1565 | /** | ||
| 1566 | * Returns whether the value of the specified calendar field has been set | ||
| 1567 | * externally by calling one of the setter methods rather than by the | ||
| 1568 | * internal time calculation. | ||
| 1569 | * | ||
| 1570 | * @return <code>true</code> if the field has been set externally, | ||
| 1571 | * <code>false</code> otherwise. | ||
| 1572 | * @exception IndexOutOfBoundsException if the specified | ||
| 1573 | * <code>field</code> is out of range | ||
| 1574 | * (<code>field < 0 || field >= FIELD_COUNT</code>). | ||
| 1575 | * @see #selectFields() | ||
| 1576 | * @see #setFieldsComputed(int) | ||
| 1577 | */ | ||
| 1578 | final boolean isExternallySet(int field) { | ||
| 1579 | return stamp[field] >= MINIMUM_USER_STAMP; | ||
| 1580 | } | ||
| 1581 | |||
| 1582 | /** | ||
| 1583 | * Returns a field mask (bit mask) indicating all calendar fields that | ||
| 1584 | * have the state of externally or internally set. | ||
| 1585 | * | ||
| 1586 | * @return a bit mask indicating set state fields | ||
| 1587 | */ | ||
| 1588 | final int getSetStateFields() { | ||
| 1589 | int mask = 0; | ||
| 1590 | for (int i = 0; i < fields.length; i++) { | ||
| 1591 | if (stamp[i] != UNSET) { | ||
| 1592 | mask |= 1 << i; | ||
| 1593 | } | ||
| 1594 | } | ||
| 1595 | return mask; | ||
| 1596 | } | ||
| 1597 | |||
| 1598 | /** | ||
| 1599 | * Sets the state of the specified calendar fields to | ||
| 1600 | * <em>computed</em>. This state means that the specified calendar fields | ||
| 1601 | * have valid values that have been set by internal time calculation | ||
| 1602 | * rather than by calling one of the setter methods. | ||
| 1603 | * | ||
| 1604 | * @param fieldMask the field to be marked as computed. | ||
| 1605 | * @exception IndexOutOfBoundsException if the specified | ||
| 1606 | * <code>field</code> is out of range | ||
| 1607 | * (<code>field < 0 || field >= FIELD_COUNT</code>). | ||
| 1608 | * @see #isExternallySet(int) | ||
| 1609 | * @see #selectFields() | ||
| 1610 | */ | ||
| 1611 | final void setFieldsComputed(int fieldMask) { | ||
| 1612 | if (fieldMask == ALL_FIELDS) { | ||
| 1613 | for (int i = 0; i < fields.length; i++) { | ||
| 1614 | stamp[i] = COMPUTED; | ||
| 1615 | isSet[i] = true; | ||
| 1616 | } | ||
| 1617 | areFieldsSet = areAllFieldsSet = true; | ||
| 1618 | } else { | ||
| 1619 | for (int i = 0; i < fields.length; i++) { | ||
| 1620 | if ((fieldMask & 1) == 1) { | ||
| 1621 | stamp[i] = COMPUTED; | ||
| 1622 | isSet[i] = true; | ||
| 1623 | } else { | ||
| 1624 | if (areAllFieldsSet && !isSet[i]) { | ||
| 1625 | areAllFieldsSet = false; | ||
| 1626 | } | ||
| 1627 | } | ||
| 1628 | fieldMask >>>= 1; | ||
| 1629 | } | ||
| 1630 | } | ||
| 1631 | } | ||
| 1632 | |||
| 1633 | /** | ||
| 1634 | * Sets the state of the calendar fields that are <em>not</em> specified | ||
| 1635 | * by <code>fieldMask</code> to <em>unset</em>. If <code>fieldMask</code> | ||
| 1636 | * specifies all the calendar fields, then the state of this | ||
| 1637 | * <code>Calendar</code> becomes that all the calendar fields are in sync | ||
| 1638 | * with the time value (millisecond offset from the Epoch). | ||
| 1639 | * | ||
| 1640 | * @param fieldMask the field mask indicating which calendar fields are in | ||
| 1641 | * sync with the time value. | ||
| 1642 | * @exception IndexOutOfBoundsException if the specified | ||
| 1643 | * <code>field</code> is out of range | ||
| 1644 | * (<code>field < 0 || field >= FIELD_COUNT</code>). | ||
| 1645 | * @see #isExternallySet(int) | ||
| 1646 | * @see #selectFields() | ||
| 1647 | */ | ||
| 1648 | final void setFieldsNormalized(int fieldMask) { | ||
| 1649 | if (fieldMask != ALL_FIELDS) { | ||
| 1650 | for (int i = 0; i < fields.length; i++) { | ||
| 1651 | if ((fieldMask & 1) == 0) { | ||
| 1652 | stamp[i] = fields[i] = 0; // UNSET == 0 | ||
| 1653 | isSet[i] = false; | ||
| 1654 | } | ||
| 1655 | fieldMask >>= 1; | ||
| 1656 | } | ||
| 1657 | } | ||
| 1658 | |||
| 1659 | // Some or all of the fields are in sync with the | ||
| 1660 | // milliseconds, but the stamp values are not normalized yet. | ||
| 1661 | areFieldsSet = true; | ||
| 1662 | areAllFieldsSet = false; | ||
| 1663 | } | ||
| 1664 | |||
| 1665 | /** | ||
| 1666 | * Returns whether the calendar fields are partially in sync with the time | ||
| 1667 | * value or fully in sync but not stamp values are not normalized yet. | ||
| 1668 | */ | ||
| 1669 | final boolean isPartiallyNormalized() { | ||
| 1670 | return areFieldsSet && !areAllFieldsSet; | ||
| 1671 | } | ||
| 1672 | |||
| 1673 | /** | ||
| 1674 | * Returns whether the calendar fields are fully in sync with the time | ||
| 1675 | * value. | ||
| 1676 | */ | ||
| 1677 | final boolean isFullyNormalized() { | ||
| 1678 | return areFieldsSet && areAllFieldsSet; | ||
| 1679 | } | ||
| 1680 | |||
| 1681 | /** | ||
| 1682 | * Marks this Calendar as not sync'd. | ||
| 1683 | */ | ||
| 1684 | final void setUnnormalized() { | ||
| 1685 | areFieldsSet = areAllFieldsSet = false; | ||
| 1686 | } | ||
| 1687 | |||
| 1688 | /** | ||
| 1689 | * Returns whether the specified <code>field</code> is on in the | ||
| 1690 | * <code>fieldMask</code>. | ||
| 1691 | */ | ||
| 1692 | static final boolean isFieldSet(int fieldMask, int field) { | ||
| 1693 | return (fieldMask & (1 << field)) != 0; | ||
| 1694 | } | ||
| 1695 | |||
| 1696 | /** | ||
| 1697 | * Returns a field mask indicating which calendar field values | ||
| 1698 | * to be used to calculate the time value. The calendar fields are | ||
| 1699 | * returned as a bit mask, each bit of which corresponds to a field, i.e., | ||
| 1700 | * the mask value of <code>field</code> is <code>(1 << | ||
| 1701 | * field)</code>. For example, 0x26 represents the <code>YEAR</code>, | ||
| 1702 | * <code>MONTH</code>, and <code>DAY_OF_MONTH</code> fields (i.e., 0x26 is | ||
| 1703 | * equal to | ||
| 1704 | * <code>(1<<YEAR)|(1<<MONTH)|(1<<DAY_OF_MONTH))</code>. | ||
| 1705 | * | ||
| 1706 | * <p>This method supports the calendar fields resolution as described in | ||
| 1707 | * the class description. If the bit mask for a given field is on and its | ||
| 1708 | * field has not been set (i.e., <code>isSet(field)</code> is | ||
| 1709 | * <code>false</code>), then the default value of the field has to be | ||
| 1710 | * used, which case means that the field has been selected because the | ||
| 1711 | * selected combination involves the field. | ||
| 1712 | * | ||
| 1713 | * @return a bit mask of selected fields | ||
| 1714 | * @see #isExternallySet(int) | ||
| 1715 | * @see #setInternallySetState(int) | ||
| 1716 | */ | ||
| 1717 | final int selectFields() { | ||
| 1718 | // This implementation has been taken from the GregorianCalendar class. | ||
| 1719 | |||
| 1720 | // The YEAR field must always be used regardless of its SET | ||
| 1721 | // state because YEAR is a mandatory field to determine the date | ||
| 1722 | // and the default value (EPOCH_YEAR) may change through the | ||
| 1723 | // normalization process. | ||
| 1724 | int fieldMask = YEAR_MASK; | ||
| 1725 | |||
| 1726 | if (stamp[ERA] != UNSET) { | ||
| 1727 | fieldMask |= ERA_MASK; | ||
| 1728 | } | ||
| 1729 | // Find the most recent group of fields specifying the day within | ||
| 1730 | // the year. These may be any of the following combinations: | ||
| 1731 | // MONTH + DAY_OF_MONTH | ||
| 1732 | // MONTH + WEEK_OF_MONTH + DAY_OF_WEEK | ||
| 1733 | // MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK | ||
| 1734 | // DAY_OF_YEAR | ||
| 1735 | // WEEK_OF_YEAR + DAY_OF_WEEK | ||
| 1736 | // We look for the most recent of the fields in each group to determine | ||
| 1737 | // the age of the group. For groups involving a week-related field such | ||
| 1738 | // as WEEK_OF_MONTH, DAY_OF_WEEK_IN_MONTH, or WEEK_OF_YEAR, both the | ||
| 1739 | // week-related field and the DAY_OF_WEEK must be set for the group as a | ||
| 1740 | // whole to be considered. (See bug 4153860 - liu 7/24/98.) | ||
| 1741 | int dowStamp = stamp[DAY_OF_WEEK]; | ||
| 1742 | int monthStamp = stamp[MONTH]; | ||
| 1743 | int domStamp = stamp[DAY_OF_MONTH]; | ||
| 1744 | int womStamp = aggregateStamp(stamp[WEEK_OF_MONTH], dowStamp); | ||
| 1745 | int dowimStamp = aggregateStamp(stamp[DAY_OF_WEEK_IN_MONTH], dowStamp); | ||
| 1746 | int doyStamp = stamp[DAY_OF_YEAR]; | ||
| 1747 | int woyStamp = aggregateStamp(stamp[WEEK_OF_YEAR], dowStamp); | ||
| 1748 | |||
| 1749 | int bestStamp = domStamp; | ||
| 1750 | if (womStamp > bestStamp) { | ||
| 1751 | bestStamp = womStamp; | ||
| 1752 | } | ||
| 1753 | if (dowimStamp > bestStamp) { | ||
| 1754 | bestStamp = dowimStamp; | ||
| 1755 | } | ||
| 1756 | if (doyStamp > bestStamp) { | ||
| 1757 | bestStamp = doyStamp; | ||
| 1758 | } | ||
| 1759 | if (woyStamp > bestStamp) { | ||
| 1760 | bestStamp = woyStamp; | ||
| 1761 | } | ||
| 1762 | |||
| 1763 | /* No complete combination exists. Look for WEEK_OF_MONTH, | ||
| 1764 | * DAY_OF_WEEK_IN_MONTH, or WEEK_OF_YEAR alone. Treat DAY_OF_WEEK alone | ||
| 1765 | * as DAY_OF_WEEK_IN_MONTH. | ||
| 1766 | */ | ||
| 1767 | if (bestStamp == UNSET) { | ||
| 1768 | womStamp = stamp[WEEK_OF_MONTH]; | ||
| 1769 | dowimStamp = Math.max(stamp[DAY_OF_WEEK_IN_MONTH], dowStamp); | ||
| 1770 | woyStamp = stamp[WEEK_OF_YEAR]; | ||
| 1771 | bestStamp = Math.max(Math.max(womStamp, dowimStamp), woyStamp); | ||
| 1772 | |||
| 1773 | /* Treat MONTH alone or no fields at all as DAY_OF_MONTH. This may | ||
| 1774 | * result in bestStamp = domStamp = UNSET if no fields are set, | ||
| 1775 | * which indicates DAY_OF_MONTH. | ||
| 1776 | */ | ||
| 1777 | if (bestStamp == UNSET) { | ||
| 1778 | bestStamp = domStamp = monthStamp; | ||
| 1779 | } | ||
| 1780 | } | ||
| 1781 | |||
| 1782 | if (bestStamp == domStamp || | ||
| 1783 | (bestStamp == womStamp && stamp[WEEK_OF_MONTH] >= stamp[WEEK_OF_YEAR]) || | ||
| 1784 | (bestStamp == dowimStamp && stamp[DAY_OF_WEEK_IN_MONTH] >= stamp[WEEK_OF_YEAR])) { | ||
| 1785 | fieldMask |= MONTH_MASK; | ||
| 1786 | if (bestStamp == domStamp) { | ||
| 1787 | fieldMask |= DAY_OF_MONTH_MASK; | ||
| 1788 | } else { | ||
| 1789 | assert (bestStamp == womStamp || bestStamp == dowimStamp); | ||
| 1790 | if (dowStamp != UNSET) { | ||
| 1791 | fieldMask |= DAY_OF_WEEK_MASK; | ||
| 1792 | } | ||
| 1793 | if (womStamp == dowimStamp) { | ||
| 1794 | // When they are equal, give the priority to | ||
| 1795 | // WEEK_OF_MONTH for compatibility. | ||
| 1796 | if (stamp[WEEK_OF_MONTH] >= stamp[DAY_OF_WEEK_IN_MONTH]) { | ||
| 1797 | fieldMask |= WEEK_OF_MONTH_MASK; | ||
| 1798 | } else { | ||
| 1799 | fieldMask |= DAY_OF_WEEK_IN_MONTH_MASK; | ||
| 1800 | } | ||
| 1801 | } else { | ||
| 1802 | if (bestStamp == womStamp) { | ||
| 1803 | fieldMask |= WEEK_OF_MONTH_MASK; | ||
| 1804 | } else { | ||
| 1805 | assert (bestStamp == dowimStamp); | ||
| 1806 | if (stamp[DAY_OF_WEEK_IN_MONTH] != UNSET) { | ||
| 1807 | fieldMask |= DAY_OF_WEEK_IN_MONTH_MASK; | ||
| 1808 | } | ||
| 1809 | } | ||
| 1810 | } | ||
| 1811 | } | ||
| 1812 | } else { | ||
| 1813 | assert (bestStamp == doyStamp || bestStamp == woyStamp || | ||
| 1814 | bestStamp == UNSET); | ||
| 1815 | if (bestStamp == doyStamp) { | ||
| 1816 | fieldMask |= DAY_OF_YEAR_MASK; | ||
| 1817 | } else { | ||
| 1818 | assert (bestStamp == woyStamp); | ||
| 1819 | if (dowStamp != UNSET) { | ||
| 1820 | fieldMask |= DAY_OF_WEEK_MASK; | ||
| 1821 | } | ||
| 1822 | fieldMask |= WEEK_OF_YEAR_MASK; | ||
| 1823 | } | ||
| 1824 | } | ||
| 1825 | |||
| 1826 | // Find the best set of fields specifying the time of day. There | ||
| 1827 | // are only two possibilities here; the HOUR_OF_DAY or the | ||
| 1828 | // AM_PM and the HOUR. | ||
| 1829 | int hourOfDayStamp = stamp[HOUR_OF_DAY]; | ||
| 1830 | int hourStamp = aggregateStamp(stamp[HOUR], stamp[AM_PM]); | ||
| 1831 | bestStamp = (hourStamp > hourOfDayStamp) ? hourStamp : hourOfDayStamp; | ||
| 1832 | |||
| 1833 | // if bestStamp is still UNSET, then take HOUR or AM_PM. (See 4846659) | ||
| 1834 | if (bestStamp == UNSET) { | ||
| 1835 | bestStamp = Math.max(stamp[HOUR], stamp[AM_PM]); | ||
| 1836 | } | ||
| 1837 | |||
| 1838 | // Hours | ||
| 1839 | if (bestStamp != UNSET) { | ||
| 1840 | if (bestStamp == hourOfDayStamp) { | ||
| 1841 | fieldMask |= HOUR_OF_DAY_MASK; | ||
| 1842 | } else { | ||
| 1843 | fieldMask |= HOUR_MASK; | ||
| 1844 | if (stamp[AM_PM] != UNSET) { | ||
| 1845 | fieldMask |= AM_PM_MASK; | ||
| 1846 | } | ||
| 1847 | } | ||
| 1848 | } | ||
| 1849 | if (stamp[MINUTE] != UNSET) { | ||
| 1850 | fieldMask |= MINUTE_MASK; | ||
| 1851 | } | ||
| 1852 | if (stamp[SECOND] != UNSET) { | ||
| 1853 | fieldMask |= SECOND_MASK; | ||
| 1854 | } | ||
| 1855 | if (stamp[MILLISECOND] != UNSET) { | ||
| 1856 | fieldMask |= MILLISECOND_MASK; | ||
| 1857 | } | ||
| 1858 | if (stamp[ZONE_OFFSET] >= MINIMUM_USER_STAMP) { | ||
| 1859 | fieldMask |= ZONE_OFFSET_MASK; | ||
| 1860 | } | ||
| 1861 | if (stamp[DST_OFFSET] >= MINIMUM_USER_STAMP) { | ||
| 1862 | fieldMask |= DST_OFFSET_MASK; | ||
| 1863 | } | ||
| 1864 | |||
| 1865 | return fieldMask; | ||
| 1866 | } | ||
| 1867 | |||
| 1868 | /** | ||
| 1869 | * Returns the pseudo-time-stamp for two fields, given their | ||
| 1870 | * individual pseudo-time-stamps. If either of the fields | ||
| 1871 | * is unset, then the aggregate is unset. Otherwise, the | ||
| 1872 | * aggregate is the later of the two stamps. | ||
| 1873 | */ | ||
| 1874 | private static final int aggregateStamp(int stamp_a, int stamp_b) { | ||
| 1875 | if (stamp_a == UNSET || stamp_b == UNSET) { | ||
| 1876 | return UNSET; | ||
| 1877 | } | ||
| 1878 | return (stamp_a > stamp_b) ? stamp_a : stamp_b; | ||
| 1879 | } | ||
| 1880 | |||
| 1881 | /** | ||
| 1882 | * Compares this <code>Calendar</code> to the specified | ||
| 1883 | * <code>Object</code>. The result is <code>true</code> if and only if | ||
| 1884 | * the argument is a <code>Calendar</code> object of the same calendar | ||
| 1885 | * system that represents the same time value (millisecond offset from the | ||
| 1886 | * <a href="#Epoch">Epoch</a>) under the same | ||
| 1887 | * <code>Calendar</code> parameters as this object. | ||
| 1888 | * | ||
| 1889 | * <p>The <code>Calendar</code> parameters are the values represented | ||
| 1890 | * by the <code>isLenient</code>, <code>getFirstDayOfWeek</code>, | ||
| 1891 | * <code>getMinimalDaysInFirstWeek</code> and <code>getTimeZone</code> | ||
| 1892 | * methods. If there is any difference in those parameters | ||
| 1893 | * between the two <code>Calendar</code>s, this method returns | ||
| 1894 | * <code>false</code>. | ||
| 1895 | * | ||
| 1896 | * <p>Use the {@link #compareTo(Calendar) compareTo} method to | ||
| 1897 | * compare only the time values. | ||
| 1898 | * | ||
| 1899 | * @param obj the object to compare with. | ||
| 1900 | * @return <code>true</code> if this object is equal to <code>obj</code>; | ||
| 1901 | * <code>false</code> otherwise. | ||
| 1902 | */ | ||
| 1903 | public boolean equals(Object obj) { | ||
| 1904 | if (this == obj) | ||
| 1905 | return true; | ||
| 1906 | try { | ||
| 1907 | Calendar that = (Calendar)obj; | ||
| 1908 | return compareTo(getMillisOf(that)) == 0 && | ||
| 1909 | lenient == that.lenient && | ||
| 1910 | firstDayOfWeek == that.firstDayOfWeek && | ||
| 1911 | minimalDaysInFirstWeek == that.minimalDaysInFirstWeek && | ||
| 1912 | zone.equals(that.zone); | ||
| 1913 | } catch (Exception e) { | ||
| 1914 | // Note: GregorianCalendar.computeTime throws | ||
| 1915 | // IllegalArgumentException if the ERA value is invalid | ||
| 1916 | // even it's in lenient mode. | ||
| 1917 | } | ||
| 1918 | return false; | ||
| 1919 | } | ||
| 1920 | |||
| 1921 | /** | ||
| 1922 | * Returns a hash code for this calendar. | ||
| 1923 | * | ||
| 1924 | * @return a hash code value for this object. | ||
| 1925 | * @since 1.2 | ||
| 1926 | */ | ||
| 1927 | public int hashCode() { | ||
| 1928 | // 'otheritems' represents the hash code for the previous versions. | ||
| 1929 | int otheritems = (lenient ? 1 : 0) | ||
| 1930 | | (firstDayOfWeek << 1) | ||
| 1931 | | (minimalDaysInFirstWeek << 4) | ||
| 1932 | | (zone.hashCode() << 7); | ||
| 1933 | long t = getMillisOf(this); | ||
| 1934 | return (int) t ^ (int)(t >> 32) ^ otheritems; | ||
| 1935 | } | ||
| 1936 | |||
| 1937 | /** | ||
| 1938 | * Returns whether this <code>Calendar</code> represents a time | ||
| 1939 | * before the time represented by the specified | ||
| 1940 | * <code>Object</code>. This method is equivalent to: | ||
| 1941 | * <pre><blockquote> | ||
| 1942 | * compareTo(when) < 0 | ||
| 1943 | * </blockquote></pre> | ||
| 1944 | * if and only if <code>when</code> is a <code>Calendar</code> | ||
| 1945 | * instance. Otherwise, the method returns <code>false</code>. | ||
| 1946 | * | ||
| 1947 | * @param when the <code>Object</code> to be compared | ||
| 1948 | * @return <code>true</code> if the time of this | ||
| 1949 | * <code>Calendar</code> is before the time represented by | ||
| 1950 | * <code>when</code>; <code>false</code> otherwise. | ||
| 1951 | * @see #compareTo(Calendar) | ||
| 1952 | */ | ||
| 1953 | public boolean before(Object when) { | ||
| 1954 | return when instanceof Calendar | ||
| 1955 | && compareTo((Calendar)when) < 0; | ||
| 1956 | } | ||
| 1957 | |||
| 1958 | /** | ||
| 1959 | * Returns whether this <code>Calendar</code> represents a time | ||
| 1960 | * after the time represented by the specified | ||
| 1961 | * <code>Object</code>. This method is equivalent to: | ||
| 1962 | * <pre><blockquote> | ||
| 1963 | * compareTo(when) > 0 | ||
| 1964 | * </blockquote></pre> | ||
| 1965 | * if and only if <code>when</code> is a <code>Calendar</code> | ||
| 1966 | * instance. Otherwise, the method returns <code>false</code>. | ||
| 1967 | * | ||
| 1968 | * @param when the <code>Object</code> to be compared | ||
| 1969 | * @return <code>true</code> if the time of this <code>Calendar</code> is | ||
| 1970 | * after the time represented by <code>when</code>; <code>false</code> | ||
| 1971 | * otherwise. | ||
| 1972 | * @see #compareTo(Calendar) | ||
| 1973 | */ | ||
| 1974 | public boolean after(Object when) { | ||
| 1975 | return when instanceof Calendar | ||
| 1976 | && compareTo((Calendar)when) > 0; | ||
| 1977 | } | ||
| 1978 | |||
| 1979 | /** | ||
| 1980 | * Compares the time values (millisecond offsets from the <a | ||
| 1981 | * href="#Epoch">Epoch</a>) represented by two | ||
| 1982 | * <code>Calendar</code> objects. | ||
| 1983 | * | ||
| 1984 | * @param anotherCalendar the <code>Calendar</code> to be compared. | ||
| 1985 | * @return the value <code>0</code> if the time represented by the argument | ||
| 1986 | * is equal to the time represented by this <code>Calendar</code>; a value | ||
| 1987 | * less than <code>0</code> if the time of this <code>Calendar</code> is | ||
| 1988 | * before the time represented by the argument; and a value greater than | ||
| 1989 | * <code>0</code> if the time of this <code>Calendar</code> is after the | ||
| 1990 | * time represented by the argument. | ||
| 1991 | * @exception NullPointerException if the specified <code>Calendar</code> is | ||
| 1992 | * <code>null</code>. | ||
| 1993 | * @exception IllegalArgumentException if the time value of the | ||
| 1994 | * specified <code>Calendar</code> object can't be obtained due to | ||
| 1995 | * any invalid calendar values. | ||
| 1996 | * @since 1.5 | ||
| 1997 | */ | ||
| 1998 | public int compareTo(Calendar anotherCalendar) { | ||
| 1999 | return compareTo(getMillisOf(anotherCalendar)); | ||
| 2000 | } | ||
| 2001 | |||
| 2002 | /** | ||
| 2003 | * Adds or subtracts the specified amount of time to the given calendar field, | ||
| 2004 | * based on the calendar's rules. For example, to subtract 5 days from | ||
| 2005 | * the current time of the calendar, you can achieve it by calling: | ||
| 2006 | * <p><code>add(Calendar.DAY_OF_MONTH, -5)</code>. | ||
| 2007 | * | ||
| 2008 | * @param field the calendar field. | ||
| 2009 | * @param amount the amount of date or time to be added to the field. | ||
| 2010 | * @see #roll(int,int) | ||
| 2011 | * @see #set(int,int) | ||
| 2012 | */ | ||
| 2013 | abstract public void add(int field, int amount); | ||
| 2014 | |||
| 2015 | /** | ||
| 2016 | * Adds or subtracts (up/down) a single unit of time on the given time | ||
| 2017 | * field without changing larger fields. For example, to roll the current | ||
| 2018 | * date up by one day, you can achieve it by calling: | ||
| 2019 | * <p>roll(Calendar.DATE, true). | ||
| 2020 | * When rolling on the year or Calendar.YEAR field, it will roll the year | ||
| 2021 | * value in the range between 1 and the value returned by calling | ||
| 2022 | * <code>getMaximum(Calendar.YEAR)</code>. | ||
| 2023 | * When rolling on the month or Calendar.MONTH field, other fields like | ||
| 2024 | * date might conflict and, need to be changed. For instance, | ||
| 2025 | * rolling the month on the date 01/31/96 will result in 02/29/96. | ||
| 2026 | * When rolling on the hour-in-day or Calendar.HOUR_OF_DAY field, it will | ||
| 2027 | * roll the hour value in the range between 0 and 23, which is zero-based. | ||
| 2028 | * | ||
| 2029 | * @param field the time field. | ||
| 2030 | * @param up indicates if the value of the specified time field is to be | ||
| 2031 | * rolled up or rolled down. Use true if rolling up, false otherwise. | ||
| 2032 | * @see Calendar#add(int,int) | ||
| 2033 | * @see Calendar#set(int,int) | ||
| 2034 | */ | ||
| 2035 | abstract public void roll(int field, boolean up); | ||
| 2036 | |||
| 2037 | /** | ||
| 2038 | * Adds the specified (signed) amount to the specified calendar field | ||
| 2039 | * without changing larger fields. A negative amount means to roll | ||
| 2040 | * down. | ||
| 2041 | * | ||
| 2042 | * <p>NOTE: This default implementation on <code>Calendar</code> just repeatedly calls the | ||
| 2043 | * version of {@link #roll(int,boolean) roll()} that rolls by one unit. This may not | ||
| 2044 | * always do the right thing. For example, if the <code>DAY_OF_MONTH</code> field is 31, | ||
| 2045 | * rolling through February will leave it set to 28. The <code>GregorianCalendar</code> | ||
| 2046 | * version of this function takes care of this problem. Other subclasses | ||
| 2047 | * should also provide overrides of this function that do the right thing. | ||
| 2048 | * | ||
| 2049 | * @param field the calendar field. | ||
| 2050 | * @param amount the signed amount to add to the calendar <code>field</code>. | ||
| 2051 | * @since 1.2 | ||
| 2052 | * @see #roll(int,boolean) | ||
| 2053 | * @see #add(int,int) | ||
| 2054 | * @see #set(int,int) | ||
| 2055 | */ | ||
| 2056 | public void roll(int field, int amount) | ||
| 2057 | { | ||
| 2058 | while (amount > 0) { | ||
| 2059 | roll(field, true); | ||
| 2060 | amount--; | ||
| 2061 | } | ||
| 2062 | while (amount < 0) { | ||
| 2063 | roll(field, false); | ||
| 2064 | amount++; | ||
| 2065 | } | ||
| 2066 | } | ||
| 2067 | |||
| 2068 | /** | ||
| 2069 | * Sets the time zone with the given time zone value. | ||
| 2070 | * | ||
| 2071 | * @param value the given time zone. | ||
| 2072 | */ | ||
| 2073 | public void setTimeZone(TimeZone value) | ||
| 2074 | { | ||
| 2075 | zone = value; | ||
| 2076 | sharedZone = false; | ||
| 2077 | /* Recompute the fields from the time using the new zone. This also | ||
| 2078 | * works if isTimeSet is false (after a call to set()). In that case | ||
| 2079 | * the time will be computed from the fields using the new zone, then | ||
| 2080 | * the fields will get recomputed from that. Consider the sequence of | ||
| 2081 | * calls: cal.setTimeZone(EST); cal.set(HOUR, 1); cal.setTimeZone(PST). | ||
| 2082 | * Is cal set to 1 o'clock EST or 1 o'clock PST? Answer: PST. More | ||
| 2083 | * generally, a call to setTimeZone() affects calls to set() BEFORE AND | ||
| 2084 | * AFTER it up to the next call to complete(). | ||
| 2085 | */ | ||
| 2086 | areAllFieldsSet = areFieldsSet = false; | ||
| 2087 | } | ||
| 2088 | |||
| 2089 | /** | ||
| 2090 | * Gets the time zone. | ||
| 2091 | * | ||
| 2092 | * @return the time zone object associated with this calendar. | ||
| 2093 | */ | ||
| 2094 | public TimeZone getTimeZone() | ||
| 2095 | { | ||
| 2096 | // If the TimeZone object is shared by other Calendar instances, then | ||
| 2097 | // create a clone. | ||
| 2098 | if (sharedZone) { | ||
| 2099 | zone = (TimeZone) zone.clone(); | ||
| 2100 | sharedZone = false; | ||
| 2101 | } | ||
| 2102 | return zone; | ||
| 2103 | } | ||
| 2104 | |||
| 2105 | /** | ||
| 2106 | * Returns the time zone (without cloning). | ||
| 2107 | */ | ||
| 2108 | TimeZone getZone() { | ||
| 2109 | return zone; | ||
| 2110 | } | ||
| 2111 | |||
| 2112 | /** | ||
| 2113 | * Sets the sharedZone flag to <code>shared</code>. | ||
| 2114 | */ | ||
| 2115 | void setZoneShared(boolean shared) { | ||
| 2116 | sharedZone = shared; | ||
| 2117 | } | ||
| 2118 | |||
| 2119 | /** | ||
| 2120 | * Specifies whether or not date/time interpretation is to be lenient. With | ||
| 2121 | * lenient interpretation, a date such as "February 942, 1996" will be | ||
| 2122 | * treated as being equivalent to the 941st day after February 1, 1996. | ||
| 2123 | * With strict (non-lenient) interpretation, such dates will cause an exception to be | ||
| 2124 | * thrown. The default is lenient. | ||
| 2125 | * | ||
| 2126 | * @param lenient <code>true</code> if the lenient mode is to be turned | ||
| 2127 | * on; <code>false</code> if it is to be turned off. | ||
| 2128 | * @see #isLenient() | ||
| 2129 | * @see java.text.DateFormat#setLenient | ||
| 2130 | */ | ||
| 2131 | public void setLenient(boolean lenient) | ||
| 2132 | { | ||
| 2133 | this.lenient = lenient; | ||
| 2134 | } | ||
| 2135 | |||
| 2136 | /** | ||
| 2137 | * Tells whether date/time interpretation is to be lenient. | ||
| 2138 | * | ||
| 2139 | * @return <code>true</code> if the interpretation mode of this calendar is lenient; | ||
| 2140 | * <code>false</code> otherwise. | ||
| 2141 | * @see #setLenient(boolean) | ||
| 2142 | */ | ||
| 2143 | public boolean isLenient() | ||
| 2144 | { | ||
| 2145 | return lenient; | ||
| 2146 | } | ||
| 2147 | |||
| 2148 | /** | ||
| 2149 | * Sets what the first day of the week is; e.g., <code>SUNDAY</code> in the U.S., | ||
| 2150 | * <code>MONDAY</code> in France. | ||
| 2151 | * | ||
| 2152 | * @param value the given first day of the week. | ||
| 2153 | * @see #getFirstDayOfWeek() | ||
| 2154 | * @see #getMinimalDaysInFirstWeek() | ||
| 2155 | */ | ||
| 2156 | public void setFirstDayOfWeek(int value) | ||
| 2157 | { | ||
| 2158 | if (firstDayOfWeek == value) { | ||
| 2159 | return; | ||
| 2160 | } | ||
| 2161 | firstDayOfWeek = value; | ||
| 2162 | invalidateWeekFields(); | ||
| 2163 | } | ||
| 2164 | |||
| 2165 | /** | ||
| 2166 | * Gets what the first day of the week is; e.g., <code>SUNDAY</code> in the U.S., | ||
| 2167 | * <code>MONDAY</code> in France. | ||
| 2168 | * | ||
| 2169 | * @return the first day of the week. | ||
| 2170 | * @see #setFirstDayOfWeek(int) | ||
| 2171 | * @see #getMinimalDaysInFirstWeek() | ||
| 2172 | */ | ||
| 2173 | public int getFirstDayOfWeek() | ||
| 2174 | { | ||
| 2175 | return firstDayOfWeek; | ||
| 2176 | } | ||
| 2177 | |||
| 2178 | /** | ||
| 2179 | * Sets what the minimal days required in the first week of the year are; | ||
| 2180 | * For example, if the first week is defined as one that contains the first | ||
| 2181 | * day of the first month of a year, call this method with value 1. If it | ||
| 2182 | * must be a full week, use value 7. | ||
| 2183 | * | ||
| 2184 | * @param value the given minimal days required in the first week | ||
| 2185 | * of the year. | ||
| 2186 | * @see #getMinimalDaysInFirstWeek() | ||
| 2187 | */ | ||
| 2188 | public void setMinimalDaysInFirstWeek(int value) | ||
| 2189 | { | ||
| 2190 | if (minimalDaysInFirstWeek == value) { | ||
| 2191 | return; | ||
| 2192 | } | ||
| 2193 | minimalDaysInFirstWeek = value; | ||
| 2194 | invalidateWeekFields(); | ||
| 2195 | } | ||
| 2196 | |||
| 2197 | /** | ||
| 2198 | * Gets what the minimal days required in the first week of the year are; | ||
| 2199 | * e.g., if the first week is defined as one that contains the first day | ||
| 2200 | * of the first month of a year, this method returns 1. If | ||
| 2201 | * the minimal days required must be a full week, this method | ||
| 2202 | * returns 7. | ||
| 2203 | * | ||
| 2204 | * @return the minimal days required in the first week of the year. | ||
| 2205 | * @see #setMinimalDaysInFirstWeek(int) | ||
| 2206 | */ | ||
| 2207 | public int getMinimalDaysInFirstWeek() | ||
| 2208 | { | ||
| 2209 | return minimalDaysInFirstWeek; | ||
| 2210 | } | ||
| 2211 | |||
| 2212 | /** | ||
| 2213 | * Returns whether this {@code Calendar} supports week dates. | ||
| 2214 | * | ||
| 2215 | * <p>The default implementation of this method returns {@code false}. | ||
| 2216 | * | ||
| 2217 | * @return {@code true} if this {@code Calendar} supports week dates; | ||
| 2218 | * {@code false} otherwise. | ||
| 2219 | * @see #getWeekYear() | ||
| 2220 | * @see #setWeekDate(int,int,int) | ||
| 2221 | * @see #getWeeksInWeekYear() | ||
| 2222 | * @since 1.7 | ||
| 2223 | */ | ||
| 2224 | public boolean isWeekDateSupported() { | ||
| 2225 | return false; | ||
| 2226 | } | ||
| 2227 | |||
| 2228 | /** | ||
| 2229 | * Returns the week year represented by this {@code Calendar}. The | ||
| 2230 | * week year is in sync with the week cycle. The {@linkplain | ||
| 2231 | * #getFirstDayOfWeek() first day of the first week} is the first | ||
| 2232 | * day of the week year. | ||
| 2233 | * | ||
| 2234 | * <p>The default implementation of this method throws an | ||
| 2235 | * {@link UnsupportedOperationException}. | ||
| 2236 | * | ||
| 2237 | * @return the week year of this {@code Calendar} | ||
| 2238 | * @exception UnsupportedOperationException | ||
| 2239 | * if any week year numbering isn't supported | ||
| 2240 | * in this {@code Calendar}. | ||
| 2241 | * @see #isWeekDateSupported() | ||
| 2242 | * @see #getFirstDayOfWeek() | ||
| 2243 | * @see #getMinimalDaysInFirstWeek() | ||
| 2244 | * @since 1.7 | ||
| 2245 | */ | ||
| 2246 | public int getWeekYear() { | ||
| 2247 | throw new UnsupportedOperationException(); | ||
| 2248 | } | ||
| 2249 | |||
| 2250 | /** | ||
| 2251 | * Sets the date of this {@code Calendar} with the the given date | ||
| 2252 | * specifiers - week year, week of year, and day of week. | ||
| 2253 | * | ||
| 2254 | * <p>Unlike the {@code set} method, all of the calendar fields | ||
| 2255 | * and {@code time} values are calculated upon return. | ||
| 2256 | * | ||
| 2257 | * <p>If {@code weekOfYear} is out of the valid week-of-year range | ||
| 2258 | * in {@code weekYear}, the {@code weekYear} and {@code | ||
| 2259 | * weekOfYear} values are adjusted in lenient mode, or an {@code | ||
| 2260 | * IllegalArgumentException} is thrown in non-lenient mode. | ||
| 2261 | * | ||
| 2262 | * <p>The default implementation of this method throws an | ||
| 2263 | * {@code UnsupportedOperationException}. | ||
| 2264 | * | ||
| 2265 | * @param weekYear the week year | ||
| 2266 | * @param weekOfYear the week number based on {@code weekYear} | ||
| 2267 | * @param dayOfWeek the day of week value: one of the constants | ||
| 2268 | * for the {@link #DAY_OF_WEEK} field: {@link | ||
| 2269 | * #SUNDAY}, ..., {@link #SATURDAY}. | ||
| 2270 | * @exception IllegalArgumentException | ||
| 2271 | * if any of the given date specifiers is invalid | ||
| 2272 | * or any of the calendar fields are inconsistent | ||
| 2273 | * with the given date specifiers in non-lenient mode | ||
| 2274 | * @exception UnsupportedOperationException | ||
| 2275 | * if any week year numbering isn't supported in this | ||
| 2276 | * {@code Calendar}. | ||
| 2277 | * @see #isWeekDateSupported() | ||
| 2278 | * @see #getFirstDayOfWeek() | ||
| 2279 | * @see #getMinimalDaysInFirstWeek() | ||
| 2280 | * @since 1.7 | ||
| 2281 | */ | ||
| 2282 | public void setWeekDate(int weekYear, int weekOfYear, int dayOfWeek) { | ||
| 2283 | throw new UnsupportedOperationException(); | ||
| 2284 | } | ||
| 2285 | |||
| 2286 | /** | ||
| 2287 | * Returns the number of weeks in the week year represented by this | ||
| 2288 | * {@code Calendar}. | ||
| 2289 | * | ||
| 2290 | * <p>The default implementation of this method throws an | ||
| 2291 | * {@code UnsupportedOperationException}. | ||
| 2292 | * | ||
| 2293 | * @return the number of weeks in the week year. | ||
| 2294 | * @exception UnsupportedOperationException | ||
| 2295 | * if any week year numbering isn't supported in this | ||
| 2296 | * {@code Calendar}. | ||
| 2297 | * @see #WEEK_OF_YEAR | ||
| 2298 | * @see #isWeekDateSupported() | ||
| 2299 | * @see #getWeekYear() | ||
| 2300 | * @see #getActualMaximum(int) | ||
| 2301 | * @since 1.7 | ||
| 2302 | */ | ||
| 2303 | public int getWeeksInWeekYear() { | ||
| 2304 | throw new UnsupportedOperationException(); | ||
| 2305 | } | ||
| 2306 | |||
| 2307 | /** | ||
| 2308 | * Returns the minimum value for the given calendar field of this | ||
| 2309 | * <code>Calendar</code> instance. The minimum value is defined as | ||
| 2310 | * the smallest value returned by the {@link #get(int) get} method | ||
| 2311 | * for any possible time value. The minimum value depends on | ||
| 2312 | * calendar system specific parameters of the instance. | ||
| 2313 | * | ||
| 2314 | * @param field the calendar field. | ||
| 2315 | * @return the minimum value for the given calendar field. | ||
| 2316 | * @see #getMaximum(int) | ||
| 2317 | * @see #getGreatestMinimum(int) | ||
| 2318 | * @see #getLeastMaximum(int) | ||
| 2319 | * @see #getActualMinimum(int) | ||
| 2320 | * @see #getActualMaximum(int) | ||
| 2321 | */ | ||
| 2322 | abstract public int getMinimum(int field); | ||
| 2323 | |||
| 2324 | /** | ||
| 2325 | * Returns the maximum value for the given calendar field of this | ||
| 2326 | * <code>Calendar</code> instance. The maximum value is defined as | ||
| 2327 | * the largest value returned by the {@link #get(int) get} method | ||
| 2328 | * for any possible time value. The maximum value depends on | ||
| 2329 | * calendar system specific parameters of the instance. | ||
| 2330 | * | ||
| 2331 | * @param field the calendar field. | ||
| 2332 | * @return the maximum value for the given calendar field. | ||
| 2333 | * @see #getMinimum(int) | ||
| 2334 | * @see #getGreatestMinimum(int) | ||
| 2335 | * @see #getLeastMaximum(int) | ||
| 2336 | * @see #getActualMinimum(int) | ||
| 2337 | * @see #getActualMaximum(int) | ||
| 2338 | */ | ||
| 2339 | abstract public int getMaximum(int field); | ||
| 2340 | |||
| 2341 | /** | ||
| 2342 | * Returns the highest minimum value for the given calendar field | ||
| 2343 | * of this <code>Calendar</code> instance. The highest minimum | ||
| 2344 | * value is defined as the largest value returned by {@link | ||
| 2345 | * #getActualMinimum(int)} for any possible time value. The | ||
| 2346 | * greatest minimum value depends on calendar system specific | ||
| 2347 | * parameters of the instance. | ||
| 2348 | * | ||
| 2349 | * @param field the calendar field. | ||
| 2350 | * @return the highest minimum value for the given calendar field. | ||
| 2351 | * @see #getMinimum(int) | ||
| 2352 | * @see #getMaximum(int) | ||
| 2353 | * @see #getLeastMaximum(int) | ||
| 2354 | * @see #getActualMinimum(int) | ||
| 2355 | * @see #getActualMaximum(int) | ||
| 2356 | */ | ||
| 2357 | abstract public int getGreatestMinimum(int field); | ||
| 2358 | |||
| 2359 | /** | ||
| 2360 | * Returns the lowest maximum value for the given calendar field | ||
| 2361 | * of this <code>Calendar</code> instance. The lowest maximum | ||
| 2362 | * value is defined as the smallest value returned by {@link | ||
| 2363 | * #getActualMaximum(int)} for any possible time value. The least | ||
| 2364 | * maximum value depends on calendar system specific parameters of | ||
| 2365 | * the instance. For example, a <code>Calendar</code> for the | ||
| 2366 | * Gregorian calendar system returns 28 for the | ||
| 2367 | * <code>DAY_OF_MONTH</code> field, because the 28th is the last | ||
| 2368 | * day of the shortest month of this calendar, February in a | ||
| 2369 | * common year. | ||
| 2370 | * | ||
| 2371 | * @param field the calendar field. | ||
| 2372 | * @return the lowest maximum value for the given calendar field. | ||
| 2373 | * @see #getMinimum(int) | ||
| 2374 | * @see #getMaximum(int) | ||
| 2375 | * @see #getGreatestMinimum(int) | ||
| 2376 | * @see #getActualMinimum(int) | ||
| 2377 | * @see #getActualMaximum(int) | ||
| 2378 | */ | ||
| 2379 | abstract public int getLeastMaximum(int field); | ||
| 2380 | |||
| 2381 | /** | ||
| 2382 | * Returns the minimum value that the specified calendar field | ||
| 2383 | * could have, given the time value of this <code>Calendar</code>. | ||
| 2384 | * | ||
| 2385 | * <p>The default implementation of this method uses an iterative | ||
| 2386 | * algorithm to determine the actual minimum value for the | ||
| 2387 | * calendar field. Subclasses should, if possible, override this | ||
| 2388 | * with a more efficient implementation - in many cases, they can | ||
| 2389 | * simply return <code>getMinimum()</code>. | ||
| 2390 | * | ||
| 2391 | * @param field the calendar field | ||
| 2392 | * @return the minimum of the given calendar field for the time | ||
| 2393 | * value of this <code>Calendar</code> | ||
| 2394 | * @see #getMinimum(int) | ||
| 2395 | * @see #getMaximum(int) | ||
| 2396 | * @see #getGreatestMinimum(int) | ||
| 2397 | * @see #getLeastMaximum(int) | ||
| 2398 | * @see #getActualMaximum(int) | ||
| 2399 | * @since 1.2 | ||
| 2400 | */ | ||
| 2401 | public int getActualMinimum(int field) { | ||
| 2402 | int fieldValue = getGreatestMinimum(field); | ||
| 2403 | int endValue = getMinimum(field); | ||
| 2404 | |||
| 2405 | // if we know that the minimum value is always the same, just return it | ||
| 2406 | if (fieldValue == endValue) { | ||
| 2407 | return fieldValue; | ||
| 2408 | } | ||
| 2409 | |||
| 2410 | // clone the calendar so we don't mess with the real one, and set it to | ||
| 2411 | // accept anything for the field values | ||
| 2412 | Calendar work = (Calendar)this.clone(); | ||
| 2413 | work.setLenient(true); | ||
| 2414 | |||
| 2415 | // now try each value from getLeastMaximum() to getMaximum() one by one until | ||
| 2416 | // we get a value that normalizes to another value. The last value that | ||
| 2417 | // normalizes to itself is the actual minimum for the current date | ||
| 2418 | int result = fieldValue; | ||
| 2419 | |||
| 2420 | do { | ||
| 2421 | work.set(field, fieldValue); | ||
| 2422 | if (work.get(field) != fieldValue) { | ||
| 2423 | break; | ||
| 2424 | } else { | ||
| 2425 | result = fieldValue; | ||
| 2426 | fieldValue--; | ||
| 2427 | } | ||
| 2428 | } while (fieldValue >= endValue); | ||
| 2429 | |||
| 2430 | return result; | ||
| 2431 | } | ||
| 2432 | |||
| 2433 | /** | ||
| 2434 | * Returns the maximum value that the specified calendar field | ||
| 2435 | * could have, given the time value of this | ||
| 2436 | * <code>Calendar</code>. For example, the actual maximum value of | ||
| 2437 | * the <code>MONTH</code> field is 12 in some years, and 13 in | ||
| 2438 | * other years in the Hebrew calendar system. | ||
| 2439 | * | ||
| 2440 | * <p>The default implementation of this method uses an iterative | ||
| 2441 | * algorithm to determine the actual maximum value for the | ||
| 2442 | * calendar field. Subclasses should, if possible, override this | ||
| 2443 | * with a more efficient implementation. | ||
| 2444 | * | ||
| 2445 | * @param field the calendar field | ||
| 2446 | * @return the maximum of the given calendar field for the time | ||
| 2447 | * value of this <code>Calendar</code> | ||
| 2448 | * @see #getMinimum(int) | ||
| 2449 | * @see #getMaximum(int) | ||
| 2450 | * @see #getGreatestMinimum(int) | ||
| 2451 | * @see #getLeastMaximum(int) | ||
| 2452 | * @see #getActualMinimum(int) | ||
| 2453 | * @since 1.2 | ||
| 2454 | */ | ||
| 2455 | public int getActualMaximum(int field) { | ||
| 2456 | int fieldValue = getLeastMaximum(field); | ||
| 2457 | int endValue = getMaximum(field); | ||
| 2458 | |||
| 2459 | // if we know that the maximum value is always the same, just return it. | ||
| 2460 | if (fieldValue == endValue) { | ||
| 2461 | return fieldValue; | ||
| 2462 | } | ||
| 2463 | |||
| 2464 | // clone the calendar so we don't mess with the real one, and set it to | ||
| 2465 | // accept anything for the field values. | ||
| 2466 | Calendar work = (Calendar)this.clone(); | ||
| 2467 | work.setLenient(true); | ||
| 2468 | |||
| 2469 | // if we're counting weeks, set the day of the week to Sunday. We know the | ||
| 2470 | // last week of a month or year will contain the first day of the week. | ||
| 2471 | if (field == WEEK_OF_YEAR || field == WEEK_OF_MONTH) | ||
| 2472 | work.set(DAY_OF_WEEK, firstDayOfWeek); | ||
| 2473 | |||
| 2474 | // now try each value from getLeastMaximum() to getMaximum() one by one until | ||
| 2475 | // we get a value that normalizes to another value. The last value that | ||
| 2476 | // normalizes to itself is the actual maximum for the current date | ||
| 2477 | int result = fieldValue; | ||
| 2478 | |||
| 2479 | do { | ||
| 2480 | work.set(field, fieldValue); | ||
| 2481 | if (work.get(field) != fieldValue) { | ||
| 2482 | break; | ||
| 2483 | } else { | ||
| 2484 | result = fieldValue; | ||
| 2485 | fieldValue++; | ||
| 2486 | } | ||
| 2487 | } while (fieldValue <= endValue); | ||
| 2488 | |||
| 2489 | return result; | ||
| 2490 | } | ||
| 2491 | |||
| 2492 | /** | ||
| 2493 | * Creates and returns a copy of this object. | ||
| 2494 | * | ||
| 2495 | * @return a copy of this object. | ||
| 2496 | */ | ||
| 2497 | public Object clone() | ||
| 2498 | { | ||
| 2499 | try { | ||
| 2500 | Calendar other = (Calendar) super.clone(); | ||
| 2501 | |||
| 2502 | other.fields = new int[FIELD_COUNT]; | ||
| 2503 | other.isSet = new boolean[FIELD_COUNT]; | ||
| 2504 | other.stamp = new int[FIELD_COUNT]; | ||
| 2505 | for (int i = 0; i < FIELD_COUNT; i++) { | ||
| 2506 | other.fields[i] = fields[i]; | ||
| 2507 | other.stamp[i] = stamp[i]; | ||
| 2508 | other.isSet[i] = isSet[i]; | ||
| 2509 | } | ||
| 2510 | other.zone = (TimeZone) zone.clone(); | ||
| 2511 | return other; | ||
| 2512 | } | ||
| 2513 | catch (CloneNotSupportedException e) { | ||
| 2514 | // this shouldn't happen, since we are Cloneable | ||
| 2515 | throw new InternalError(); | ||
| 2516 | } | ||
| 2517 | } | ||
| 2518 | |||
| 2519 | private static final String[] FIELD_NAME = { | ||
| 2520 | "ERA", "YEAR", "MONTH", "WEEK_OF_YEAR", "WEEK_OF_MONTH", "DAY_OF_MONTH", | ||
| 2521 | "DAY_OF_YEAR", "DAY_OF_WEEK", "DAY_OF_WEEK_IN_MONTH", "AM_PM", "HOUR", | ||
| 2522 | "HOUR_OF_DAY", "MINUTE", "SECOND", "MILLISECOND", "ZONE_OFFSET", | ||
| 2523 | "DST_OFFSET" | ||
| 2524 | }; | ||
| 2525 | |||
| 2526 | /** | ||
| 2527 | * Returns the name of the specified calendar field. | ||
| 2528 | * | ||
| 2529 | * @param field the calendar field | ||
| 2530 | * @return the calendar field name | ||
| 2531 | * @exception IndexOutOfBoundsException if <code>field</code> is negative, | ||
| 2532 | * equal to or greater then <code>FIELD_COUNT</code>. | ||
| 2533 | */ | ||
| 2534 | static final String getFieldName(int field) { | ||
| 2535 | return FIELD_NAME[field]; | ||
| 2536 | } | ||
| 2537 | |||
| 2538 | /** | ||
| 2539 | * Return a string representation of this calendar. This method | ||
| 2540 | * is intended to be used only for debugging purposes, and the | ||
| 2541 | * format of the returned string may vary between implementations. | ||
| 2542 | * The returned string may be empty but may not be <code>null</code>. | ||
| 2543 | * | ||
| 2544 | * @return a string representation of this calendar. | ||
| 2545 | */ | ||
| 2546 | public String toString() { | ||
| 2547 | // NOTE: BuddhistCalendar.toString() interprets the string | ||
| 2548 | // produced by this method so that the Gregorian year number | ||
| 2549 | // is substituted by its B.E. year value. It relies on | ||
| 2550 | // "...,YEAR=<year>,..." or "...,YEAR=?,...". | ||
| 2551 | StringBuilder buffer = new StringBuilder(800); | ||
| 2552 | buffer.append(getClass().getName()).append('['); | ||
| 2553 | appendValue(buffer, "time", isTimeSet, time); | ||
| 2554 | buffer.append(",areFieldsSet=").append(areFieldsSet); | ||
| 2555 | buffer.append(",areAllFieldsSet=").append(areAllFieldsSet); | ||
| 2556 | buffer.append(",lenient=").append(lenient); | ||
| 2557 | buffer.append(",zone=").append(zone); | ||
| 2558 | appendValue(buffer, ",firstDayOfWeek", true, (long) firstDayOfWeek); | ||
| 2559 | appendValue(buffer, ",minimalDaysInFirstWeek", true, (long) minimalDaysInFirstWeek); | ||
| 2560 | for (int i = 0; i < FIELD_COUNT; ++i) { | ||
| 2561 | buffer.append(','); | ||
| 2562 | appendValue(buffer, FIELD_NAME[i], isSet(i), (long) fields[i]); | ||
| 2563 | } | ||
| 2564 | buffer.append(']'); | ||
| 2565 | return buffer.toString(); | ||
| 2566 | } | ||
| 2567 | |||
| 2568 | // =======================privates=============================== | ||
| 2569 | |||
| 2570 | private static final void appendValue(StringBuilder sb, String item, boolean valid, long value) { | ||
| 2571 | sb.append(item).append('='); | ||
| 2572 | if (valid) { | ||
| 2573 | sb.append(value); | ||
| 2574 | } else { | ||
| 2575 | sb.append('?'); | ||
| 2576 | } | ||
| 2577 | } | ||
| 2578 | |||
| 2579 | /** | ||
| 2580 | * Both firstDayOfWeek and minimalDaysInFirstWeek are locale-dependent. | ||
| 2581 | * They are used to figure out the week count for a specific date for | ||
| 2582 | * a given locale. These must be set when a Calendar is constructed. | ||
| 2583 | * @param desiredLocale the given locale. | ||
| 2584 | */ | ||
| 2585 | private void setWeekCountData(Locale desiredLocale) | ||
| 2586 | { | ||
| 2587 | /* try to get the Locale data from the cache */ | ||
| 2588 | int[] data = cachedLocaleData.get(desiredLocale); | ||
| 2589 | if (data == null) { /* cache miss */ | ||
| 2590 | ResourceBundle bundle = LocaleData.getCalendarData(desiredLocale); | ||
| 2591 | data = new int[2]; | ||
| 2592 | data[0] = Integer.parseInt(bundle.getString("firstDayOfWeek")); | ||
| 2593 | data[1] = Integer.parseInt(bundle.getString("minimalDaysInFirstWeek")); | ||
| 2594 | cachedLocaleData.putIfAbsent(desiredLocale, data); | ||
| 2595 | } | ||
| 2596 | firstDayOfWeek = data[0]; | ||
| 2597 | minimalDaysInFirstWeek = data[1]; | ||
| 2598 | } | ||
| 2599 | |||
| 2600 | /** | ||
| 2601 | * Recomputes the time and updates the status fields isTimeSet | ||
| 2602 | * and areFieldsSet. Callers should check isTimeSet and only | ||
| 2603 | * call this method if isTimeSet is false. | ||
| 2604 | */ | ||
| 2605 | private void updateTime() { | ||
| 2606 | computeTime(); | ||
| 2607 | // The areFieldsSet and areAllFieldsSet values are no longer | ||
| 2608 | // controlled here (as of 1.5). | ||
| 2609 | isTimeSet = true; | ||
| 2610 | } | ||
| 2611 | |||
| 2612 | private int compareTo(long t) { | ||
| 2613 | long thisTime = getMillisOf(this); | ||
| 2614 | return (thisTime > t) ? 1 : (thisTime == t) ? 0 : -1; | ||
| 2615 | } | ||
| 2616 | |||
| 2617 | private static final long getMillisOf(Calendar calendar) { | ||
| 2618 | if (calendar.isTimeSet) { | ||
| 2619 | return calendar.time; | ||
| 2620 | } | ||
| 2621 | Calendar cal = (Calendar) calendar.clone(); | ||
| 2622 | cal.setLenient(true); | ||
| 2623 | return cal.getTimeInMillis(); | ||
| 2624 | } | ||
| 2625 | |||
| 2626 | /** | ||
| 2627 | * Adjusts the stamp[] values before nextStamp overflow. nextStamp | ||
| 2628 | * is set to the next stamp value upon the return. | ||
| 2629 | */ | ||
| 2630 | private final void adjustStamp() { | ||
| 2631 | int max = MINIMUM_USER_STAMP; | ||
| 2632 | int newStamp = MINIMUM_USER_STAMP; | ||
| 2633 | |||
| 2634 | for (;;) { | ||
| 2635 | int min = Integer.MAX_VALUE; | ||
| 2636 | for (int i = 0; i < stamp.length; i++) { | ||
| 2637 | int v = stamp[i]; | ||
| 2638 | if (v >= newStamp && min > v) { | ||
| 2639 | min = v; | ||
| 2640 | } | ||
| 2641 | if (max < v) { | ||
| 2642 | max = v; | ||
| 2643 | } | ||
| 2644 | } | ||
| 2645 | if (max != min && min == Integer.MAX_VALUE) { | ||
| 2646 | break; | ||
| 2647 | } | ||
| 2648 | for (int i = 0; i < stamp.length; i++) { | ||
| 2649 | if (stamp[i] == min) { | ||
| 2650 | stamp[i] = newStamp; | ||
| 2651 | } | ||
| 2652 | } | ||
| 2653 | newStamp++; | ||
| 2654 | if (min == max) { | ||
| 2655 | break; | ||
| 2656 | } | ||
| 2657 | } | ||
| 2658 | nextStamp = newStamp; | ||
| 2659 | } | ||
| 2660 | |||
| 2661 | /** | ||
| 2662 | * Sets the WEEK_OF_MONTH and WEEK_OF_YEAR fields to new values with the | ||
| 2663 | * new parameter value if they have been calculated internally. | ||
| 2664 | */ | ||
| 2665 | private void invalidateWeekFields() | ||
| 2666 | { | ||
| 2667 | if (stamp[WEEK_OF_MONTH] != COMPUTED && | ||
| 2668 | stamp[WEEK_OF_YEAR] != COMPUTED) { | ||
| 2669 | return; | ||
| 2670 | } | ||
| 2671 | |||
| 2672 | // We have to check the new values of these fields after changing | ||
| 2673 | // firstDayOfWeek and/or minimalDaysInFirstWeek. If the field values | ||
| 2674 | // have been changed, then set the new values. (4822110) | ||
| 2675 | Calendar cal = (Calendar) clone(); | ||
| 2676 | cal.setLenient(true); | ||
| 2677 | cal.clear(WEEK_OF_MONTH); | ||
| 2678 | cal.clear(WEEK_OF_YEAR); | ||
| 2679 | |||
| 2680 | if (stamp[WEEK_OF_MONTH] == COMPUTED) { | ||
| 2681 | int weekOfMonth = cal.get(WEEK_OF_MONTH); | ||
| 2682 | if (fields[WEEK_OF_MONTH] != weekOfMonth) { | ||
| 2683 | fields[WEEK_OF_MONTH] = weekOfMonth; | ||
| 2684 | } | ||
| 2685 | } | ||
| 2686 | |||
| 2687 | if (stamp[WEEK_OF_YEAR] == COMPUTED) { | ||
| 2688 | int weekOfYear = cal.get(WEEK_OF_YEAR); | ||
| 2689 | if (fields[WEEK_OF_YEAR] != weekOfYear) { | ||
| 2690 | fields[WEEK_OF_YEAR] = weekOfYear; | ||
| 2691 | } | ||
| 2692 | } | ||
| 2693 | } | ||
| 2694 | |||
| 2695 | /** | ||
| 2696 | * Save the state of this object to a stream (i.e., serialize it). | ||
| 2697 | * | ||
| 2698 | * Ideally, <code>Calendar</code> would only write out its state data and | ||
| 2699 | * the current time, and not write any field data out, such as | ||
| 2700 | * <code>fields[]</code>, <code>isTimeSet</code>, <code>areFieldsSet</code>, | ||
| 2701 | * and <code>isSet[]</code>. <code>nextStamp</code> also should not be part | ||
| 2702 | * of the persistent state. Unfortunately, this didn't happen before JDK 1.1 | ||
| 2703 | * shipped. To be compatible with JDK 1.1, we will always have to write out | ||
| 2704 | * the field values and state flags. However, <code>nextStamp</code> can be | ||
| 2705 | * removed from the serialization stream; this will probably happen in the | ||
| 2706 | * near future. | ||
| 2707 | */ | ||
| 2708 | private void writeObject(ObjectOutputStream stream) | ||
| 2709 | throws IOException | ||
| 2710 | { | ||
| 2711 | // Try to compute the time correctly, for the future (stream | ||
| 2712 | // version 2) in which we don't write out fields[] or isSet[]. | ||
| 2713 | if (!isTimeSet) { | ||
| 2714 | try { | ||
| 2715 | updateTime(); | ||
| 2716 | } | ||
| 2717 | catch (IllegalArgumentException e) {} | ||
| 2718 | } | ||
| 2719 | |||
| 2720 | // If this Calendar has a ZoneInfo, save it and set a | ||
| 2721 | // SimpleTimeZone equivalent (as a single DST schedule) for | ||
| 2722 | // backward compatibility. | ||
| 2723 | TimeZone savedZone = null; | ||
| 2724 | if (zone instanceof ZoneInfo) { | ||
| 2725 | SimpleTimeZone stz = ((ZoneInfo)zone).getLastRuleInstance(); | ||
| 2726 | if (stz == null) { | ||
| 2727 | stz = new SimpleTimeZone(zone.getRawOffset(), zone.getID()); | ||
| 2728 | } | ||
| 2729 | savedZone = zone; | ||
| 2730 | zone = stz; | ||
| 2731 | } | ||
| 2732 | |||
| 2733 | // Write out the 1.1 FCS object. | ||
| 2734 | stream.defaultWriteObject(); | ||
| 2735 | |||
| 2736 | // Write out the ZoneInfo object | ||
| 2737 | // 4802409: we write out even if it is null, a temporary workaround | ||
| 2738 | // the real fix for bug 4844924 in corba-iiop | ||
| 2739 | stream.writeObject(savedZone); | ||
| 2740 | if (savedZone != null) { | ||
| 2741 | zone = savedZone; | ||
| 2742 | } | ||
| 2743 | } | ||
| 2744 | |||
| 2745 | private static class CalendarAccessControlContext { | ||
| 2746 | private static final AccessControlContext INSTANCE; | ||
| 2747 | static { | ||
| 2748 | RuntimePermission perm = new RuntimePermission("accessClassInPackage.sun.util.calendar"); | ||
| 2749 | PermissionCollection perms = perm.newPermissionCollection(); | ||
| 2750 | perms.add(perm); | ||
| 2751 | INSTANCE = new AccessControlContext(new ProtectionDomain[] { | ||
| 2752 | new ProtectionDomain(null, perms) | ||
| 2753 | }); | ||
| 2754 | } | ||
| 2755 | } | ||
| 2756 | |||
| 2757 | /** | ||
| 2758 | * Reconstitutes this object from a stream (i.e., deserialize it). | ||
| 2759 | */ | ||
| 2760 | private void readObject(ObjectInputStream stream) | ||
| 2761 | throws IOException, ClassNotFoundException | ||
| 2762 | { | ||
| 2763 | final ObjectInputStream input = stream; | ||
| 2764 | input.defaultReadObject(); | ||
| 2765 | |||
| 2766 | stamp = new int[FIELD_COUNT]; | ||
| 2767 | |||
| 2768 | // Starting with version 2 (not implemented yet), we expect that | ||
| 2769 | // fields[], isSet[], isTimeSet, and areFieldsSet may not be | ||
| 2770 | // streamed out anymore. We expect 'time' to be correct. | ||
| 2771 | if (serialVersionOnStream >= 2) | ||
| 2772 | { | ||
| 2773 | isTimeSet = true; | ||
| 2774 | if (fields == null) fields = new int[FIELD_COUNT]; | ||
| 2775 | if (isSet == null) isSet = new boolean[FIELD_COUNT]; | ||
| 2776 | } | ||
| 2777 | else if (serialVersionOnStream >= 0) | ||
| 2778 | { | ||
| 2779 | for (int i=0; i<FIELD_COUNT; ++i) | ||
| 2780 | stamp[i] = isSet[i] ? COMPUTED : UNSET; | ||
| 2781 | } | ||
| 2782 | |||
| 2783 | serialVersionOnStream = currentSerialVersion; | ||
| 2784 | |||
| 2785 | // If there's a ZoneInfo object, use it for zone. | ||
| 2786 | ZoneInfo zi = null; | ||
| 2787 | try { | ||
| 2788 | zi = AccessController.doPrivileged( | ||
| 2789 | new PrivilegedExceptionAction<ZoneInfo>() { | ||
| 2790 | public ZoneInfo run() throws Exception { | ||
| 2791 | return (ZoneInfo) input.readObject(); | ||
| 2792 | } | ||
| 2793 | }, | ||
| 2794 | CalendarAccessControlContext.INSTANCE); | ||
| 2795 | } catch (PrivilegedActionException pae) { | ||
| 2796 | Exception e = pae.getException(); | ||
| 2797 | if (!(e instanceof OptionalDataException)) { | ||
| 2798 | if (e instanceof RuntimeException) { | ||
| 2799 | throw (RuntimeException) e; | ||
| 2800 | } else if (e instanceof IOException) { | ||
| 2801 | throw (IOException) e; | ||
| 2802 | } else if (e instanceof ClassNotFoundException) { | ||
| 2803 | throw (ClassNotFoundException) e; | ||
| 2804 | } | ||
| 2805 | throw new RuntimeException(e); | ||
| 2806 | } | ||
| 2807 | } | ||
| 2808 | if (zi != null) { | ||
| 2809 | zone = zi; | ||
| 2810 | } | ||
| 2811 | |||
| 2812 | // If the deserialized object has a SimpleTimeZone, try to | ||
| 2813 | // replace it with a ZoneInfo equivalent (as of 1.4) in order | ||
| 2814 | // to be compatible with the SimpleTimeZone-based | ||
| 2815 | // implementation as much as possible. | ||
| 2816 | if (zone instanceof SimpleTimeZone) { | ||
| 2817 | String id = zone.getID(); | ||
| 2818 | TimeZone tz = TimeZone.getTimeZone(id); | ||
| 2819 | if (tz != null && tz.hasSameRules(zone) && tz.getID().equals(id)) { | ||
| 2820 | zone = tz; | ||
| 2821 | } | ||
| 2822 | } | ||
| 2823 | } | ||
| 2824 | } | ||
Binary file not shown.
| @@ -0,0 +1,456 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package java.util; | ||
| 27 | |||
| 28 | /** | ||
| 29 | * The root interface in the <i>collection hierarchy</i>. A collection | ||
| 30 | * represents a group of objects, known as its <i>elements</i>. Some | ||
| 31 | * collections allow duplicate elements and others do not. Some are ordered | ||
| 32 | * and others unordered. The JDK does not provide any <i>direct</i> | ||
| 33 | * implementations of this interface: it provides implementations of more | ||
| 34 | * specific subinterfaces like <tt>Set</tt> and <tt>List</tt>. This interface | ||
| 35 | * is typically used to pass collections around and manipulate them where | ||
| 36 | * maximum generality is desired. | ||
| 37 | * | ||
| 38 | * <p><i>Bags</i> or <i>multisets</i> (unordered collections that may contain | ||
| 39 | * duplicate elements) should implement this interface directly. | ||
| 40 | * | ||
| 41 | * <p>All general-purpose <tt>Collection</tt> implementation classes (which | ||
| 42 | * typically implement <tt>Collection</tt> indirectly through one of its | ||
| 43 | * subinterfaces) should provide two "standard" constructors: a void (no | ||
| 44 | * arguments) constructor, which creates an empty collection, and a | ||
| 45 | * constructor with a single argument of type <tt>Collection</tt>, which | ||
| 46 | * creates a new collection with the same elements as its argument. In | ||
| 47 | * effect, the latter constructor allows the user to copy any collection, | ||
| 48 | * producing an equivalent collection of the desired implementation type. | ||
| 49 | * There is no way to enforce this convention (as interfaces cannot contain | ||
| 50 | * constructors) but all of the general-purpose <tt>Collection</tt> | ||
| 51 | * implementations in the Java platform libraries comply. | ||
| 52 | * | ||
| 53 | * <p>The "destructive" methods contained in this interface, that is, the | ||
| 54 | * methods that modify the collection on which they operate, are specified to | ||
| 55 | * throw <tt>UnsupportedOperationException</tt> if this collection does not | ||
| 56 | * support the operation. If this is the case, these methods may, but are not | ||
| 57 | * required to, throw an <tt>UnsupportedOperationException</tt> if the | ||
| 58 | * invocation would have no effect on the collection. For example, invoking | ||
| 59 | * the {@link #addAll(Collection)} method on an unmodifiable collection may, | ||
| 60 | * but is not required to, throw the exception if the collection to be added | ||
| 61 | * is empty. | ||
| 62 | * | ||
| 63 | * <p><a name="optional-restrictions"/> | ||
| 64 | * Some collection implementations have restrictions on the elements that | ||
| 65 | * they may contain. For example, some implementations prohibit null elements, | ||
| 66 | * and some have restrictions on the types of their elements. Attempting to | ||
| 67 | * add an ineligible element throws an unchecked exception, typically | ||
| 68 | * <tt>NullPointerException</tt> or <tt>ClassCastException</tt>. Attempting | ||
| 69 | * to query the presence of an ineligible element may throw an exception, | ||
| 70 | * or it may simply return false; some implementations will exhibit the former | ||
| 71 | * behavior and some will exhibit the latter. More generally, attempting an | ||
| 72 | * operation on an ineligible element whose completion would not result in | ||
| 73 | * the insertion of an ineligible element into the collection may throw an | ||
| 74 | * exception or it may succeed, at the option of the implementation. | ||
| 75 | * Such exceptions are marked as "optional" in the specification for this | ||
| 76 | * interface. | ||
| 77 | * | ||
| 78 | * <p>It is up to each collection to determine its own synchronization | ||
| 79 | * policy. In the absence of a stronger guarantee by the | ||
| 80 | * implementation, undefined behavior may result from the invocation | ||
| 81 | * of any method on a collection that is being mutated by another | ||
| 82 | * thread; this includes direct invocations, passing the collection to | ||
| 83 | * a method that might perform invocations, and using an existing | ||
| 84 | * iterator to examine the collection. | ||
| 85 | * | ||
| 86 | * <p>Many methods in Collections Framework interfaces are defined in | ||
| 87 | * terms of the {@link Object#equals(Object) equals} method. For example, | ||
| 88 | * the specification for the {@link #contains(Object) contains(Object o)} | ||
| 89 | * method says: "returns <tt>true</tt> if and only if this collection | ||
| 90 | * contains at least one element <tt>e</tt> such that | ||
| 91 | * <tt>(o==null ? e==null : o.equals(e))</tt>." This specification should | ||
| 92 | * <i>not</i> be construed to imply that invoking <tt>Collection.contains</tt> | ||
| 93 | * with a non-null argument <tt>o</tt> will cause <tt>o.equals(e)</tt> to be | ||
| 94 | * invoked for any element <tt>e</tt>. Implementations are free to implement | ||
| 95 | * optimizations whereby the <tt>equals</tt> invocation is avoided, for | ||
| 96 | * example, by first comparing the hash codes of the two elements. (The | ||
| 97 | * {@link Object#hashCode()} specification guarantees that two objects with | ||
| 98 | * unequal hash codes cannot be equal.) More generally, implementations of | ||
| 99 | * the various Collections Framework interfaces are free to take advantage of | ||
| 100 | * the specified behavior of underlying {@link Object} methods wherever the | ||
| 101 | * implementor deems it appropriate. | ||
| 102 | * | ||
| 103 | * <p>This interface is a member of the | ||
| 104 | * <a href="{@docRoot}/../technotes/guides/collections/index.html"> | ||
| 105 | * Java Collections Framework</a>. | ||
| 106 | * | ||
| 107 | * @param <E> the type of elements in this collection | ||
| 108 | * | ||
| 109 | * @author Josh Bloch | ||
| 110 | * @author Neal Gafter | ||
| 111 | * @see Set | ||
| 112 | * @see List | ||
| 113 | * @see Map | ||
| 114 | * @see SortedSet | ||
| 115 | * @see SortedMap | ||
| 116 | * @see HashSet | ||
| 117 | * @see TreeSet | ||
| 118 | * @see ArrayList | ||
| 119 | * @see LinkedList | ||
| 120 | * @see Vector | ||
| 121 | * @see Collections | ||
| 122 | * @see Arrays | ||
| 123 | * @see AbstractCollection | ||
| 124 | * @since 1.2 | ||
| 125 | */ | ||
| 126 | |||
| 127 | public interface Collection<E> extends Iterable<E> { | ||
| 128 | // Query Operations | ||
| 129 | |||
| 130 | /** | ||
| 131 | * Returns the number of elements in this collection. If this collection | ||
| 132 | * contains more than <tt>Integer.MAX_VALUE</tt> elements, returns | ||
| 133 | * <tt>Integer.MAX_VALUE</tt>. | ||
| 134 | * | ||
| 135 | * @return the number of elements in this collection | ||
| 136 | */ | ||
| 137 | int size(); | ||
| 138 | |||
| 139 | /** | ||
| 140 | * Returns <tt>true</tt> if this collection contains no elements. | ||
| 141 | * | ||
| 142 | * @return <tt>true</tt> if this collection contains no elements | ||
| 143 | */ | ||
| 144 | boolean isEmpty(); | ||
| 145 | |||
| 146 | /** | ||
| 147 | * Returns <tt>true</tt> if this collection contains the specified element. | ||
| 148 | * More formally, returns <tt>true</tt> if and only if this collection | ||
| 149 | * contains at least one element <tt>e</tt> such that | ||
| 150 | * <tt>(o==null ? e==null : o.equals(e))</tt>. | ||
| 151 | * | ||
| 152 | * @param o element whose presence in this collection is to be tested | ||
| 153 | * @return <tt>true</tt> if this collection contains the specified | ||
| 154 | * element | ||
| 155 | * @throws ClassCastException if the type of the specified element | ||
| 156 | * is incompatible with this collection | ||
| 157 | * (<a href="#optional-restrictions">optional</a>) | ||
| 158 | * @throws NullPointerException if the specified element is null and this | ||
| 159 | * collection does not permit null elements | ||
| 160 | * (<a href="#optional-restrictions">optional</a>) | ||
| 161 | */ | ||
| 162 | boolean contains(Object o); | ||
| 163 | |||
| 164 | /** | ||
| 165 | * Returns an iterator over the elements in this collection. There are no | ||
| 166 | * guarantees concerning the order in which the elements are returned | ||
| 167 | * (unless this collection is an instance of some class that provides a | ||
| 168 | * guarantee). | ||
| 169 | * | ||
| 170 | * @return an <tt>Iterator</tt> over the elements in this collection | ||
| 171 | */ | ||
| 172 | Iterator<E> iterator(); | ||
| 173 | |||
| 174 | /** | ||
| 175 | * Returns an array containing all of the elements in this collection. | ||
| 176 | * If this collection makes any guarantees as to what order its elements | ||
| 177 | * are returned by its iterator, this method must return the elements in | ||
| 178 | * the same order. | ||
| 179 | * | ||
| 180 | * <p>The returned array will be "safe" in that no references to it are | ||
| 181 | * maintained by this collection. (In other words, this method must | ||
| 182 | * allocate a new array even if this collection is backed by an array). | ||
| 183 | * The caller is thus free to modify the returned array. | ||
| 184 | * | ||
| 185 | * <p>This method acts as bridge between array-based and collection-based | ||
| 186 | * APIs. | ||
| 187 | * | ||
| 188 | * @return an array containing all of the elements in this collection | ||
| 189 | */ | ||
| 190 | Object[] toArray(); | ||
| 191 | |||
| 192 | /** | ||
| 193 | * Returns an array containing all of the elements in this collection; | ||
| 194 | * the runtime type of the returned array is that of the specified array. | ||
| 195 | * If the collection fits in the specified array, it is returned therein. | ||
| 196 | * Otherwise, a new array is allocated with the runtime type of the | ||
| 197 | * specified array and the size of this collection. | ||
| 198 | * | ||
| 199 | * <p>If this collection fits in the specified array with room to spare | ||
| 200 | * (i.e., the array has more elements than this collection), the element | ||
| 201 | * in the array immediately following the end of the collection is set to | ||
| 202 | * <tt>null</tt>. (This is useful in determining the length of this | ||
| 203 | * collection <i>only</i> if the caller knows that this collection does | ||
| 204 | * not contain any <tt>null</tt> elements.) | ||
| 205 | * | ||
| 206 | * <p>If this collection makes any guarantees as to what order its elements | ||
| 207 | * are returned by its iterator, this method must return the elements in | ||
| 208 | * the same order. | ||
| 209 | * | ||
| 210 | * <p>Like the {@link #toArray()} method, this method acts as bridge between | ||
| 211 | * array-based and collection-based APIs. Further, this method allows | ||
| 212 | * precise control over the runtime type of the output array, and may, | ||
| 213 | * under certain circumstances, be used to save allocation costs. | ||
| 214 | * | ||
| 215 | * <p>Suppose <tt>x</tt> is a collection known to contain only strings. | ||
| 216 | * The following code can be used to dump the collection into a newly | ||
| 217 | * allocated array of <tt>String</tt>: | ||
| 218 | * | ||
| 219 | * <pre> | ||
| 220 | * String[] y = x.toArray(new String[0]);</pre> | ||
| 221 | * | ||
| 222 | * Note that <tt>toArray(new Object[0])</tt> is identical in function to | ||
| 223 | * <tt>toArray()</tt>. | ||
| 224 | * | ||
| 225 | * @param a the array into which the elements of this collection are to be | ||
| 226 | * stored, if it is big enough; otherwise, a new array of the same | ||
| 227 | * runtime type is allocated for this purpose. | ||
| 228 | * @return an array containing all of the elements in this collection | ||
| 229 | * @throws ArrayStoreException if the runtime type of the specified array | ||
| 230 | * is not a supertype of the runtime type of every element in | ||
| 231 | * this collection | ||
| 232 | * @throws NullPointerException if the specified array is null | ||
| 233 | */ | ||
| 234 | <T> T[] toArray(T[] a); | ||
| 235 | |||
| 236 | // Modification Operations | ||
| 237 | |||
| 238 | /** | ||
| 239 | * Ensures that this collection contains the specified element (optional | ||
| 240 | * operation). Returns <tt>true</tt> if this collection changed as a | ||
| 241 | * result of the call. (Returns <tt>false</tt> if this collection does | ||
| 242 | * not permit duplicates and already contains the specified element.)<p> | ||
| 243 | * | ||
| 244 | * Collections that support this operation may place limitations on what | ||
| 245 | * elements may be added to this collection. In particular, some | ||
| 246 | * collections will refuse to add <tt>null</tt> elements, and others will | ||
| 247 | * impose restrictions on the type of elements that may be added. | ||
| 248 | * Collection classes should clearly specify in their documentation any | ||
| 249 | * restrictions on what elements may be added.<p> | ||
| 250 | * | ||
| 251 | * If a collection refuses to add a particular element for any reason | ||
| 252 | * other than that it already contains the element, it <i>must</i> throw | ||
| 253 | * an exception (rather than returning <tt>false</tt>). This preserves | ||
| 254 | * the invariant that a collection always contains the specified element | ||
| 255 | * after this call returns. | ||
| 256 | * | ||
| 257 | * @param e element whose presence in this collection is to be ensured | ||
| 258 | * @return <tt>true</tt> if this collection changed as a result of the | ||
| 259 | * call | ||
| 260 | * @throws UnsupportedOperationException if the <tt>add</tt> operation | ||
| 261 | * is not supported by this collection | ||
| 262 | * @throws ClassCastException if the class of the specified element | ||
| 263 | * prevents it from being added to this collection | ||
| 264 | * @throws NullPointerException if the specified element is null and this | ||
| 265 | * collection does not permit null elements | ||
| 266 | * @throws IllegalArgumentException if some property of the element | ||
| 267 | * prevents it from being added to this collection | ||
| 268 | * @throws IllegalStateException if the element cannot be added at this | ||
| 269 | * time due to insertion restrictions | ||
| 270 | */ | ||
| 271 | boolean add(E e); | ||
| 272 | |||
| 273 | /** | ||
| 274 | * Removes a single instance of the specified element from this | ||
| 275 | * collection, if it is present (optional operation). More formally, | ||
| 276 | * removes an element <tt>e</tt> such that | ||
| 277 | * <tt>(o==null ? e==null : o.equals(e))</tt>, if | ||
| 278 | * this collection contains one or more such elements. Returns | ||
| 279 | * <tt>true</tt> if this collection contained the specified element (or | ||
| 280 | * equivalently, if this collection changed as a result of the call). | ||
| 281 | * | ||
| 282 | * @param o element to be removed from this collection, if present | ||
| 283 | * @return <tt>true</tt> if an element was removed as a result of this call | ||
| 284 | * @throws ClassCastException if the type of the specified element | ||
| 285 | * is incompatible with this collection | ||
| 286 | * (<a href="#optional-restrictions">optional</a>) | ||
| 287 | * @throws NullPointerException if the specified element is null and this | ||
| 288 | * collection does not permit null elements | ||
| 289 | * (<a href="#optional-restrictions">optional</a>) | ||
| 290 | * @throws UnsupportedOperationException if the <tt>remove</tt> operation | ||
| 291 | * is not supported by this collection | ||
| 292 | */ | ||
| 293 | boolean remove(Object o); | ||
| 294 | |||
| 295 | |||
| 296 | // Bulk Operations | ||
| 297 | |||
| 298 | /** | ||
| 299 | * Returns <tt>true</tt> if this collection contains all of the elements | ||
| 300 | * in the specified collection. | ||
| 301 | * | ||
| 302 | * @param c collection to be checked for containment in this collection | ||
| 303 | * @return <tt>true</tt> if this collection contains all of the elements | ||
| 304 | * in the specified collection | ||
| 305 | * @throws ClassCastException if the types of one or more elements | ||
| 306 | * in the specified collection are incompatible with this | ||
| 307 | * collection | ||
| 308 | * (<a href="#optional-restrictions">optional</a>) | ||
| 309 | * @throws NullPointerException if the specified collection contains one | ||
| 310 | * or more null elements and this collection does not permit null | ||
| 311 | * elements | ||
| 312 | * (<a href="#optional-restrictions">optional</a>), | ||
| 313 | * or if the specified collection is null. | ||
| 314 | * @see #contains(Object) | ||
| 315 | */ | ||
| 316 | boolean containsAll(Collection<?> c); | ||
| 317 | |||
| 318 | /** | ||
| 319 | * Adds all of the elements in the specified collection to this collection | ||
| 320 | * (optional operation). The behavior of this operation is undefined if | ||
| 321 | * the specified collection is modified while the operation is in progress. | ||
| 322 | * (This implies that the behavior of this call is undefined if the | ||
| 323 | * specified collection is this collection, and this collection is | ||
| 324 | * nonempty.) | ||
| 325 | * | ||
| 326 | * @param c collection containing elements to be added to this collection | ||
| 327 | * @return <tt>true</tt> if this collection changed as a result of the call | ||
| 328 | * @throws UnsupportedOperationException if the <tt>addAll</tt> operation | ||
| 329 | * is not supported by this collection | ||
| 330 | * @throws ClassCastException if the class of an element of the specified | ||
| 331 | * collection prevents it from being added to this collection | ||
| 332 | * @throws NullPointerException if the specified collection contains a | ||
| 333 | * null element and this collection does not permit null elements, | ||
| 334 | * or if the specified collection is null | ||
| 335 | * @throws IllegalArgumentException if some property of an element of the | ||
| 336 | * specified collection prevents it from being added to this | ||
| 337 | * collection | ||
| 338 | * @throws IllegalStateException if not all the elements can be added at | ||
| 339 | * this time due to insertion restrictions | ||
| 340 | * @see #add(Object) | ||
| 341 | */ | ||
| 342 | boolean addAll(Collection<? extends E> c); | ||
| 343 | |||
| 344 | /** | ||
| 345 | * Removes all of this collection's elements that are also contained in the | ||
| 346 | * specified collection (optional operation). After this call returns, | ||
| 347 | * this collection will contain no elements in common with the specified | ||
| 348 | * collection. | ||
| 349 | * | ||
| 350 | * @param c collection containing elements to be removed from this collection | ||
| 351 | * @return <tt>true</tt> if this collection changed as a result of the | ||
| 352 | * call | ||
| 353 | * @throws UnsupportedOperationException if the <tt>removeAll</tt> method | ||
| 354 | * is not supported by this collection | ||
| 355 | * @throws ClassCastException if the types of one or more elements | ||
| 356 | * in this collection are incompatible with the specified | ||
| 357 | * collection | ||
| 358 | * (<a href="#optional-restrictions">optional</a>) | ||
| 359 | * @throws NullPointerException if this collection contains one or more | ||
| 360 | * null elements and the specified collection does not support | ||
| 361 | * null elements | ||
| 362 | * (<a href="#optional-restrictions">optional</a>), | ||
| 363 | * or if the specified collection is null | ||
| 364 | * @see #remove(Object) | ||
| 365 | * @see #contains(Object) | ||
| 366 | */ | ||
| 367 | boolean removeAll(Collection<?> c); | ||
| 368 | |||
| 369 | /** | ||
| 370 | * Retains only the elements in this collection that are contained in the | ||
| 371 | * specified collection (optional operation). In other words, removes from | ||
| 372 | * this collection all of its elements that are not contained in the | ||
| 373 | * specified collection. | ||
| 374 | * | ||
| 375 | * @param c collection containing elements to be retained in this collection | ||
| 376 | * @return <tt>true</tt> if this collection changed as a result of the call | ||
| 377 | * @throws UnsupportedOperationException if the <tt>retainAll</tt> operation | ||
| 378 | * is not supported by this collection | ||
| 379 | * @throws ClassCastException if the types of one or more elements | ||
| 380 | * in this collection are incompatible with the specified | ||
| 381 | * collection | ||
| 382 | * (<a href="#optional-restrictions">optional</a>) | ||
| 383 | * @throws NullPointerException if this collection contains one or more | ||
| 384 | * null elements and the specified collection does not permit null | ||
| 385 | * elements | ||
| 386 | * (<a href="#optional-restrictions">optional</a>), | ||
| 387 | * or if the specified collection is null | ||
| 388 | * @see #remove(Object) | ||
| 389 | * @see #contains(Object) | ||
| 390 | */ | ||
| 391 | boolean retainAll(Collection<?> c); | ||
| 392 | |||
| 393 | /** | ||
| 394 | * Removes all of the elements from this collection (optional operation). | ||
| 395 | * The collection will be empty after this method returns. | ||
| 396 | * | ||
| 397 | * @throws UnsupportedOperationException if the <tt>clear</tt> operation | ||
| 398 | * is not supported by this collection | ||
| 399 | */ | ||
| 400 | void clear(); | ||
| 401 | |||
| 402 | |||
| 403 | // Comparison and hashing | ||
| 404 | |||
| 405 | /** | ||
| 406 | * Compares the specified object with this collection for equality. <p> | ||
| 407 | * | ||
| 408 | * While the <tt>Collection</tt> interface adds no stipulations to the | ||
| 409 | * general contract for the <tt>Object.equals</tt>, programmers who | ||
| 410 | * implement the <tt>Collection</tt> interface "directly" (in other words, | ||
| 411 | * create a class that is a <tt>Collection</tt> but is not a <tt>Set</tt> | ||
| 412 | * or a <tt>List</tt>) must exercise care if they choose to override the | ||
| 413 | * <tt>Object.equals</tt>. It is not necessary to do so, and the simplest | ||
| 414 | * course of action is to rely on <tt>Object</tt>'s implementation, but | ||
| 415 | * the implementor may wish to implement a "value comparison" in place of | ||
| 416 | * the default "reference comparison." (The <tt>List</tt> and | ||
| 417 | * <tt>Set</tt> interfaces mandate such value comparisons.)<p> | ||
| 418 | * | ||
| 419 | * The general contract for the <tt>Object.equals</tt> method states that | ||
| 420 | * equals must be symmetric (in other words, <tt>a.equals(b)</tt> if and | ||
| 421 | * only if <tt>b.equals(a)</tt>). The contracts for <tt>List.equals</tt> | ||
| 422 | * and <tt>Set.equals</tt> state that lists are only equal to other lists, | ||
| 423 | * and sets to other sets. Thus, a custom <tt>equals</tt> method for a | ||
| 424 | * collection class that implements neither the <tt>List</tt> nor | ||
| 425 | * <tt>Set</tt> interface must return <tt>false</tt> when this collection | ||
| 426 | * is compared to any list or set. (By the same logic, it is not possible | ||
| 427 | * to write a class that correctly implements both the <tt>Set</tt> and | ||
| 428 | * <tt>List</tt> interfaces.) | ||
| 429 | * | ||
| 430 | * @param o object to be compared for equality with this collection | ||
| 431 | * @return <tt>true</tt> if the specified object is equal to this | ||
| 432 | * collection | ||
| 433 | * | ||
| 434 | * @see Object#equals(Object) | ||
| 435 | * @see Set#equals(Object) | ||
| 436 | * @see List#equals(Object) | ||
| 437 | */ | ||
| 438 | boolean equals(Object o); | ||
| 439 | |||
| 440 | /** | ||
| 441 | * Returns the hash code value for this collection. While the | ||
| 442 | * <tt>Collection</tt> interface adds no stipulations to the general | ||
| 443 | * contract for the <tt>Object.hashCode</tt> method, programmers should | ||
| 444 | * take note that any class that overrides the <tt>Object.equals</tt> | ||
| 445 | * method must also override the <tt>Object.hashCode</tt> method in order | ||
| 446 | * to satisfy the general contract for the <tt>Object.hashCode</tt> method. | ||
| 447 | * In particular, <tt>c1.equals(c2)</tt> implies that | ||
| 448 | * <tt>c1.hashCode()==c2.hashCode()</tt>. | ||
| 449 | * | ||
| 450 | * @return the hash code value for this collection | ||
| 451 | * | ||
| 452 | * @see Object#hashCode() | ||
| 453 | * @see Object#equals(Object) | ||
| 454 | */ | ||
| 455 | int hashCode(); | ||
| 456 | } | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,3966 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package java.util; | ||
| 27 | import java.io.Serializable; | ||
| 28 | import java.io.ObjectOutputStream; | ||
| 29 | import java.io.IOException; | ||
| 30 | import java.lang.reflect.Array; | ||
| 31 | |||
| 32 | /** | ||
| 33 | * This class consists exclusively of static methods that operate on or return | ||
| 34 | * collections. It contains polymorphic algorithms that operate on | ||
| 35 | * collections, "wrappers", which return a new collection backed by a | ||
| 36 | * specified collection, and a few other odds and ends. | ||
| 37 | * | ||
| 38 | * <p>The methods of this class all throw a <tt>NullPointerException</tt> | ||
| 39 | * if the collections or class objects provided to them are null. | ||
| 40 | * | ||
| 41 | * <p>The documentation for the polymorphic algorithms contained in this class | ||
| 42 | * generally includes a brief description of the <i>implementation</i>. Such | ||
| 43 | * descriptions should be regarded as <i>implementation notes</i>, rather than | ||
| 44 | * parts of the <i>specification</i>. Implementors should feel free to | ||
| 45 | * substitute other algorithms, so long as the specification itself is adhered | ||
| 46 | * to. (For example, the algorithm used by <tt>sort</tt> does not have to be | ||
| 47 | * a mergesort, but it does have to be <i>stable</i>.) | ||
| 48 | * | ||
| 49 | * <p>The "destructive" algorithms contained in this class, that is, the | ||
| 50 | * algorithms that modify the collection on which they operate, are specified | ||
| 51 | * to throw <tt>UnsupportedOperationException</tt> if the collection does not | ||
| 52 | * support the appropriate mutation primitive(s), such as the <tt>set</tt> | ||
| 53 | * method. These algorithms may, but are not required to, throw this | ||
| 54 | * exception if an invocation would have no effect on the collection. For | ||
| 55 | * example, invoking the <tt>sort</tt> method on an unmodifiable list that is | ||
| 56 | * already sorted may or may not throw <tt>UnsupportedOperationException</tt>. | ||
| 57 | * | ||
| 58 | * <p>This class is a member of the | ||
| 59 | * <a href="{@docRoot}/../technotes/guides/collections/index.html"> | ||
| 60 | * Java Collections Framework</a>. | ||
| 61 | * | ||
| 62 | * @author Josh Bloch | ||
| 63 | * @author Neal Gafter | ||
| 64 | * @see Collection | ||
| 65 | * @see Set | ||
| 66 | * @see List | ||
| 67 | * @see Map | ||
| 68 | * @since 1.2 | ||
| 69 | */ | ||
| 70 | |||
| 71 | public class Collections { | ||
| 72 | // Suppresses default constructor, ensuring non-instantiability. | ||
| 73 | private Collections() { | ||
| 74 | } | ||
| 75 | |||
| 76 | // Algorithms | ||
| 77 | |||
| 78 | /* | ||
| 79 | * Tuning parameters for algorithms - Many of the List algorithms have | ||
| 80 | * two implementations, one of which is appropriate for RandomAccess | ||
| 81 | * lists, the other for "sequential." Often, the random access variant | ||
| 82 | * yields better performance on small sequential access lists. The | ||
| 83 | * tuning parameters below determine the cutoff point for what constitutes | ||
| 84 | * a "small" sequential access list for each algorithm. The values below | ||
| 85 | * were empirically determined to work well for LinkedList. Hopefully | ||
| 86 | * they should be reasonable for other sequential access List | ||
| 87 | * implementations. Those doing performance work on this code would | ||
| 88 | * do well to validate the values of these parameters from time to time. | ||
| 89 | * (The first word of each tuning parameter name is the algorithm to which | ||
| 90 | * it applies.) | ||
| 91 | */ | ||
| 92 | private static final int BINARYSEARCH_THRESHOLD = 5000; | ||
| 93 | private static final int REVERSE_THRESHOLD = 18; | ||
| 94 | private static final int SHUFFLE_THRESHOLD = 5; | ||
| 95 | private static final int FILL_THRESHOLD = 25; | ||
| 96 | private static final int ROTATE_THRESHOLD = 100; | ||
| 97 | private static final int COPY_THRESHOLD = 10; | ||
| 98 | private static final int REPLACEALL_THRESHOLD = 11; | ||
| 99 | private static final int INDEXOFSUBLIST_THRESHOLD = 35; | ||
| 100 | |||
| 101 | /** | ||
| 102 | * Sorts the specified list into ascending order, according to the | ||
| 103 | * {@linkplain Comparable natural ordering} of its elements. | ||
| 104 | * All elements in the list must implement the {@link Comparable} | ||
| 105 | * interface. Furthermore, all elements in the list must be | ||
| 106 | * <i>mutually comparable</i> (that is, {@code e1.compareTo(e2)} | ||
| 107 | * must not throw a {@code ClassCastException} for any elements | ||
| 108 | * {@code e1} and {@code e2} in the list). | ||
| 109 | * | ||
| 110 | * <p>This sort is guaranteed to be <i>stable</i>: equal elements will | ||
| 111 | * not be reordered as a result of the sort. | ||
| 112 | * | ||
| 113 | * <p>The specified list must be modifiable, but need not be resizable. | ||
| 114 | * | ||
| 115 | * <p>Implementation note: This implementation is a stable, adaptive, | ||
| 116 | * iterative mergesort that requires far fewer than n lg(n) comparisons | ||
| 117 | * when the input array is partially sorted, while offering the | ||
| 118 | * performance of a traditional mergesort when the input array is | ||
| 119 | * randomly ordered. If the input array is nearly sorted, the | ||
| 120 | * implementation requires approximately n comparisons. Temporary | ||
| 121 | * storage requirements vary from a small constant for nearly sorted | ||
| 122 | * input arrays to n/2 object references for randomly ordered input | ||
| 123 | * arrays. | ||
| 124 | * | ||
| 125 | * <p>The implementation takes equal advantage of ascending and | ||
| 126 | * descending order in its input array, and can take advantage of | ||
| 127 | * ascending and descending order in different parts of the same | ||
| 128 | * input array. It is well-suited to merging two or more sorted arrays: | ||
| 129 | * simply concatenate the arrays and sort the resulting array. | ||
| 130 | * | ||
| 131 | * <p>The implementation was adapted from Tim Peters's list sort for Python | ||
| 132 | * (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt"> | ||
| 133 | * TimSort</a>). It uses techiques from Peter McIlroy's "Optimistic | ||
| 134 | * Sorting and Information Theoretic Complexity", in Proceedings of the | ||
| 135 | * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474, | ||
| 136 | * January 1993. | ||
| 137 | * | ||
| 138 | * <p>This implementation dumps the specified list into an array, sorts | ||
| 139 | * the array, and iterates over the list resetting each element | ||
| 140 | * from the corresponding position in the array. This avoids the | ||
| 141 | * n<sup>2</sup> log(n) performance that would result from attempting | ||
| 142 | * to sort a linked list in place. | ||
| 143 | * | ||
| 144 | * @param list the list to be sorted. | ||
| 145 | * @throws ClassCastException if the list contains elements that are not | ||
| 146 | * <i>mutually comparable</i> (for example, strings and integers). | ||
| 147 | * @throws UnsupportedOperationException if the specified list's | ||
| 148 | * list-iterator does not support the {@code set} operation. | ||
| 149 | * @throws IllegalArgumentException (optional) if the implementation | ||
| 150 | * detects that the natural ordering of the list elements is | ||
| 151 | * found to violate the {@link Comparable} contract | ||
| 152 | */ | ||
| 153 | public static <T extends Comparable<? super T>> void sort(List<T> list) { | ||
| 154 | Object[] a = list.toArray(); | ||
| 155 | Arrays.sort(a); | ||
| 156 | ListIterator<T> i = list.listIterator(); | ||
| 157 | for (int j=0; j<a.length; j++) { | ||
| 158 | i.next(); | ||
| 159 | i.set((T)a[j]); | ||
| 160 | } | ||
| 161 | } | ||
| 162 | |||
| 163 | /** | ||
| 164 | * Sorts the specified list according to the order induced by the | ||
| 165 | * specified comparator. All elements in the list must be <i>mutually | ||
| 166 | * comparable</i> using the specified comparator (that is, | ||
| 167 | * {@code c.compare(e1, e2)} must not throw a {@code ClassCastException} | ||
| 168 | * for any elements {@code e1} and {@code e2} in the list). | ||
| 169 | * | ||
| 170 | * <p>This sort is guaranteed to be <i>stable</i>: equal elements will | ||
| 171 | * not be reordered as a result of the sort. | ||
| 172 | * | ||
| 173 | * <p>The specified list must be modifiable, but need not be resizable. | ||
| 174 | * | ||
| 175 | * <p>Implementation note: This implementation is a stable, adaptive, | ||
| 176 | * iterative mergesort that requires far fewer than n lg(n) comparisons | ||
| 177 | * when the input array is partially sorted, while offering the | ||
| 178 | * performance of a traditional mergesort when the input array is | ||
| 179 | * randomly ordered. If the input array is nearly sorted, the | ||
| 180 | * implementation requires approximately n comparisons. Temporary | ||
| 181 | * storage requirements vary from a small constant for nearly sorted | ||
| 182 | * input arrays to n/2 object references for randomly ordered input | ||
| 183 | * arrays. | ||
| 184 | * | ||
| 185 | * <p>The implementation takes equal advantage of ascending and | ||
| 186 | * descending order in its input array, and can take advantage of | ||
| 187 | * ascending and descending order in different parts of the same | ||
| 188 | * input array. It is well-suited to merging two or more sorted arrays: | ||
| 189 | * simply concatenate the arrays and sort the resulting array. | ||
| 190 | * | ||
| 191 | * <p>The implementation was adapted from Tim Peters's list sort for Python | ||
| 192 | * (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt"> | ||
| 193 | * TimSort</a>). It uses techiques from Peter McIlroy's "Optimistic | ||
| 194 | * Sorting and Information Theoretic Complexity", in Proceedings of the | ||
| 195 | * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474, | ||
| 196 | * January 1993. | ||
| 197 | * | ||
| 198 | * <p>This implementation dumps the specified list into an array, sorts | ||
| 199 | * the array, and iterates over the list resetting each element | ||
| 200 | * from the corresponding position in the array. This avoids the | ||
| 201 | * n<sup>2</sup> log(n) performance that would result from attempting | ||
| 202 | * to sort a linked list in place. | ||
| 203 | * | ||
| 204 | * @param list the list to be sorted. | ||
| 205 | * @param c the comparator to determine the order of the list. A | ||
| 206 | * {@code null} value indicates that the elements' <i>natural | ||
| 207 | * ordering</i> should be used. | ||
| 208 | * @throws ClassCastException if the list contains elements that are not | ||
| 209 | * <i>mutually comparable</i> using the specified comparator. | ||
| 210 | * @throws UnsupportedOperationException if the specified list's | ||
| 211 | * list-iterator does not support the {@code set} operation. | ||
| 212 | * @throws IllegalArgumentException (optional) if the comparator is | ||
| 213 | * found to violate the {@link Comparator} contract | ||
| 214 | */ | ||
| 215 | public static <T> void sort(List<T> list, Comparator<? super T> c) { | ||
| 216 | Object[] a = list.toArray(); | ||
| 217 | Arrays.sort(a, (Comparator)c); | ||
| 218 | ListIterator i = list.listIterator(); | ||
| 219 | for (int j=0; j<a.length; j++) { | ||
| 220 | i.next(); | ||
| 221 | i.set(a[j]); | ||
| 222 | } | ||
| 223 | } | ||
| 224 | |||
| 225 | |||
| 226 | /** | ||
| 227 | * Searches the specified list for the specified object using the binary | ||
| 228 | * search algorithm. The list must be sorted into ascending order | ||
| 229 | * according to the {@linkplain Comparable natural ordering} of its | ||
| 230 | * elements (as by the {@link #sort(List)} method) prior to making this | ||
| 231 | * call. If it is not sorted, the results are undefined. If the list | ||
| 232 | * contains multiple elements equal to the specified object, there is no | ||
| 233 | * guarantee which one will be found. | ||
| 234 | * | ||
| 235 | * <p>This method runs in log(n) time for a "random access" list (which | ||
| 236 | * provides near-constant-time positional access). If the specified list | ||
| 237 | * does not implement the {@link RandomAccess} interface and is large, | ||
| 238 | * this method will do an iterator-based binary search that performs | ||
| 239 | * O(n) link traversals and O(log n) element comparisons. | ||
| 240 | * | ||
| 241 | * @param list the list to be searched. | ||
| 242 | * @param key the key to be searched for. | ||
| 243 | * @return the index of the search key, if it is contained in the list; | ||
| 244 | * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The | ||
| 245 | * <i>insertion point</i> is defined as the point at which the | ||
| 246 | * key would be inserted into the list: the index of the first | ||
| 247 | * element greater than the key, or <tt>list.size()</tt> if all | ||
| 248 | * elements in the list are less than the specified key. Note | ||
| 249 | * that this guarantees that the return value will be >= 0 if | ||
| 250 | * and only if the key is found. | ||
| 251 | * @throws ClassCastException if the list contains elements that are not | ||
| 252 | * <i>mutually comparable</i> (for example, strings and | ||
| 253 | * integers), or the search key is not mutually comparable | ||
| 254 | * with the elements of the list. | ||
| 255 | */ | ||
| 256 | public static <T> | ||
| 257 | int binarySearch(List<? extends Comparable<? super T>> list, T key) { | ||
| 258 | if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD) | ||
| 259 | return Collections.indexedBinarySearch(list, key); | ||
| 260 | else | ||
| 261 | return Collections.iteratorBinarySearch(list, key); | ||
| 262 | } | ||
| 263 | |||
| 264 | private static <T> | ||
| 265 | int indexedBinarySearch(List<? extends Comparable<? super T>> list, T key) | ||
| 266 | { | ||
| 267 | int low = 0; | ||
| 268 | int high = list.size()-1; | ||
| 269 | |||
| 270 | while (low <= high) { | ||
| 271 | int mid = (low + high) >>> 1; | ||
| 272 | Comparable<? super T> midVal = list.get(mid); | ||
| 273 | int cmp = midVal.compareTo(key); | ||
| 274 | |||
| 275 | if (cmp < 0) | ||
| 276 | low = mid + 1; | ||
| 277 | else if (cmp > 0) | ||
| 278 | high = mid - 1; | ||
| 279 | else | ||
| 280 | return mid; // key found | ||
| 281 | } | ||
| 282 | return -(low + 1); // key not found | ||
| 283 | } | ||
| 284 | |||
| 285 | private static <T> | ||
| 286 | int iteratorBinarySearch(List<? extends Comparable<? super T>> list, T key) | ||
| 287 | { | ||
| 288 | int low = 0; | ||
| 289 | int high = list.size()-1; | ||
| 290 | ListIterator<? extends Comparable<? super T>> i = list.listIterator(); | ||
| 291 | |||
| 292 | while (low <= high) { | ||
| 293 | int mid = (low + high) >>> 1; | ||
| 294 | Comparable<? super T> midVal = get(i, mid); | ||
| 295 | int cmp = midVal.compareTo(key); | ||
| 296 | |||
| 297 | if (cmp < 0) | ||
| 298 | low = mid + 1; | ||
| 299 | else if (cmp > 0) | ||
| 300 | high = mid - 1; | ||
| 301 | else | ||
| 302 | return mid; // key found | ||
| 303 | } | ||
| 304 | return -(low + 1); // key not found | ||
| 305 | } | ||
| 306 | |||
| 307 | /** | ||
| 308 | * Gets the ith element from the given list by repositioning the specified | ||
| 309 | * list listIterator. | ||
| 310 | */ | ||
| 311 | private static <T> T get(ListIterator<? extends T> i, int index) { | ||
| 312 | T obj = null; | ||
| 313 | int pos = i.nextIndex(); | ||
| 314 | if (pos <= index) { | ||
| 315 | do { | ||
| 316 | obj = i.next(); | ||
| 317 | } while (pos++ < index); | ||
| 318 | } else { | ||
| 319 | do { | ||
| 320 | obj = i.previous(); | ||
| 321 | } while (--pos > index); | ||
| 322 | } | ||
| 323 | return obj; | ||
| 324 | } | ||
| 325 | |||
| 326 | /** | ||
| 327 | * Searches the specified list for the specified object using the binary | ||
| 328 | * search algorithm. The list must be sorted into ascending order | ||
| 329 | * according to the specified comparator (as by the | ||
| 330 | * {@link #sort(List, Comparator) sort(List, Comparator)} | ||
| 331 | * method), prior to making this call. If it is | ||
| 332 | * not sorted, the results are undefined. If the list contains multiple | ||
| 333 | * elements equal to the specified object, there is no guarantee which one | ||
| 334 | * will be found. | ||
| 335 | * | ||
| 336 | * <p>This method runs in log(n) time for a "random access" list (which | ||
| 337 | * provides near-constant-time positional access). If the specified list | ||
| 338 | * does not implement the {@link RandomAccess} interface and is large, | ||
| 339 | * this method will do an iterator-based binary search that performs | ||
| 340 | * O(n) link traversals and O(log n) element comparisons. | ||
| 341 | * | ||
| 342 | * @param list the list to be searched. | ||
| 343 | * @param key the key to be searched for. | ||
| 344 | * @param c the comparator by which the list is ordered. | ||
| 345 | * A <tt>null</tt> value indicates that the elements' | ||
| 346 | * {@linkplain Comparable natural ordering} should be used. | ||
| 347 | * @return the index of the search key, if it is contained in the list; | ||
| 348 | * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The | ||
| 349 | * <i>insertion point</i> is defined as the point at which the | ||
| 350 | * key would be inserted into the list: the index of the first | ||
| 351 | * element greater than the key, or <tt>list.size()</tt> if all | ||
| 352 | * elements in the list are less than the specified key. Note | ||
| 353 | * that this guarantees that the return value will be >= 0 if | ||
| 354 | * and only if the key is found. | ||
| 355 | * @throws ClassCastException if the list contains elements that are not | ||
| 356 | * <i>mutually comparable</i> using the specified comparator, | ||
| 357 | * or the search key is not mutually comparable with the | ||
| 358 | * elements of the list using this comparator. | ||
| 359 | */ | ||
| 360 | public static <T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c) { | ||
| 361 | if (c==null) | ||
| 362 | return binarySearch((List) list, key); | ||
| 363 | |||
| 364 | if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD) | ||
| 365 | return Collections.indexedBinarySearch(list, key, c); | ||
| 366 | else | ||
| 367 | return Collections.iteratorBinarySearch(list, key, c); | ||
| 368 | } | ||
| 369 | |||
| 370 | private static <T> int indexedBinarySearch(List<? extends T> l, T key, Comparator<? super T> c) { | ||
| 371 | int low = 0; | ||
| 372 | int high = l.size()-1; | ||
| 373 | |||
| 374 | while (low <= high) { | ||
| 375 | int mid = (low + high) >>> 1; | ||
| 376 | T midVal = l.get(mid); | ||
| 377 | int cmp = c.compare(midVal, key); | ||
| 378 | |||
| 379 | if (cmp < 0) | ||
| 380 | low = mid + 1; | ||
| 381 | else if (cmp > 0) | ||
| 382 | high = mid - 1; | ||
| 383 | else | ||
| 384 | return mid; // key found | ||
| 385 | } | ||
| 386 | return -(low + 1); // key not found | ||
| 387 | } | ||
| 388 | |||
| 389 | private static <T> int iteratorBinarySearch(List<? extends T> l, T key, Comparator<? super T> c) { | ||
| 390 | int low = 0; | ||
| 391 | int high = l.size()-1; | ||
| 392 | ListIterator<? extends T> i = l.listIterator(); | ||
| 393 | |||
| 394 | while (low <= high) { | ||
| 395 | int mid = (low + high) >>> 1; | ||
| 396 | T midVal = get(i, mid); | ||
| 397 | int cmp = c.compare(midVal, key); | ||
| 398 | |||
| 399 | if (cmp < 0) | ||
| 400 | low = mid + 1; | ||
| 401 | else if (cmp > 0) | ||
| 402 | high = mid - 1; | ||
| 403 | else | ||
| 404 | return mid; // key found | ||
| 405 | } | ||
| 406 | return -(low + 1); // key not found | ||
| 407 | } | ||
| 408 | |||
| 409 | private interface SelfComparable extends Comparable<SelfComparable> {} | ||
| 410 | |||
| 411 | |||
| 412 | /** | ||
| 413 | * Reverses the order of the elements in the specified list.<p> | ||
| 414 | * | ||
| 415 | * This method runs in linear time. | ||
| 416 | * | ||
| 417 | * @param list the list whose elements are to be reversed. | ||
| 418 | * @throws UnsupportedOperationException if the specified list or | ||
| 419 | * its list-iterator does not support the <tt>set</tt> operation. | ||
| 420 | */ | ||
| 421 | public static void reverse(List<?> list) { | ||
| 422 | int size = list.size(); | ||
| 423 | if (size < REVERSE_THRESHOLD || list instanceof RandomAccess) { | ||
| 424 | for (int i=0, mid=size>>1, j=size-1; i<mid; i++, j--) | ||
| 425 | swap(list, i, j); | ||
| 426 | } else { | ||
| 427 | ListIterator fwd = list.listIterator(); | ||
| 428 | ListIterator rev = list.listIterator(size); | ||
| 429 | for (int i=0, mid=list.size()>>1; i<mid; i++) { | ||
| 430 | Object tmp = fwd.next(); | ||
| 431 | fwd.set(rev.previous()); | ||
| 432 | rev.set(tmp); | ||
| 433 | } | ||
| 434 | } | ||
| 435 | } | ||
| 436 | |||
| 437 | /** | ||
| 438 | * Randomly permutes the specified list using a default source of | ||
| 439 | * randomness. All permutations occur with approximately equal | ||
| 440 | * likelihood.<p> | ||
| 441 | * | ||
| 442 | * The hedge "approximately" is used in the foregoing description because | ||
| 443 | * default source of randomness is only approximately an unbiased source | ||
| 444 | * of independently chosen bits. If it were a perfect source of randomly | ||
| 445 | * chosen bits, then the algorithm would choose permutations with perfect | ||
| 446 | * uniformity.<p> | ||
| 447 | * | ||
| 448 | * This implementation traverses the list backwards, from the last element | ||
| 449 | * up to the second, repeatedly swapping a randomly selected element into | ||
| 450 | * the "current position". Elements are randomly selected from the | ||
| 451 | * portion of the list that runs from the first element to the current | ||
| 452 | * position, inclusive.<p> | ||
| 453 | * | ||
| 454 | * This method runs in linear time. If the specified list does not | ||
| 455 | * implement the {@link RandomAccess} interface and is large, this | ||
| 456 | * implementation dumps the specified list into an array before shuffling | ||
| 457 | * it, and dumps the shuffled array back into the list. This avoids the | ||
| 458 | * quadratic behavior that would result from shuffling a "sequential | ||
| 459 | * access" list in place. | ||
| 460 | * | ||
| 461 | * @param list the list to be shuffled. | ||
| 462 | * @throws UnsupportedOperationException if the specified list or | ||
| 463 | * its list-iterator does not support the <tt>set</tt> operation. | ||
| 464 | */ | ||
| 465 | public static void shuffle(List<?> list) { | ||
| 466 | Random rnd = r; | ||
| 467 | if (rnd == null) | ||
| 468 | r = rnd = new Random(); | ||
| 469 | shuffle(list, rnd); | ||
| 470 | } | ||
| 471 | private static Random r; | ||
| 472 | |||
| 473 | /** | ||
| 474 | * Randomly permute the specified list using the specified source of | ||
| 475 | * randomness. All permutations occur with equal likelihood | ||
| 476 | * assuming that the source of randomness is fair.<p> | ||
| 477 | * | ||
| 478 | * This implementation traverses the list backwards, from the last element | ||
| 479 | * up to the second, repeatedly swapping a randomly selected element into | ||
| 480 | * the "current position". Elements are randomly selected from the | ||
| 481 | * portion of the list that runs from the first element to the current | ||
| 482 | * position, inclusive.<p> | ||
| 483 | * | ||
| 484 | * This method runs in linear time. If the specified list does not | ||
| 485 | * implement the {@link RandomAccess} interface and is large, this | ||
| 486 | * implementation dumps the specified list into an array before shuffling | ||
| 487 | * it, and dumps the shuffled array back into the list. This avoids the | ||
| 488 | * quadratic behavior that would result from shuffling a "sequential | ||
| 489 | * access" list in place. | ||
| 490 | * | ||
| 491 | * @param list the list to be shuffled. | ||
| 492 | * @param rnd the source of randomness to use to shuffle the list. | ||
| 493 | * @throws UnsupportedOperationException if the specified list or its | ||
| 494 | * list-iterator does not support the <tt>set</tt> operation. | ||
| 495 | */ | ||
| 496 | public static void shuffle(List<?> list, Random rnd) { | ||
| 497 | int size = list.size(); | ||
| 498 | if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) { | ||
| 499 | for (int i=size; i>1; i--) | ||
| 500 | swap(list, i-1, rnd.nextInt(i)); | ||
| 501 | } else { | ||
| 502 | Object arr[] = list.toArray(); | ||
| 503 | |||
| 504 | // Shuffle array | ||
| 505 | for (int i=size; i>1; i--) | ||
| 506 | swap(arr, i-1, rnd.nextInt(i)); | ||
| 507 | |||
| 508 | // Dump array back into list | ||
| 509 | ListIterator it = list.listIterator(); | ||
| 510 | for (int i=0; i<arr.length; i++) { | ||
| 511 | it.next(); | ||
| 512 | it.set(arr[i]); | ||
| 513 | } | ||
| 514 | } | ||
| 515 | } | ||
| 516 | |||
| 517 | /** | ||
| 518 | * Swaps the elements at the specified positions in the specified list. | ||
| 519 | * (If the specified positions are equal, invoking this method leaves | ||
| 520 | * the list unchanged.) | ||
| 521 | * | ||
| 522 | * @param list The list in which to swap elements. | ||
| 523 | * @param i the index of one element to be swapped. | ||
| 524 | * @param j the index of the other element to be swapped. | ||
| 525 | * @throws IndexOutOfBoundsException if either <tt>i</tt> or <tt>j</tt> | ||
| 526 | * is out of range (i < 0 || i >= list.size() | ||
| 527 | * || j < 0 || j >= list.size()). | ||
| 528 | * @since 1.4 | ||
| 529 | */ | ||
| 530 | public static void swap(List<?> list, int i, int j) { | ||
| 531 | final List l = list; | ||
| 532 | l.set(i, l.set(j, l.get(i))); | ||
| 533 | } | ||
| 534 | |||
| 535 | /** | ||
| 536 | * Swaps the two specified elements in the specified array. | ||
| 537 | */ | ||
| 538 | private static void swap(Object[] arr, int i, int j) { | ||
| 539 | Object tmp = arr[i]; | ||
| 540 | arr[i] = arr[j]; | ||
| 541 | arr[j] = tmp; | ||
| 542 | } | ||
| 543 | |||
| 544 | /** | ||
| 545 | * Replaces all of the elements of the specified list with the specified | ||
| 546 | * element. <p> | ||
| 547 | * | ||
| 548 | * This method runs in linear time. | ||
| 549 | * | ||
| 550 | * @param list the list to be filled with the specified element. | ||
| 551 | * @param obj The element with which to fill the specified list. | ||
| 552 | * @throws UnsupportedOperationException if the specified list or its | ||
| 553 | * list-iterator does not support the <tt>set</tt> operation. | ||
| 554 | */ | ||
| 555 | public static <T> void fill(List<? super T> list, T obj) { | ||
| 556 | int size = list.size(); | ||
| 557 | |||
| 558 | if (size < FILL_THRESHOLD || list instanceof RandomAccess) { | ||
| 559 | for (int i=0; i<size; i++) | ||
| 560 | list.set(i, obj); | ||
| 561 | } else { | ||
| 562 | ListIterator<? super T> itr = list.listIterator(); | ||
| 563 | for (int i=0; i<size; i++) { | ||
| 564 | itr.next(); | ||
| 565 | itr.set(obj); | ||
| 566 | } | ||
| 567 | } | ||
| 568 | } | ||
| 569 | |||
| 570 | /** | ||
| 571 | * Copies all of the elements from one list into another. After the | ||
| 572 | * operation, the index of each copied element in the destination list | ||
| 573 | * will be identical to its index in the source list. The destination | ||
| 574 | * list must be at least as long as the source list. If it is longer, the | ||
| 575 | * remaining elements in the destination list are unaffected. <p> | ||
| 576 | * | ||
| 577 | * This method runs in linear time. | ||
| 578 | * | ||
| 579 | * @param dest The destination list. | ||
| 580 | * @param src The source list. | ||
| 581 | * @throws IndexOutOfBoundsException if the destination list is too small | ||
| 582 | * to contain the entire source List. | ||
| 583 | * @throws UnsupportedOperationException if the destination list's | ||
| 584 | * list-iterator does not support the <tt>set</tt> operation. | ||
| 585 | */ | ||
| 586 | public static <T> void copy(List<? super T> dest, List<? extends T> src) { | ||
| 587 | int srcSize = src.size(); | ||
| 588 | if (srcSize > dest.size()) | ||
| 589 | throw new IndexOutOfBoundsException("Source does not fit in dest"); | ||
| 590 | |||
| 591 | if (srcSize < COPY_THRESHOLD || | ||
| 592 | (src instanceof RandomAccess && dest instanceof RandomAccess)) { | ||
| 593 | for (int i=0; i<srcSize; i++) | ||
| 594 | dest.set(i, src.get(i)); | ||
| 595 | } else { | ||
| 596 | ListIterator<? super T> di=dest.listIterator(); | ||
| 597 | ListIterator<? extends T> si=src.listIterator(); | ||
| 598 | for (int i=0; i<srcSize; i++) { | ||
| 599 | di.next(); | ||
| 600 | di.set(si.next()); | ||
| 601 | } | ||
| 602 | } | ||
| 603 | } | ||
| 604 | |||
| 605 | /** | ||
| 606 | * Returns the minimum element of the given collection, according to the | ||
| 607 | * <i>natural ordering</i> of its elements. All elements in the | ||
| 608 | * collection must implement the <tt>Comparable</tt> interface. | ||
| 609 | * Furthermore, all elements in the collection must be <i>mutually | ||
| 610 | * comparable</i> (that is, <tt>e1.compareTo(e2)</tt> must not throw a | ||
| 611 | * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and | ||
| 612 | * <tt>e2</tt> in the collection).<p> | ||
| 613 | * | ||
| 614 | * This method iterates over the entire collection, hence it requires | ||
| 615 | * time proportional to the size of the collection. | ||
| 616 | * | ||
| 617 | * @param coll the collection whose minimum element is to be determined. | ||
| 618 | * @return the minimum element of the given collection, according | ||
| 619 | * to the <i>natural ordering</i> of its elements. | ||
| 620 | * @throws ClassCastException if the collection contains elements that are | ||
| 621 | * not <i>mutually comparable</i> (for example, strings and | ||
| 622 | * integers). | ||
| 623 | * @throws NoSuchElementException if the collection is empty. | ||
| 624 | * @see Comparable | ||
| 625 | */ | ||
| 626 | public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll) { | ||
| 627 | Iterator<? extends T> i = coll.iterator(); | ||
| 628 | T candidate = i.next(); | ||
| 629 | |||
| 630 | while (i.hasNext()) { | ||
| 631 | T next = i.next(); | ||
| 632 | if (next.compareTo(candidate) < 0) | ||
| 633 | candidate = next; | ||
| 634 | } | ||
| 635 | return candidate; | ||
| 636 | } | ||
| 637 | |||
| 638 | /** | ||
| 639 | * Returns the minimum element of the given collection, according to the | ||
| 640 | * order induced by the specified comparator. All elements in the | ||
| 641 | * collection must be <i>mutually comparable</i> by the specified | ||
| 642 | * comparator (that is, <tt>comp.compare(e1, e2)</tt> must not throw a | ||
| 643 | * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and | ||
| 644 | * <tt>e2</tt> in the collection).<p> | ||
| 645 | * | ||
| 646 | * This method iterates over the entire collection, hence it requires | ||
| 647 | * time proportional to the size of the collection. | ||
| 648 | * | ||
| 649 | * @param coll the collection whose minimum element is to be determined. | ||
| 650 | * @param comp the comparator with which to determine the minimum element. | ||
| 651 | * A <tt>null</tt> value indicates that the elements' <i>natural | ||
| 652 | * ordering</i> should be used. | ||
| 653 | * @return the minimum element of the given collection, according | ||
| 654 | * to the specified comparator. | ||
| 655 | * @throws ClassCastException if the collection contains elements that are | ||
| 656 | * not <i>mutually comparable</i> using the specified comparator. | ||
| 657 | * @throws NoSuchElementException if the collection is empty. | ||
| 658 | * @see Comparable | ||
| 659 | */ | ||
| 660 | public static <T> T min(Collection<? extends T> coll, Comparator<? super T> comp) { | ||
| 661 | if (comp==null) | ||
| 662 | return (T)min((Collection<SelfComparable>) (Collection) coll); | ||
| 663 | |||
| 664 | Iterator<? extends T> i = coll.iterator(); | ||
| 665 | T candidate = i.next(); | ||
| 666 | |||
| 667 | while (i.hasNext()) { | ||
| 668 | T next = i.next(); | ||
| 669 | if (comp.compare(next, candidate) < 0) | ||
| 670 | candidate = next; | ||
| 671 | } | ||
| 672 | return candidate; | ||
| 673 | } | ||
| 674 | |||
| 675 | /** | ||
| 676 | * Returns the maximum element of the given collection, according to the | ||
| 677 | * <i>natural ordering</i> of its elements. All elements in the | ||
| 678 | * collection must implement the <tt>Comparable</tt> interface. | ||
| 679 | * Furthermore, all elements in the collection must be <i>mutually | ||
| 680 | * comparable</i> (that is, <tt>e1.compareTo(e2)</tt> must not throw a | ||
| 681 | * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and | ||
| 682 | * <tt>e2</tt> in the collection).<p> | ||
| 683 | * | ||
| 684 | * This method iterates over the entire collection, hence it requires | ||
| 685 | * time proportional to the size of the collection. | ||
| 686 | * | ||
| 687 | * @param coll the collection whose maximum element is to be determined. | ||
| 688 | * @return the maximum element of the given collection, according | ||
| 689 | * to the <i>natural ordering</i> of its elements. | ||
| 690 | * @throws ClassCastException if the collection contains elements that are | ||
| 691 | * not <i>mutually comparable</i> (for example, strings and | ||
| 692 | * integers). | ||
| 693 | * @throws NoSuchElementException if the collection is empty. | ||
| 694 | * @see Comparable | ||
| 695 | */ | ||
| 696 | public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) { | ||
| 697 | Iterator<? extends T> i = coll.iterator(); | ||
| 698 | T candidate = i.next(); | ||
| 699 | |||
| 700 | while (i.hasNext()) { | ||
| 701 | T next = i.next(); | ||
| 702 | if (next.compareTo(candidate) > 0) | ||
| 703 | candidate = next; | ||
| 704 | } | ||
| 705 | return candidate; | ||
| 706 | } | ||
| 707 | |||
| 708 | /** | ||
| 709 | * Returns the maximum element of the given collection, according to the | ||
| 710 | * order induced by the specified comparator. All elements in the | ||
| 711 | * collection must be <i>mutually comparable</i> by the specified | ||
| 712 | * comparator (that is, <tt>comp.compare(e1, e2)</tt> must not throw a | ||
| 713 | * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and | ||
| 714 | * <tt>e2</tt> in the collection).<p> | ||
| 715 | * | ||
| 716 | * This method iterates over the entire collection, hence it requires | ||
| 717 | * time proportional to the size of the collection. | ||
| 718 | * | ||
| 719 | * @param coll the collection whose maximum element is to be determined. | ||
| 720 | * @param comp the comparator with which to determine the maximum element. | ||
| 721 | * A <tt>null</tt> value indicates that the elements' <i>natural | ||
| 722 | * ordering</i> should be used. | ||
| 723 | * @return the maximum element of the given collection, according | ||
| 724 | * to the specified comparator. | ||
| 725 | * @throws ClassCastException if the collection contains elements that are | ||
| 726 | * not <i>mutually comparable</i> using the specified comparator. | ||
| 727 | * @throws NoSuchElementException if the collection is empty. | ||
| 728 | * @see Comparable | ||
| 729 | */ | ||
| 730 | public static <T> T max(Collection<? extends T> coll, Comparator<? super T> comp) { | ||
| 731 | if (comp==null) | ||
| 732 | return (T)max((Collection<SelfComparable>) (Collection) coll); | ||
| 733 | |||
| 734 | Iterator<? extends T> i = coll.iterator(); | ||
| 735 | T candidate = i.next(); | ||
| 736 | |||
| 737 | while (i.hasNext()) { | ||
| 738 | T next = i.next(); | ||
| 739 | if (comp.compare(next, candidate) > 0) | ||
| 740 | candidate = next; | ||
| 741 | } | ||
| 742 | return candidate; | ||
| 743 | } | ||
| 744 | |||
| 745 | /** | ||
| 746 | * Rotates the elements in the specified list by the specified distance. | ||
| 747 | * After calling this method, the element at index <tt>i</tt> will be | ||
| 748 | * the element previously at index <tt>(i - distance)</tt> mod | ||
| 749 | * <tt>list.size()</tt>, for all values of <tt>i</tt> between <tt>0</tt> | ||
| 750 | * and <tt>list.size()-1</tt>, inclusive. (This method has no effect on | ||
| 751 | * the size of the list.) | ||
| 752 | * | ||
| 753 | * <p>For example, suppose <tt>list</tt> comprises<tt> [t, a, n, k, s]</tt>. | ||
| 754 | * After invoking <tt>Collections.rotate(list, 1)</tt> (or | ||
| 755 | * <tt>Collections.rotate(list, -4)</tt>), <tt>list</tt> will comprise | ||
| 756 | * <tt>[s, t, a, n, k]</tt>. | ||
| 757 | * | ||
| 758 | * <p>Note that this method can usefully be applied to sublists to | ||
| 759 | * move one or more elements within a list while preserving the | ||
| 760 | * order of the remaining elements. For example, the following idiom | ||
| 761 | * moves the element at index <tt>j</tt> forward to position | ||
| 762 | * <tt>k</tt> (which must be greater than or equal to <tt>j</tt>): | ||
| 763 | * <pre> | ||
| 764 | * Collections.rotate(list.subList(j, k+1), -1); | ||
| 765 | * </pre> | ||
| 766 | * To make this concrete, suppose <tt>list</tt> comprises | ||
| 767 | * <tt>[a, b, c, d, e]</tt>. To move the element at index <tt>1</tt> | ||
| 768 | * (<tt>b</tt>) forward two positions, perform the following invocation: | ||
| 769 | * <pre> | ||
| 770 | * Collections.rotate(l.subList(1, 4), -1); | ||
| 771 | * </pre> | ||
| 772 | * The resulting list is <tt>[a, c, d, b, e]</tt>. | ||
| 773 | * | ||
| 774 | * <p>To move more than one element forward, increase the absolute value | ||
| 775 | * of the rotation distance. To move elements backward, use a positive | ||
| 776 | * shift distance. | ||
| 777 | * | ||
| 778 | * <p>If the specified list is small or implements the {@link | ||
| 779 | * RandomAccess} interface, this implementation exchanges the first | ||
| 780 | * element into the location it should go, and then repeatedly exchanges | ||
| 781 | * the displaced element into the location it should go until a displaced | ||
| 782 | * element is swapped into the first element. If necessary, the process | ||
| 783 | * is repeated on the second and successive elements, until the rotation | ||
| 784 | * is complete. If the specified list is large and doesn't implement the | ||
| 785 | * <tt>RandomAccess</tt> interface, this implementation breaks the | ||
| 786 | * list into two sublist views around index <tt>-distance mod size</tt>. | ||
| 787 | * Then the {@link #reverse(List)} method is invoked on each sublist view, | ||
| 788 | * and finally it is invoked on the entire list. For a more complete | ||
| 789 | * description of both algorithms, see Section 2.3 of Jon Bentley's | ||
| 790 | * <i>Programming Pearls</i> (Addison-Wesley, 1986). | ||
| 791 | * | ||
| 792 | * @param list the list to be rotated. | ||
| 793 | * @param distance the distance to rotate the list. There are no | ||
| 794 | * constraints on this value; it may be zero, negative, or | ||
| 795 | * greater than <tt>list.size()</tt>. | ||
| 796 | * @throws UnsupportedOperationException if the specified list or | ||
| 797 | * its list-iterator does not support the <tt>set</tt> operation. | ||
| 798 | * @since 1.4 | ||
| 799 | */ | ||
| 800 | public static void rotate(List<?> list, int distance) { | ||
| 801 | if (list instanceof RandomAccess || list.size() < ROTATE_THRESHOLD) | ||
| 802 | rotate1(list, distance); | ||
| 803 | else | ||
| 804 | rotate2(list, distance); | ||
| 805 | } | ||
| 806 | |||
| 807 | private static <T> void rotate1(List<T> list, int distance) { | ||
| 808 | int size = list.size(); | ||
| 809 | if (size == 0) | ||
| 810 | return; | ||
| 811 | distance = distance % size; | ||
| 812 | if (distance < 0) | ||
| 813 | distance += size; | ||
| 814 | if (distance == 0) | ||
| 815 | return; | ||
| 816 | |||
| 817 | for (int cycleStart = 0, nMoved = 0; nMoved != size; cycleStart++) { | ||
| 818 | T displaced = list.get(cycleStart); | ||
| 819 | int i = cycleStart; | ||
| 820 | do { | ||
| 821 | i += distance; | ||
| 822 | if (i >= size) | ||
| 823 | i -= size; | ||
| 824 | displaced = list.set(i, displaced); | ||
| 825 | nMoved ++; | ||
| 826 | } while (i != cycleStart); | ||
| 827 | } | ||
| 828 | } | ||
| 829 | |||
| 830 | private static void rotate2(List<?> list, int distance) { | ||
| 831 | int size = list.size(); | ||
| 832 | if (size == 0) | ||
| 833 | return; | ||
| 834 | int mid = -distance % size; | ||
| 835 | if (mid < 0) | ||
| 836 | mid += size; | ||
| 837 | if (mid == 0) | ||
| 838 | return; | ||
| 839 | |||
| 840 | reverse(list.subList(0, mid)); | ||
| 841 | reverse(list.subList(mid, size)); | ||
| 842 | reverse(list); | ||
| 843 | } | ||
| 844 | |||
| 845 | /** | ||
| 846 | * Replaces all occurrences of one specified value in a list with another. | ||
| 847 | * More formally, replaces with <tt>newVal</tt> each element <tt>e</tt> | ||
| 848 | * in <tt>list</tt> such that | ||
| 849 | * <tt>(oldVal==null ? e==null : oldVal.equals(e))</tt>. | ||
| 850 | * (This method has no effect on the size of the list.) | ||
| 851 | * | ||
| 852 | * @param list the list in which replacement is to occur. | ||
| 853 | * @param oldVal the old value to be replaced. | ||
| 854 | * @param newVal the new value with which <tt>oldVal</tt> is to be | ||
| 855 | * replaced. | ||
| 856 | * @return <tt>true</tt> if <tt>list</tt> contained one or more elements | ||
| 857 | * <tt>e</tt> such that | ||
| 858 | * <tt>(oldVal==null ? e==null : oldVal.equals(e))</tt>. | ||
| 859 | * @throws UnsupportedOperationException if the specified list or | ||
| 860 | * its list-iterator does not support the <tt>set</tt> operation. | ||
| 861 | * @since 1.4 | ||
| 862 | */ | ||
| 863 | public static <T> boolean replaceAll(List<T> list, T oldVal, T newVal) { | ||
| 864 | boolean result = false; | ||
| 865 | int size = list.size(); | ||
| 866 | if (size < REPLACEALL_THRESHOLD || list instanceof RandomAccess) { | ||
| 867 | if (oldVal==null) { | ||
| 868 | for (int i=0; i<size; i++) { | ||
| 869 | if (list.get(i)==null) { | ||
| 870 | list.set(i, newVal); | ||
| 871 | result = true; | ||
| 872 | } | ||
| 873 | } | ||
| 874 | } else { | ||
| 875 | for (int i=0; i<size; i++) { | ||
| 876 | if (oldVal.equals(list.get(i))) { | ||
| 877 | list.set(i, newVal); | ||
| 878 | result = true; | ||
| 879 | } | ||
| 880 | } | ||
| 881 | } | ||
| 882 | } else { | ||
| 883 | ListIterator<T> itr=list.listIterator(); | ||
| 884 | if (oldVal==null) { | ||
| 885 | for (int i=0; i<size; i++) { | ||
| 886 | if (itr.next()==null) { | ||
| 887 | itr.set(newVal); | ||
| 888 | result = true; | ||
| 889 | } | ||
| 890 | } | ||
| 891 | } else { | ||
| 892 | for (int i=0; i<size; i++) { | ||
| 893 | if (oldVal.equals(itr.next())) { | ||
| 894 | itr.set(newVal); | ||
| 895 | result = true; | ||
| 896 | } | ||
| 897 | } | ||
| 898 | } | ||
| 899 | } | ||
| 900 | return result; | ||
| 901 | } | ||
| 902 | |||
| 903 | /** | ||
| 904 | * Returns the starting position of the first occurrence of the specified | ||
| 905 | * target list within the specified source list, or -1 if there is no | ||
| 906 | * such occurrence. More formally, returns the lowest index <tt>i</tt> | ||
| 907 | * such that <tt>source.subList(i, i+target.size()).equals(target)</tt>, | ||
| 908 | * or -1 if there is no such index. (Returns -1 if | ||
| 909 | * <tt>target.size() > source.size()</tt>.) | ||
| 910 | * | ||
| 911 | * <p>This implementation uses the "brute force" technique of scanning | ||
| 912 | * over the source list, looking for a match with the target at each | ||
| 913 | * location in turn. | ||
| 914 | * | ||
| 915 | * @param source the list in which to search for the first occurrence | ||
| 916 | * of <tt>target</tt>. | ||
| 917 | * @param target the list to search for as a subList of <tt>source</tt>. | ||
| 918 | * @return the starting position of the first occurrence of the specified | ||
| 919 | * target list within the specified source list, or -1 if there | ||
| 920 | * is no such occurrence. | ||
| 921 | * @since 1.4 | ||
| 922 | */ | ||
| 923 | public static int indexOfSubList(List<?> source, List<?> target) { | ||
| 924 | int sourceSize = source.size(); | ||
| 925 | int targetSize = target.size(); | ||
| 926 | int maxCandidate = sourceSize - targetSize; | ||
| 927 | |||
| 928 | if (sourceSize < INDEXOFSUBLIST_THRESHOLD || | ||
| 929 | (source instanceof RandomAccess&&target instanceof RandomAccess)) { | ||
| 930 | nextCand: | ||
| 931 | for (int candidate = 0; candidate <= maxCandidate; candidate++) { | ||
| 932 | for (int i=0, j=candidate; i<targetSize; i++, j++) | ||
| 933 | if (!eq(target.get(i), source.get(j))) | ||
| 934 | continue nextCand; // Element mismatch, try next cand | ||
| 935 | return candidate; // All elements of candidate matched target | ||
| 936 | } | ||
| 937 | } else { // Iterator version of above algorithm | ||
| 938 | ListIterator<?> si = source.listIterator(); | ||
| 939 | nextCand: | ||
| 940 | for (int candidate = 0; candidate <= maxCandidate; candidate++) { | ||
| 941 | ListIterator<?> ti = target.listIterator(); | ||
| 942 | for (int i=0; i<targetSize; i++) { | ||
| 943 | if (!eq(ti.next(), si.next())) { | ||
| 944 | // Back up source iterator to next candidate | ||
| 945 | for (int j=0; j<i; j++) | ||
| 946 | si.previous(); | ||
| 947 | continue nextCand; | ||
| 948 | } | ||
| 949 | } | ||
| 950 | return candidate; | ||
| 951 | } | ||
| 952 | } | ||
| 953 | return -1; // No candidate matched the target | ||
| 954 | } | ||
| 955 | |||
| 956 | /** | ||
| 957 | * Returns the starting position of the last occurrence of the specified | ||
| 958 | * target list within the specified source list, or -1 if there is no such | ||
| 959 | * occurrence. More formally, returns the highest index <tt>i</tt> | ||
| 960 | * such that <tt>source.subList(i, i+target.size()).equals(target)</tt>, | ||
| 961 | * or -1 if there is no such index. (Returns -1 if | ||
| 962 | * <tt>target.size() > source.size()</tt>.) | ||
| 963 | * | ||
| 964 | * <p>This implementation uses the "brute force" technique of iterating | ||
| 965 | * over the source list, looking for a match with the target at each | ||
| 966 | * location in turn. | ||
| 967 | * | ||
| 968 | * @param source the list in which to search for the last occurrence | ||
| 969 | * of <tt>target</tt>. | ||
| 970 | * @param target the list to search for as a subList of <tt>source</tt>. | ||
| 971 | * @return the starting position of the last occurrence of the specified | ||
| 972 | * target list within the specified source list, or -1 if there | ||
| 973 | * is no such occurrence. | ||
| 974 | * @since 1.4 | ||
| 975 | */ | ||
| 976 | public static int lastIndexOfSubList(List<?> source, List<?> target) { | ||
| 977 | int sourceSize = source.size(); | ||
| 978 | int targetSize = target.size(); | ||
| 979 | int maxCandidate = sourceSize - targetSize; | ||
| 980 | |||
| 981 | if (sourceSize < INDEXOFSUBLIST_THRESHOLD || | ||
| 982 | source instanceof RandomAccess) { // Index access version | ||
| 983 | nextCand: | ||
| 984 | for (int candidate = maxCandidate; candidate >= 0; candidate--) { | ||
| 985 | for (int i=0, j=candidate; i<targetSize; i++, j++) | ||
| 986 | if (!eq(target.get(i), source.get(j))) | ||
| 987 | continue nextCand; // Element mismatch, try next cand | ||
| 988 | return candidate; // All elements of candidate matched target | ||
| 989 | } | ||
| 990 | } else { // Iterator version of above algorithm | ||
| 991 | if (maxCandidate < 0) | ||
| 992 | return -1; | ||
| 993 | ListIterator<?> si = source.listIterator(maxCandidate); | ||
| 994 | nextCand: | ||
| 995 | for (int candidate = maxCandidate; candidate >= 0; candidate--) { | ||
| 996 | ListIterator<?> ti = target.listIterator(); | ||
| 997 | for (int i=0; i<targetSize; i++) { | ||
| 998 | if (!eq(ti.next(), si.next())) { | ||
| 999 | if (candidate != 0) { | ||
| 1000 | // Back up source iterator to next candidate | ||
| 1001 | for (int j=0; j<=i+1; j++) | ||
| 1002 | si.previous(); | ||
| 1003 | } | ||
| 1004 | continue nextCand; | ||
| 1005 | } | ||
| 1006 | } | ||
| 1007 | return candidate; | ||
| 1008 | } | ||
| 1009 | } | ||
| 1010 | return -1; // No candidate matched the target | ||
| 1011 | } | ||
| 1012 | |||
| 1013 | |||
| 1014 | // Unmodifiable Wrappers | ||
| 1015 | |||
| 1016 | /** | ||
| 1017 | * Returns an unmodifiable view of the specified collection. This method | ||
| 1018 | * allows modules to provide users with "read-only" access to internal | ||
| 1019 | * collections. Query operations on the returned collection "read through" | ||
| 1020 | * to the specified collection, and attempts to modify the returned | ||
| 1021 | * collection, whether direct or via its iterator, result in an | ||
| 1022 | * <tt>UnsupportedOperationException</tt>.<p> | ||
| 1023 | * | ||
| 1024 | * The returned collection does <i>not</i> pass the hashCode and equals | ||
| 1025 | * operations through to the backing collection, but relies on | ||
| 1026 | * <tt>Object</tt>'s <tt>equals</tt> and <tt>hashCode</tt> methods. This | ||
| 1027 | * is necessary to preserve the contracts of these operations in the case | ||
| 1028 | * that the backing collection is a set or a list.<p> | ||
| 1029 | * | ||
| 1030 | * The returned collection will be serializable if the specified collection | ||
| 1031 | * is serializable. | ||
| 1032 | * | ||
| 1033 | * @param c the collection for which an unmodifiable view is to be | ||
| 1034 | * returned. | ||
| 1035 | * @return an unmodifiable view of the specified collection. | ||
| 1036 | */ | ||
| 1037 | public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c) { | ||
| 1038 | return new UnmodifiableCollection<>(c); | ||
| 1039 | } | ||
| 1040 | |||
| 1041 | /** | ||
| 1042 | * @serial include | ||
| 1043 | */ | ||
| 1044 | static class UnmodifiableCollection<E> implements Collection<E>, Serializable { | ||
| 1045 | private static final long serialVersionUID = 1820017752578914078L; | ||
| 1046 | |||
| 1047 | final Collection<? extends E> c; | ||
| 1048 | |||
| 1049 | UnmodifiableCollection(Collection<? extends E> c) { | ||
| 1050 | if (c==null) | ||
| 1051 | throw new NullPointerException(); | ||
| 1052 | this.c = c; | ||
| 1053 | } | ||
| 1054 | |||
| 1055 | public int size() {return c.size();} | ||
| 1056 | public boolean isEmpty() {return c.isEmpty();} | ||
| 1057 | public boolean contains(Object o) {return c.contains(o);} | ||
| 1058 | public Object[] toArray() {return c.toArray();} | ||
| 1059 | public <T> T[] toArray(T[] a) {return c.toArray(a);} | ||
| 1060 | public String toString() {return c.toString();} | ||
| 1061 | |||
| 1062 | public Iterator<E> iterator() { | ||
| 1063 | return new Iterator<E>() { | ||
| 1064 | private final Iterator<? extends E> i = c.iterator(); | ||
| 1065 | |||
| 1066 | public boolean hasNext() {return i.hasNext();} | ||
| 1067 | public E next() {return i.next();} | ||
| 1068 | public void remove() { | ||
| 1069 | throw new UnsupportedOperationException(); | ||
| 1070 | } | ||
| 1071 | }; | ||
| 1072 | } | ||
| 1073 | |||
| 1074 | public boolean add(E e) { | ||
| 1075 | throw new UnsupportedOperationException(); | ||
| 1076 | } | ||
| 1077 | public boolean remove(Object o) { | ||
| 1078 | throw new UnsupportedOperationException(); | ||
| 1079 | } | ||
| 1080 | |||
| 1081 | public boolean containsAll(Collection<?> coll) { | ||
| 1082 | return c.containsAll(coll); | ||
| 1083 | } | ||
| 1084 | public boolean addAll(Collection<? extends E> coll) { | ||
| 1085 | throw new UnsupportedOperationException(); | ||
| 1086 | } | ||
| 1087 | public boolean removeAll(Collection<?> coll) { | ||
| 1088 | throw new UnsupportedOperationException(); | ||
| 1089 | } | ||
| 1090 | public boolean retainAll(Collection<?> coll) { | ||
| 1091 | throw new UnsupportedOperationException(); | ||
| 1092 | } | ||
| 1093 | public void clear() { | ||
| 1094 | throw new UnsupportedOperationException(); | ||
| 1095 | } | ||
| 1096 | } | ||
| 1097 | |||
| 1098 | /** | ||
| 1099 | * Returns an unmodifiable view of the specified set. This method allows | ||
| 1100 | * modules to provide users with "read-only" access to internal sets. | ||
| 1101 | * Query operations on the returned set "read through" to the specified | ||
| 1102 | * set, and attempts to modify the returned set, whether direct or via its | ||
| 1103 | * iterator, result in an <tt>UnsupportedOperationException</tt>.<p> | ||
| 1104 | * | ||
| 1105 | * The returned set will be serializable if the specified set | ||
| 1106 | * is serializable. | ||
| 1107 | * | ||
| 1108 | * @param s the set for which an unmodifiable view is to be returned. | ||
| 1109 | * @return an unmodifiable view of the specified set. | ||
| 1110 | */ | ||
| 1111 | public static <T> Set<T> unmodifiableSet(Set<? extends T> s) { | ||
| 1112 | return new UnmodifiableSet<>(s); | ||
| 1113 | } | ||
| 1114 | |||
| 1115 | /** | ||
| 1116 | * @serial include | ||
| 1117 | */ | ||
| 1118 | static class UnmodifiableSet<E> extends UnmodifiableCollection<E> | ||
| 1119 | implements Set<E>, Serializable { | ||
| 1120 | private static final long serialVersionUID = -9215047833775013803L; | ||
| 1121 | |||
| 1122 | UnmodifiableSet(Set<? extends E> s) {super(s);} | ||
| 1123 | public boolean equals(Object o) {return o == this || c.equals(o);} | ||
| 1124 | public int hashCode() {return c.hashCode();} | ||
| 1125 | } | ||
| 1126 | |||
| 1127 | /** | ||
| 1128 | * Returns an unmodifiable view of the specified sorted set. This method | ||
| 1129 | * allows modules to provide users with "read-only" access to internal | ||
| 1130 | * sorted sets. Query operations on the returned sorted set "read | ||
| 1131 | * through" to the specified sorted set. Attempts to modify the returned | ||
| 1132 | * sorted set, whether direct, via its iterator, or via its | ||
| 1133 | * <tt>subSet</tt>, <tt>headSet</tt>, or <tt>tailSet</tt> views, result in | ||
| 1134 | * an <tt>UnsupportedOperationException</tt>.<p> | ||
| 1135 | * | ||
| 1136 | * The returned sorted set will be serializable if the specified sorted set | ||
| 1137 | * is serializable. | ||
| 1138 | * | ||
| 1139 | * @param s the sorted set for which an unmodifiable view is to be | ||
| 1140 | * returned. | ||
| 1141 | * @return an unmodifiable view of the specified sorted set. | ||
| 1142 | */ | ||
| 1143 | public static <T> SortedSet<T> unmodifiableSortedSet(SortedSet<T> s) { | ||
| 1144 | return new UnmodifiableSortedSet<>(s); | ||
| 1145 | } | ||
| 1146 | |||
| 1147 | /** | ||
| 1148 | * @serial include | ||
| 1149 | */ | ||
| 1150 | static class UnmodifiableSortedSet<E> | ||
| 1151 | extends UnmodifiableSet<E> | ||
| 1152 | implements SortedSet<E>, Serializable { | ||
| 1153 | private static final long serialVersionUID = -4929149591599911165L; | ||
| 1154 | private final SortedSet<E> ss; | ||
| 1155 | |||
| 1156 | UnmodifiableSortedSet(SortedSet<E> s) {super(s); ss = s;} | ||
| 1157 | |||
| 1158 | public Comparator<? super E> comparator() {return ss.comparator();} | ||
| 1159 | |||
| 1160 | public SortedSet<E> subSet(E fromElement, E toElement) { | ||
| 1161 | return new UnmodifiableSortedSet<>(ss.subSet(fromElement,toElement)); | ||
| 1162 | } | ||
| 1163 | public SortedSet<E> headSet(E toElement) { | ||
| 1164 | return new UnmodifiableSortedSet<>(ss.headSet(toElement)); | ||
| 1165 | } | ||
| 1166 | public SortedSet<E> tailSet(E fromElement) { | ||
| 1167 | return new UnmodifiableSortedSet<>(ss.tailSet(fromElement)); | ||
| 1168 | } | ||
| 1169 | |||
| 1170 | public E first() {return ss.first();} | ||
| 1171 | public E last() {return ss.last();} | ||
| 1172 | } | ||
| 1173 | |||
| 1174 | /** | ||
| 1175 | * Returns an unmodifiable view of the specified list. This method allows | ||
| 1176 | * modules to provide users with "read-only" access to internal | ||
| 1177 | * lists. Query operations on the returned list "read through" to the | ||
| 1178 | * specified list, and attempts to modify the returned list, whether | ||
| 1179 | * direct or via its iterator, result in an | ||
| 1180 | * <tt>UnsupportedOperationException</tt>.<p> | ||
| 1181 | * | ||
| 1182 | * The returned list will be serializable if the specified list | ||
| 1183 | * is serializable. Similarly, the returned list will implement | ||
| 1184 | * {@link RandomAccess} if the specified list does. | ||
| 1185 | * | ||
| 1186 | * @param list the list for which an unmodifiable view is to be returned. | ||
| 1187 | * @return an unmodifiable view of the specified list. | ||
| 1188 | */ | ||
| 1189 | public static <T> List<T> unmodifiableList(List<? extends T> list) { | ||
| 1190 | return (list instanceof RandomAccess ? | ||
| 1191 | new UnmodifiableRandomAccessList<>(list) : | ||
| 1192 | new UnmodifiableList<>(list)); | ||
| 1193 | } | ||
| 1194 | |||
| 1195 | /** | ||
| 1196 | * @serial include | ||
| 1197 | */ | ||
| 1198 | static class UnmodifiableList<E> extends UnmodifiableCollection<E> | ||
| 1199 | implements List<E> { | ||
| 1200 | private static final long serialVersionUID = -283967356065247728L; | ||
| 1201 | final List<? extends E> list; | ||
| 1202 | |||
| 1203 | UnmodifiableList(List<? extends E> list) { | ||
| 1204 | super(list); | ||
| 1205 | this.list = list; | ||
| 1206 | } | ||
| 1207 | |||
| 1208 | public boolean equals(Object o) {return o == this || list.equals(o);} | ||
| 1209 | public int hashCode() {return list.hashCode();} | ||
| 1210 | |||
| 1211 | public E get(int index) {return list.get(index);} | ||
| 1212 | public E set(int index, E element) { | ||
| 1213 | throw new UnsupportedOperationException(); | ||
| 1214 | } | ||
| 1215 | public void add(int index, E element) { | ||
| 1216 | throw new UnsupportedOperationException(); | ||
| 1217 | } | ||
| 1218 | public E remove(int index) { | ||
| 1219 | throw new UnsupportedOperationException(); | ||
| 1220 | } | ||
| 1221 | public int indexOf(Object o) {return list.indexOf(o);} | ||
| 1222 | public int lastIndexOf(Object o) {return list.lastIndexOf(o);} | ||
| 1223 | public boolean addAll(int index, Collection<? extends E> c) { | ||
| 1224 | throw new UnsupportedOperationException(); | ||
| 1225 | } | ||
| 1226 | public ListIterator<E> listIterator() {return listIterator(0);} | ||
| 1227 | |||
| 1228 | public ListIterator<E> listIterator(final int index) { | ||
| 1229 | return new ListIterator<E>() { | ||
| 1230 | private final ListIterator<? extends E> i | ||
| 1231 | = list.listIterator(index); | ||
| 1232 | |||
| 1233 | public boolean hasNext() {return i.hasNext();} | ||
| 1234 | public E next() {return i.next();} | ||
| 1235 | public boolean hasPrevious() {return i.hasPrevious();} | ||
| 1236 | public E previous() {return i.previous();} | ||
| 1237 | public int nextIndex() {return i.nextIndex();} | ||
| 1238 | public int previousIndex() {return i.previousIndex();} | ||
| 1239 | |||
| 1240 | public void remove() { | ||
| 1241 | throw new UnsupportedOperationException(); | ||
| 1242 | } | ||
| 1243 | public void set(E e) { | ||
| 1244 | throw new UnsupportedOperationException(); | ||
| 1245 | } | ||
| 1246 | public void add(E e) { | ||
| 1247 | throw new UnsupportedOperationException(); | ||
| 1248 | } | ||
| 1249 | }; | ||
| 1250 | } | ||
| 1251 | |||
| 1252 | public List<E> subList(int fromIndex, int toIndex) { | ||
| 1253 | return new UnmodifiableList<>(list.subList(fromIndex, toIndex)); | ||
| 1254 | } | ||
| 1255 | |||
| 1256 | /** | ||
| 1257 | * UnmodifiableRandomAccessList instances are serialized as | ||
| 1258 | * UnmodifiableList instances to allow them to be deserialized | ||
| 1259 | * in pre-1.4 JREs (which do not have UnmodifiableRandomAccessList). | ||
| 1260 | * This method inverts the transformation. As a beneficial | ||
| 1261 | * side-effect, it also grafts the RandomAccess marker onto | ||
| 1262 | * UnmodifiableList instances that were serialized in pre-1.4 JREs. | ||
| 1263 | * | ||
| 1264 | * Note: Unfortunately, UnmodifiableRandomAccessList instances | ||
| 1265 | * serialized in 1.4.1 and deserialized in 1.4 will become | ||
| 1266 | * UnmodifiableList instances, as this method was missing in 1.4. | ||
| 1267 | */ | ||
| 1268 | private Object readResolve() { | ||
| 1269 | return (list instanceof RandomAccess | ||
| 1270 | ? new UnmodifiableRandomAccessList<>(list) | ||
| 1271 | : this); | ||
| 1272 | } | ||
| 1273 | } | ||
| 1274 | |||
| 1275 | /** | ||
| 1276 | * @serial include | ||
| 1277 | */ | ||
| 1278 | static class UnmodifiableRandomAccessList<E> extends UnmodifiableList<E> | ||
| 1279 | implements RandomAccess | ||
| 1280 | { | ||
| 1281 | UnmodifiableRandomAccessList(List<? extends E> list) { | ||
| 1282 | super(list); | ||
| 1283 | } | ||
| 1284 | |||
| 1285 | public List<E> subList(int fromIndex, int toIndex) { | ||
| 1286 | return new UnmodifiableRandomAccessList<>( | ||
| 1287 | list.subList(fromIndex, toIndex)); | ||
| 1288 | } | ||
| 1289 | |||
| 1290 | private static final long serialVersionUID = -2542308836966382001L; | ||
| 1291 | |||
| 1292 | /** | ||
| 1293 | * Allows instances to be deserialized in pre-1.4 JREs (which do | ||
| 1294 | * not have UnmodifiableRandomAccessList). UnmodifiableList has | ||
| 1295 | * a readResolve method that inverts this transformation upon | ||
| 1296 | * deserialization. | ||
| 1297 | */ | ||
| 1298 | private Object writeReplace() { | ||
| 1299 | return new UnmodifiableList<>(list); | ||
| 1300 | } | ||
| 1301 | } | ||
| 1302 | |||
| 1303 | /** | ||
| 1304 | * Returns an unmodifiable view of the specified map. This method | ||
| 1305 | * allows modules to provide users with "read-only" access to internal | ||
| 1306 | * maps. Query operations on the returned map "read through" | ||
| 1307 | * to the specified map, and attempts to modify the returned | ||
| 1308 | * map, whether direct or via its collection views, result in an | ||
| 1309 | * <tt>UnsupportedOperationException</tt>.<p> | ||
| 1310 | * | ||
| 1311 | * The returned map will be serializable if the specified map | ||
| 1312 | * is serializable. | ||
| 1313 | * | ||
| 1314 | * @param m the map for which an unmodifiable view is to be returned. | ||
| 1315 | * @return an unmodifiable view of the specified map. | ||
| 1316 | */ | ||
| 1317 | public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K, ? extends V> m) { | ||
| 1318 | return new UnmodifiableMap<>(m); | ||
| 1319 | } | ||
| 1320 | |||
| 1321 | /** | ||
| 1322 | * @serial include | ||
| 1323 | */ | ||
| 1324 | private static class UnmodifiableMap<K,V> implements Map<K,V>, Serializable { | ||
| 1325 | private static final long serialVersionUID = -1034234728574286014L; | ||
| 1326 | |||
| 1327 | private final Map<? extends K, ? extends V> m; | ||
| 1328 | |||
| 1329 | UnmodifiableMap(Map<? extends K, ? extends V> m) { | ||
| 1330 | if (m==null) | ||
| 1331 | throw new NullPointerException(); | ||
| 1332 | this.m = m; | ||
| 1333 | } | ||
| 1334 | |||
| 1335 | public int size() {return m.size();} | ||
| 1336 | public boolean isEmpty() {return m.isEmpty();} | ||
| 1337 | public boolean containsKey(Object key) {return m.containsKey(key);} | ||
| 1338 | public boolean containsValue(Object val) {return m.containsValue(val);} | ||
| 1339 | public V get(Object key) {return m.get(key);} | ||
| 1340 | |||
| 1341 | public V put(K key, V value) { | ||
| 1342 | throw new UnsupportedOperationException(); | ||
| 1343 | } | ||
| 1344 | public V remove(Object key) { | ||
| 1345 | throw new UnsupportedOperationException(); | ||
| 1346 | } | ||
| 1347 | public void putAll(Map<? extends K, ? extends V> m) { | ||
| 1348 | throw new UnsupportedOperationException(); | ||
| 1349 | } | ||
| 1350 | public void clear() { | ||
| 1351 | throw new UnsupportedOperationException(); | ||
| 1352 | } | ||
| 1353 | |||
| 1354 | private transient Set<K> keySet = null; | ||
| 1355 | private transient Set<Map.Entry<K,V>> entrySet = null; | ||
| 1356 | private transient Collection<V> values = null; | ||
| 1357 | |||
| 1358 | public Set<K> keySet() { | ||
| 1359 | if (keySet==null) | ||
| 1360 | keySet = unmodifiableSet(m.keySet()); | ||
| 1361 | return keySet; | ||
| 1362 | } | ||
| 1363 | |||
| 1364 | public Set<Map.Entry<K,V>> entrySet() { | ||
| 1365 | if (entrySet==null) | ||
| 1366 | entrySet = new UnmodifiableEntrySet<>(m.entrySet()); | ||
| 1367 | return entrySet; | ||
| 1368 | } | ||
| 1369 | |||
| 1370 | public Collection<V> values() { | ||
| 1371 | if (values==null) | ||
| 1372 | values = unmodifiableCollection(m.values()); | ||
| 1373 | return values; | ||
| 1374 | } | ||
| 1375 | |||
| 1376 | public boolean equals(Object o) {return o == this || m.equals(o);} | ||
| 1377 | public int hashCode() {return m.hashCode();} | ||
| 1378 | public String toString() {return m.toString();} | ||
| 1379 | |||
| 1380 | /** | ||
| 1381 | * We need this class in addition to UnmodifiableSet as | ||
| 1382 | * Map.Entries themselves permit modification of the backing Map | ||
| 1383 | * via their setValue operation. This class is subtle: there are | ||
| 1384 | * many possible attacks that must be thwarted. | ||
| 1385 | * | ||
| 1386 | * @serial include | ||
| 1387 | */ | ||
| 1388 | static class UnmodifiableEntrySet<K,V> | ||
| 1389 | extends UnmodifiableSet<Map.Entry<K,V>> { | ||
| 1390 | private static final long serialVersionUID = 7854390611657943733L; | ||
| 1391 | |||
| 1392 | UnmodifiableEntrySet(Set<? extends Map.Entry<? extends K, ? extends V>> s) { | ||
| 1393 | super((Set)s); | ||
| 1394 | } | ||
| 1395 | public Iterator<Map.Entry<K,V>> iterator() { | ||
| 1396 | return new Iterator<Map.Entry<K,V>>() { | ||
| 1397 | private final Iterator<? extends Map.Entry<? extends K, ? extends V>> i = c.iterator(); | ||
| 1398 | |||
| 1399 | public boolean hasNext() { | ||
| 1400 | return i.hasNext(); | ||
| 1401 | } | ||
| 1402 | public Map.Entry<K,V> next() { | ||
| 1403 | return new UnmodifiableEntry<>(i.next()); | ||
| 1404 | } | ||
| 1405 | public void remove() { | ||
| 1406 | throw new UnsupportedOperationException(); | ||
| 1407 | } | ||
| 1408 | }; | ||
| 1409 | } | ||
| 1410 | |||
| 1411 | public Object[] toArray() { | ||
| 1412 | Object[] a = c.toArray(); | ||
| 1413 | for (int i=0; i<a.length; i++) | ||
| 1414 | a[i] = new UnmodifiableEntry<>((Map.Entry<K,V>)a[i]); | ||
| 1415 | return a; | ||
| 1416 | } | ||
| 1417 | |||
| 1418 | public <T> T[] toArray(T[] a) { | ||
| 1419 | // We don't pass a to c.toArray, to avoid window of | ||
| 1420 | // vulnerability wherein an unscrupulous multithreaded client | ||
| 1421 | // could get his hands on raw (unwrapped) Entries from c. | ||
| 1422 | Object[] arr = c.toArray(a.length==0 ? a : Arrays.copyOf(a, 0)); | ||
| 1423 | |||
| 1424 | for (int i=0; i<arr.length; i++) | ||
| 1425 | arr[i] = new UnmodifiableEntry<>((Map.Entry<K,V>)arr[i]); | ||
| 1426 | |||
| 1427 | if (arr.length > a.length) | ||
| 1428 | return (T[])arr; | ||
| 1429 | |||
| 1430 | System.arraycopy(arr, 0, a, 0, arr.length); | ||
| 1431 | if (a.length > arr.length) | ||
| 1432 | a[arr.length] = null; | ||
| 1433 | return a; | ||
| 1434 | } | ||
| 1435 | |||
| 1436 | /** | ||
| 1437 | * This method is overridden to protect the backing set against | ||
| 1438 | * an object with a nefarious equals function that senses | ||
| 1439 | * that the equality-candidate is Map.Entry and calls its | ||
| 1440 | * setValue method. | ||
| 1441 | */ | ||
| 1442 | public boolean contains(Object o) { | ||
| 1443 | if (!(o instanceof Map.Entry)) | ||
| 1444 | return false; | ||
| 1445 | return c.contains( | ||
| 1446 | new UnmodifiableEntry<>((Map.Entry<?,?>) o)); | ||
| 1447 | } | ||
| 1448 | |||
| 1449 | /** | ||
| 1450 | * The next two methods are overridden to protect against | ||
| 1451 | * an unscrupulous List whose contains(Object o) method senses | ||
| 1452 | * when o is a Map.Entry, and calls o.setValue. | ||
| 1453 | */ | ||
| 1454 | public boolean containsAll(Collection<?> coll) { | ||
| 1455 | for (Object e : coll) { | ||
| 1456 | if (!contains(e)) // Invokes safe contains() above | ||
| 1457 | return false; | ||
| 1458 | } | ||
| 1459 | return true; | ||
| 1460 | } | ||
| 1461 | public boolean equals(Object o) { | ||
| 1462 | if (o == this) | ||
| 1463 | return true; | ||
| 1464 | |||
| 1465 | if (!(o instanceof Set)) | ||
| 1466 | return false; | ||
| 1467 | Set s = (Set) o; | ||
| 1468 | if (s.size() != c.size()) | ||
| 1469 | return false; | ||
| 1470 | return containsAll(s); // Invokes safe containsAll() above | ||
| 1471 | } | ||
| 1472 | |||
| 1473 | /** | ||
| 1474 | * This "wrapper class" serves two purposes: it prevents | ||
| 1475 | * the client from modifying the backing Map, by short-circuiting | ||
| 1476 | * the setValue method, and it protects the backing Map against | ||
| 1477 | * an ill-behaved Map.Entry that attempts to modify another | ||
| 1478 | * Map Entry when asked to perform an equality check. | ||
| 1479 | */ | ||
| 1480 | private static class UnmodifiableEntry<K,V> implements Map.Entry<K,V> { | ||
| 1481 | private Map.Entry<? extends K, ? extends V> e; | ||
| 1482 | |||
| 1483 | UnmodifiableEntry(Map.Entry<? extends K, ? extends V> e) {this.e = e;} | ||
| 1484 | |||
| 1485 | public K getKey() {return e.getKey();} | ||
| 1486 | public V getValue() {return e.getValue();} | ||
| 1487 | public V setValue(V value) { | ||
| 1488 | throw new UnsupportedOperationException(); | ||
| 1489 | } | ||
| 1490 | public int hashCode() {return e.hashCode();} | ||
| 1491 | public boolean equals(Object o) { | ||
| 1492 | if (!(o instanceof Map.Entry)) | ||
| 1493 | return false; | ||
| 1494 | Map.Entry t = (Map.Entry)o; | ||
| 1495 | return eq(e.getKey(), t.getKey()) && | ||
| 1496 | eq(e.getValue(), t.getValue()); | ||
| 1497 | } | ||
| 1498 | public String toString() {return e.toString();} | ||
| 1499 | } | ||
| 1500 | } | ||
| 1501 | } | ||
| 1502 | |||
| 1503 | /** | ||
| 1504 | * Returns an unmodifiable view of the specified sorted map. This method | ||
| 1505 | * allows modules to provide users with "read-only" access to internal | ||
| 1506 | * sorted maps. Query operations on the returned sorted map "read through" | ||
| 1507 | * to the specified sorted map. Attempts to modify the returned | ||
| 1508 | * sorted map, whether direct, via its collection views, or via its | ||
| 1509 | * <tt>subMap</tt>, <tt>headMap</tt>, or <tt>tailMap</tt> views, result in | ||
| 1510 | * an <tt>UnsupportedOperationException</tt>.<p> | ||
| 1511 | * | ||
| 1512 | * The returned sorted map will be serializable if the specified sorted map | ||
| 1513 | * is serializable. | ||
| 1514 | * | ||
| 1515 | * @param m the sorted map for which an unmodifiable view is to be | ||
| 1516 | * returned. | ||
| 1517 | * @return an unmodifiable view of the specified sorted map. | ||
| 1518 | */ | ||
| 1519 | public static <K,V> SortedMap<K,V> unmodifiableSortedMap(SortedMap<K, ? extends V> m) { | ||
| 1520 | return new UnmodifiableSortedMap<>(m); | ||
| 1521 | } | ||
| 1522 | |||
| 1523 | /** | ||
| 1524 | * @serial include | ||
| 1525 | */ | ||
| 1526 | static class UnmodifiableSortedMap<K,V> | ||
| 1527 | extends UnmodifiableMap<K,V> | ||
| 1528 | implements SortedMap<K,V>, Serializable { | ||
| 1529 | private static final long serialVersionUID = -8806743815996713206L; | ||
| 1530 | |||
| 1531 | private final SortedMap<K, ? extends V> sm; | ||
| 1532 | |||
| 1533 | UnmodifiableSortedMap(SortedMap<K, ? extends V> m) {super(m); sm = m;} | ||
| 1534 | |||
| 1535 | public Comparator<? super K> comparator() {return sm.comparator();} | ||
| 1536 | |||
| 1537 | public SortedMap<K,V> subMap(K fromKey, K toKey) { | ||
| 1538 | return new UnmodifiableSortedMap<>(sm.subMap(fromKey, toKey)); | ||
| 1539 | } | ||
| 1540 | public SortedMap<K,V> headMap(K toKey) { | ||
| 1541 | return new UnmodifiableSortedMap<>(sm.headMap(toKey)); | ||
| 1542 | } | ||
| 1543 | public SortedMap<K,V> tailMap(K fromKey) { | ||
| 1544 | return new UnmodifiableSortedMap<>(sm.tailMap(fromKey)); | ||
| 1545 | } | ||
| 1546 | |||
| 1547 | public K firstKey() {return sm.firstKey();} | ||
| 1548 | public K lastKey() {return sm.lastKey();} | ||
| 1549 | } | ||
| 1550 | |||
| 1551 | |||
| 1552 | // Synch Wrappers | ||
| 1553 | |||
| 1554 | /** | ||
| 1555 | * Returns a synchronized (thread-safe) collection backed by the specified | ||
| 1556 | * collection. In order to guarantee serial access, it is critical that | ||
| 1557 | * <strong>all</strong> access to the backing collection is accomplished | ||
| 1558 | * through the returned collection.<p> | ||
| 1559 | * | ||
| 1560 | * It is imperative that the user manually synchronize on the returned | ||
| 1561 | * collection when iterating over it: | ||
| 1562 | * <pre> | ||
| 1563 | * Collection c = Collections.synchronizedCollection(myCollection); | ||
| 1564 | * ... | ||
| 1565 | * synchronized (c) { | ||
| 1566 | * Iterator i = c.iterator(); // Must be in the synchronized block | ||
| 1567 | * while (i.hasNext()) | ||
| 1568 | * foo(i.next()); | ||
| 1569 | * } | ||
| 1570 | * </pre> | ||
| 1571 | * Failure to follow this advice may result in non-deterministic behavior. | ||
| 1572 | * | ||
| 1573 | * <p>The returned collection does <i>not</i> pass the <tt>hashCode</tt> | ||
| 1574 | * and <tt>equals</tt> operations through to the backing collection, but | ||
| 1575 | * relies on <tt>Object</tt>'s equals and hashCode methods. This is | ||
| 1576 | * necessary to preserve the contracts of these operations in the case | ||
| 1577 | * that the backing collection is a set or a list.<p> | ||
| 1578 | * | ||
| 1579 | * The returned collection will be serializable if the specified collection | ||
| 1580 | * is serializable. | ||
| 1581 | * | ||
| 1582 | * @param c the collection to be "wrapped" in a synchronized collection. | ||
| 1583 | * @return a synchronized view of the specified collection. | ||
| 1584 | */ | ||
| 1585 | public static <T> Collection<T> synchronizedCollection(Collection<T> c) { | ||
| 1586 | return new SynchronizedCollection<>(c); | ||
| 1587 | } | ||
| 1588 | |||
| 1589 | static <T> Collection<T> synchronizedCollection(Collection<T> c, Object mutex) { | ||
| 1590 | return new SynchronizedCollection<>(c, mutex); | ||
| 1591 | } | ||
| 1592 | |||
| 1593 | /** | ||
| 1594 | * @serial include | ||
| 1595 | */ | ||
| 1596 | static class SynchronizedCollection<E> implements Collection<E>, Serializable { | ||
| 1597 | private static final long serialVersionUID = 3053995032091335093L; | ||
| 1598 | |||
| 1599 | final Collection<E> c; // Backing Collection | ||
| 1600 | final Object mutex; // Object on which to synchronize | ||
| 1601 | |||
| 1602 | SynchronizedCollection(Collection<E> c) { | ||
| 1603 | if (c==null) | ||
| 1604 | throw new NullPointerException(); | ||
| 1605 | this.c = c; | ||
| 1606 | mutex = this; | ||
| 1607 | } | ||
| 1608 | SynchronizedCollection(Collection<E> c, Object mutex) { | ||
| 1609 | this.c = c; | ||
| 1610 | this.mutex = mutex; | ||
| 1611 | } | ||
| 1612 | |||
| 1613 | public int size() { | ||
| 1614 | synchronized (mutex) {return c.size();} | ||
| 1615 | } | ||
| 1616 | public boolean isEmpty() { | ||
| 1617 | synchronized (mutex) {return c.isEmpty();} | ||
| 1618 | } | ||
| 1619 | public boolean contains(Object o) { | ||
| 1620 | synchronized (mutex) {return c.contains(o);} | ||
| 1621 | } | ||
| 1622 | public Object[] toArray() { | ||
| 1623 | synchronized (mutex) {return c.toArray();} | ||
| 1624 | } | ||
| 1625 | public <T> T[] toArray(T[] a) { | ||
| 1626 | synchronized (mutex) {return c.toArray(a);} | ||
| 1627 | } | ||
| 1628 | |||
| 1629 | public Iterator<E> iterator() { | ||
| 1630 | return c.iterator(); // Must be manually synched by user! | ||
| 1631 | } | ||
| 1632 | |||
| 1633 | public boolean add(E e) { | ||
| 1634 | synchronized (mutex) {return c.add(e);} | ||
| 1635 | } | ||
| 1636 | public boolean remove(Object o) { | ||
| 1637 | synchronized (mutex) {return c.remove(o);} | ||
| 1638 | } | ||
| 1639 | |||
| 1640 | public boolean containsAll(Collection<?> coll) { | ||
| 1641 | synchronized (mutex) {return c.containsAll(coll);} | ||
| 1642 | } | ||
| 1643 | public boolean addAll(Collection<? extends E> coll) { | ||
| 1644 | synchronized (mutex) {return c.addAll(coll);} | ||
| 1645 | } | ||
| 1646 | public boolean removeAll(Collection<?> coll) { | ||
| 1647 | synchronized (mutex) {return c.removeAll(coll);} | ||
| 1648 | } | ||
| 1649 | public boolean retainAll(Collection<?> coll) { | ||
| 1650 | synchronized (mutex) {return c.retainAll(coll);} | ||
| 1651 | } | ||
| 1652 | public void clear() { | ||
| 1653 | synchronized (mutex) {c.clear();} | ||
| 1654 | } | ||
| 1655 | public String toString() { | ||
| 1656 | synchronized (mutex) {return c.toString();} | ||
| 1657 | } | ||
| 1658 | private void writeObject(ObjectOutputStream s) throws IOException { | ||
| 1659 | synchronized (mutex) {s.defaultWriteObject();} | ||
| 1660 | } | ||
| 1661 | } | ||
| 1662 | |||
| 1663 | /** | ||
| 1664 | * Returns a synchronized (thread-safe) set backed by the specified | ||
| 1665 | * set. In order to guarantee serial access, it is critical that | ||
| 1666 | * <strong>all</strong> access to the backing set is accomplished | ||
| 1667 | * through the returned set.<p> | ||
| 1668 | * | ||
| 1669 | * It is imperative that the user manually synchronize on the returned | ||
| 1670 | * set when iterating over it: | ||
| 1671 | * <pre> | ||
| 1672 | * Set s = Collections.synchronizedSet(new HashSet()); | ||
| 1673 | * ... | ||
| 1674 | * synchronized (s) { | ||
| 1675 | * Iterator i = s.iterator(); // Must be in the synchronized block | ||
| 1676 | * while (i.hasNext()) | ||
| 1677 | * foo(i.next()); | ||
| 1678 | * } | ||
| 1679 | * </pre> | ||
| 1680 | * Failure to follow this advice may result in non-deterministic behavior. | ||
| 1681 | * | ||
| 1682 | * <p>The returned set will be serializable if the specified set is | ||
| 1683 | * serializable. | ||
| 1684 | * | ||
| 1685 | * @param s the set to be "wrapped" in a synchronized set. | ||
| 1686 | * @return a synchronized view of the specified set. | ||
| 1687 | */ | ||
| 1688 | public static <T> Set<T> synchronizedSet(Set<T> s) { | ||
| 1689 | return new SynchronizedSet<>(s); | ||
| 1690 | } | ||
| 1691 | |||
| 1692 | static <T> Set<T> synchronizedSet(Set<T> s, Object mutex) { | ||
| 1693 | return new SynchronizedSet<>(s, mutex); | ||
| 1694 | } | ||
| 1695 | |||
| 1696 | /** | ||
| 1697 | * @serial include | ||
| 1698 | */ | ||
| 1699 | static class SynchronizedSet<E> | ||
| 1700 | extends SynchronizedCollection<E> | ||
| 1701 | implements Set<E> { | ||
| 1702 | private static final long serialVersionUID = 487447009682186044L; | ||
| 1703 | |||
| 1704 | SynchronizedSet(Set<E> s) { | ||
| 1705 | super(s); | ||
| 1706 | } | ||
| 1707 | SynchronizedSet(Set<E> s, Object mutex) { | ||
| 1708 | super(s, mutex); | ||
| 1709 | } | ||
| 1710 | |||
| 1711 | public boolean equals(Object o) { | ||
| 1712 | synchronized (mutex) {return c.equals(o);} | ||
| 1713 | } | ||
| 1714 | public int hashCode() { | ||
| 1715 | synchronized (mutex) {return c.hashCode();} | ||
| 1716 | } | ||
| 1717 | } | ||
| 1718 | |||
| 1719 | /** | ||
| 1720 | * Returns a synchronized (thread-safe) sorted set backed by the specified | ||
| 1721 | * sorted set. In order to guarantee serial access, it is critical that | ||
| 1722 | * <strong>all</strong> access to the backing sorted set is accomplished | ||
| 1723 | * through the returned sorted set (or its views).<p> | ||
| 1724 | * | ||
| 1725 | * It is imperative that the user manually synchronize on the returned | ||
| 1726 | * sorted set when iterating over it or any of its <tt>subSet</tt>, | ||
| 1727 | * <tt>headSet</tt>, or <tt>tailSet</tt> views. | ||
| 1728 | * <pre> | ||
| 1729 | * SortedSet s = Collections.synchronizedSortedSet(new TreeSet()); | ||
| 1730 | * ... | ||
| 1731 | * synchronized (s) { | ||
| 1732 | * Iterator i = s.iterator(); // Must be in the synchronized block | ||
| 1733 | * while (i.hasNext()) | ||
| 1734 | * foo(i.next()); | ||
| 1735 | * } | ||
| 1736 | * </pre> | ||
| 1737 | * or: | ||
| 1738 | * <pre> | ||
| 1739 | * SortedSet s = Collections.synchronizedSortedSet(new TreeSet()); | ||
| 1740 | * SortedSet s2 = s.headSet(foo); | ||
| 1741 | * ... | ||
| 1742 | * synchronized (s) { // Note: s, not s2!!! | ||
| 1743 | * Iterator i = s2.iterator(); // Must be in the synchronized block | ||
| 1744 | * while (i.hasNext()) | ||
| 1745 | * foo(i.next()); | ||
| 1746 | * } | ||
| 1747 | * </pre> | ||
| 1748 | * Failure to follow this advice may result in non-deterministic behavior. | ||
| 1749 | * | ||
| 1750 | * <p>The returned sorted set will be serializable if the specified | ||
| 1751 | * sorted set is serializable. | ||
| 1752 | * | ||
| 1753 | * @param s the sorted set to be "wrapped" in a synchronized sorted set. | ||
| 1754 | * @return a synchronized view of the specified sorted set. | ||
| 1755 | */ | ||
| 1756 | public static <T> SortedSet<T> synchronizedSortedSet(SortedSet<T> s) { | ||
| 1757 | return new SynchronizedSortedSet<>(s); | ||
| 1758 | } | ||
| 1759 | |||
| 1760 | /** | ||
| 1761 | * @serial include | ||
| 1762 | */ | ||
| 1763 | static class SynchronizedSortedSet<E> | ||
| 1764 | extends SynchronizedSet<E> | ||
| 1765 | implements SortedSet<E> | ||
| 1766 | { | ||
| 1767 | private static final long serialVersionUID = 8695801310862127406L; | ||
| 1768 | |||
| 1769 | private final SortedSet<E> ss; | ||
| 1770 | |||
| 1771 | SynchronizedSortedSet(SortedSet<E> s) { | ||
| 1772 | super(s); | ||
| 1773 | ss = s; | ||
| 1774 | } | ||
| 1775 | SynchronizedSortedSet(SortedSet<E> s, Object mutex) { | ||
| 1776 | super(s, mutex); | ||
| 1777 | ss = s; | ||
| 1778 | } | ||
| 1779 | |||
| 1780 | public Comparator<? super E> comparator() { | ||
| 1781 | synchronized (mutex) {return ss.comparator();} | ||
| 1782 | } | ||
| 1783 | |||
| 1784 | public SortedSet<E> subSet(E fromElement, E toElement) { | ||
| 1785 | synchronized (mutex) { | ||
| 1786 | return new SynchronizedSortedSet<>( | ||
| 1787 | ss.subSet(fromElement, toElement), mutex); | ||
| 1788 | } | ||
| 1789 | } | ||
| 1790 | public SortedSet<E> headSet(E toElement) { | ||
| 1791 | synchronized (mutex) { | ||
| 1792 | return new SynchronizedSortedSet<>(ss.headSet(toElement), mutex); | ||
| 1793 | } | ||
| 1794 | } | ||
| 1795 | public SortedSet<E> tailSet(E fromElement) { | ||
| 1796 | synchronized (mutex) { | ||
| 1797 | return new SynchronizedSortedSet<>(ss.tailSet(fromElement),mutex); | ||
| 1798 | } | ||
| 1799 | } | ||
| 1800 | |||
| 1801 | public E first() { | ||
| 1802 | synchronized (mutex) {return ss.first();} | ||
| 1803 | } | ||
| 1804 | public E last() { | ||
| 1805 | synchronized (mutex) {return ss.last();} | ||
| 1806 | } | ||
| 1807 | } | ||
| 1808 | |||
| 1809 | /** | ||
| 1810 | * Returns a synchronized (thread-safe) list backed by the specified | ||
| 1811 | * list. In order to guarantee serial access, it is critical that | ||
| 1812 | * <strong>all</strong> access to the backing list is accomplished | ||
| 1813 | * through the returned list.<p> | ||
| 1814 | * | ||
| 1815 | * It is imperative that the user manually synchronize on the returned | ||
| 1816 | * list when iterating over it: | ||
| 1817 | * <pre> | ||
| 1818 | * List list = Collections.synchronizedList(new ArrayList()); | ||
| 1819 | * ... | ||
| 1820 | * synchronized (list) { | ||
| 1821 | * Iterator i = list.iterator(); // Must be in synchronized block | ||
| 1822 | * while (i.hasNext()) | ||
| 1823 | * foo(i.next()); | ||
| 1824 | * } | ||
| 1825 | * </pre> | ||
| 1826 | * Failure to follow this advice may result in non-deterministic behavior. | ||
| 1827 | * | ||
| 1828 | * <p>The returned list will be serializable if the specified list is | ||
| 1829 | * serializable. | ||
| 1830 | * | ||
| 1831 | * @param list the list to be "wrapped" in a synchronized list. | ||
| 1832 | * @return a synchronized view of the specified list. | ||
| 1833 | */ | ||
| 1834 | public static <T> List<T> synchronizedList(List<T> list) { | ||
| 1835 | return (list instanceof RandomAccess ? | ||
| 1836 | new SynchronizedRandomAccessList<>(list) : | ||
| 1837 | new SynchronizedList<>(list)); | ||
| 1838 | } | ||
| 1839 | |||
| 1840 | static <T> List<T> synchronizedList(List<T> list, Object mutex) { | ||
| 1841 | return (list instanceof RandomAccess ? | ||
| 1842 | new SynchronizedRandomAccessList<>(list, mutex) : | ||
| 1843 | new SynchronizedList<>(list, mutex)); | ||
| 1844 | } | ||
| 1845 | |||
| 1846 | /** | ||
| 1847 | * @serial include | ||
| 1848 | */ | ||
| 1849 | static class SynchronizedList<E> | ||
| 1850 | extends SynchronizedCollection<E> | ||
| 1851 | implements List<E> { | ||
| 1852 | private static final long serialVersionUID = -7754090372962971524L; | ||
| 1853 | |||
| 1854 | final List<E> list; | ||
| 1855 | |||
| 1856 | SynchronizedList(List<E> list) { | ||
| 1857 | super(list); | ||
| 1858 | this.list = list; | ||
| 1859 | } | ||
| 1860 | SynchronizedList(List<E> list, Object mutex) { | ||
| 1861 | super(list, mutex); | ||
| 1862 | this.list = list; | ||
| 1863 | } | ||
| 1864 | |||
| 1865 | public boolean equals(Object o) { | ||
| 1866 | synchronized (mutex) {return list.equals(o);} | ||
| 1867 | } | ||
| 1868 | public int hashCode() { | ||
| 1869 | synchronized (mutex) {return list.hashCode();} | ||
| 1870 | } | ||
| 1871 | |||
| 1872 | public E get(int index) { | ||
| 1873 | synchronized (mutex) {return list.get(index);} | ||
| 1874 | } | ||
| 1875 | public E set(int index, E element) { | ||
| 1876 | synchronized (mutex) {return list.set(index, element);} | ||
| 1877 | } | ||
| 1878 | public void add(int index, E element) { | ||
| 1879 | synchronized (mutex) {list.add(index, element);} | ||
| 1880 | } | ||
| 1881 | public E remove(int index) { | ||
| 1882 | synchronized (mutex) {return list.remove(index);} | ||
| 1883 | } | ||
| 1884 | |||
| 1885 | public int indexOf(Object o) { | ||
| 1886 | synchronized (mutex) {return list.indexOf(o);} | ||
| 1887 | } | ||
| 1888 | public int lastIndexOf(Object o) { | ||
| 1889 | synchronized (mutex) {return list.lastIndexOf(o);} | ||
| 1890 | } | ||
| 1891 | |||
| 1892 | public boolean addAll(int index, Collection<? extends E> c) { | ||
| 1893 | synchronized (mutex) {return list.addAll(index, c);} | ||
| 1894 | } | ||
| 1895 | |||
| 1896 | public ListIterator<E> listIterator() { | ||
| 1897 | return list.listIterator(); // Must be manually synched by user | ||
| 1898 | } | ||
| 1899 | |||
| 1900 | public ListIterator<E> listIterator(int index) { | ||
| 1901 | return list.listIterator(index); // Must be manually synched by user | ||
| 1902 | } | ||
| 1903 | |||
| 1904 | public List<E> subList(int fromIndex, int toIndex) { | ||
| 1905 | synchronized (mutex) { | ||
| 1906 | return new SynchronizedList<>(list.subList(fromIndex, toIndex), | ||
| 1907 | mutex); | ||
| 1908 | } | ||
| 1909 | } | ||
| 1910 | |||
| 1911 | /** | ||
| 1912 | * SynchronizedRandomAccessList instances are serialized as | ||
| 1913 | * SynchronizedList instances to allow them to be deserialized | ||
| 1914 | * in pre-1.4 JREs (which do not have SynchronizedRandomAccessList). | ||
| 1915 | * This method inverts the transformation. As a beneficial | ||
| 1916 | * side-effect, it also grafts the RandomAccess marker onto | ||
| 1917 | * SynchronizedList instances that were serialized in pre-1.4 JREs. | ||
| 1918 | * | ||
| 1919 | * Note: Unfortunately, SynchronizedRandomAccessList instances | ||
| 1920 | * serialized in 1.4.1 and deserialized in 1.4 will become | ||
| 1921 | * SynchronizedList instances, as this method was missing in 1.4. | ||
| 1922 | */ | ||
| 1923 | private Object readResolve() { | ||
| 1924 | return (list instanceof RandomAccess | ||
| 1925 | ? new SynchronizedRandomAccessList<>(list) | ||
| 1926 | : this); | ||
| 1927 | } | ||
| 1928 | } | ||
| 1929 | |||
| 1930 | /** | ||
| 1931 | * @serial include | ||
| 1932 | */ | ||
| 1933 | static class SynchronizedRandomAccessList<E> | ||
| 1934 | extends SynchronizedList<E> | ||
| 1935 | implements RandomAccess { | ||
| 1936 | |||
| 1937 | SynchronizedRandomAccessList(List<E> list) { | ||
| 1938 | super(list); | ||
| 1939 | } | ||
| 1940 | |||
| 1941 | SynchronizedRandomAccessList(List<E> list, Object mutex) { | ||
| 1942 | super(list, mutex); | ||
| 1943 | } | ||
| 1944 | |||
| 1945 | public List<E> subList(int fromIndex, int toIndex) { | ||
| 1946 | synchronized (mutex) { | ||
| 1947 | return new SynchronizedRandomAccessList<>( | ||
| 1948 | list.subList(fromIndex, toIndex), mutex); | ||
| 1949 | } | ||
| 1950 | } | ||
| 1951 | |||
| 1952 | private static final long serialVersionUID = 1530674583602358482L; | ||
| 1953 | |||
| 1954 | /** | ||
| 1955 | * Allows instances to be deserialized in pre-1.4 JREs (which do | ||
| 1956 | * not have SynchronizedRandomAccessList). SynchronizedList has | ||
| 1957 | * a readResolve method that inverts this transformation upon | ||
| 1958 | * deserialization. | ||
| 1959 | */ | ||
| 1960 | private Object writeReplace() { | ||
| 1961 | return new SynchronizedList<>(list); | ||
| 1962 | } | ||
| 1963 | } | ||
| 1964 | |||
| 1965 | /** | ||
| 1966 | * Returns a synchronized (thread-safe) map backed by the specified | ||
| 1967 | * map. In order to guarantee serial access, it is critical that | ||
| 1968 | * <strong>all</strong> access to the backing map is accomplished | ||
| 1969 | * through the returned map.<p> | ||
| 1970 | * | ||
| 1971 | * It is imperative that the user manually synchronize on the returned | ||
| 1972 | * map when iterating over any of its collection views: | ||
| 1973 | * <pre> | ||
| 1974 | * Map m = Collections.synchronizedMap(new HashMap()); | ||
| 1975 | * ... | ||
| 1976 | * Set s = m.keySet(); // Needn't be in synchronized block | ||
| 1977 | * ... | ||
| 1978 | * synchronized (m) { // Synchronizing on m, not s! | ||
| 1979 | * Iterator i = s.iterator(); // Must be in synchronized block | ||
| 1980 | * while (i.hasNext()) | ||
| 1981 | * foo(i.next()); | ||
| 1982 | * } | ||
| 1983 | * </pre> | ||
| 1984 | * Failure to follow this advice may result in non-deterministic behavior. | ||
| 1985 | * | ||
| 1986 | * <p>The returned map will be serializable if the specified map is | ||
| 1987 | * serializable. | ||
| 1988 | * | ||
| 1989 | * @param m the map to be "wrapped" in a synchronized map. | ||
| 1990 | * @return a synchronized view of the specified map. | ||
| 1991 | */ | ||
| 1992 | public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) { | ||
| 1993 | return new SynchronizedMap<>(m); | ||
| 1994 | } | ||
| 1995 | |||
| 1996 | /** | ||
| 1997 | * @serial include | ||
| 1998 | */ | ||
| 1999 | private static class SynchronizedMap<K,V> | ||
| 2000 | implements Map<K,V>, Serializable { | ||
| 2001 | private static final long serialVersionUID = 1978198479659022715L; | ||
| 2002 | |||
| 2003 | private final Map<K,V> m; // Backing Map | ||
| 2004 | final Object mutex; // Object on which to synchronize | ||
| 2005 | |||
| 2006 | SynchronizedMap(Map<K,V> m) { | ||
| 2007 | if (m==null) | ||
| 2008 | throw new NullPointerException(); | ||
| 2009 | this.m = m; | ||
| 2010 | mutex = this; | ||
| 2011 | } | ||
| 2012 | |||
| 2013 | SynchronizedMap(Map<K,V> m, Object mutex) { | ||
| 2014 | this.m = m; | ||
| 2015 | this.mutex = mutex; | ||
| 2016 | } | ||
| 2017 | |||
| 2018 | public int size() { | ||
| 2019 | synchronized (mutex) {return m.size();} | ||
| 2020 | } | ||
| 2021 | public boolean isEmpty() { | ||
| 2022 | synchronized (mutex) {return m.isEmpty();} | ||
| 2023 | } | ||
| 2024 | public boolean containsKey(Object key) { | ||
| 2025 | synchronized (mutex) {return m.containsKey(key);} | ||
| 2026 | } | ||
| 2027 | public boolean containsValue(Object value) { | ||
| 2028 | synchronized (mutex) {return m.containsValue(value);} | ||
| 2029 | } | ||
| 2030 | public V get(Object key) { | ||
| 2031 | synchronized (mutex) {return m.get(key);} | ||
| 2032 | } | ||
| 2033 | |||
| 2034 | public V put(K key, V value) { | ||
| 2035 | synchronized (mutex) {return m.put(key, value);} | ||
| 2036 | } | ||
| 2037 | public V remove(Object key) { | ||
| 2038 | synchronized (mutex) {return m.remove(key);} | ||
| 2039 | } | ||
| 2040 | public void putAll(Map<? extends K, ? extends V> map) { | ||
| 2041 | synchronized (mutex) {m.putAll(map);} | ||
| 2042 | } | ||
| 2043 | public void clear() { | ||
| 2044 | synchronized (mutex) {m.clear();} | ||
| 2045 | } | ||
| 2046 | |||
| 2047 | private transient Set<K> keySet = null; | ||
| 2048 | private transient Set<Map.Entry<K,V>> entrySet = null; | ||
| 2049 | private transient Collection<V> values = null; | ||
| 2050 | |||
| 2051 | public Set<K> keySet() { | ||
| 2052 | synchronized (mutex) { | ||
| 2053 | if (keySet==null) | ||
| 2054 | keySet = new SynchronizedSet<>(m.keySet(), mutex); | ||
| 2055 | return keySet; | ||
| 2056 | } | ||
| 2057 | } | ||
| 2058 | |||
| 2059 | public Set<Map.Entry<K,V>> entrySet() { | ||
| 2060 | synchronized (mutex) { | ||
| 2061 | if (entrySet==null) | ||
| 2062 | entrySet = new SynchronizedSet<>(m.entrySet(), mutex); | ||
| 2063 | return entrySet; | ||
| 2064 | } | ||
| 2065 | } | ||
| 2066 | |||
| 2067 | public Collection<V> values() { | ||
| 2068 | synchronized (mutex) { | ||
| 2069 | if (values==null) | ||
| 2070 | values = new SynchronizedCollection<>(m.values(), mutex); | ||
| 2071 | return values; | ||
| 2072 | } | ||
| 2073 | } | ||
| 2074 | |||
| 2075 | public boolean equals(Object o) { | ||
| 2076 | synchronized (mutex) {return m.equals(o);} | ||
| 2077 | } | ||
| 2078 | public int hashCode() { | ||
| 2079 | synchronized (mutex) {return m.hashCode();} | ||
| 2080 | } | ||
| 2081 | public String toString() { | ||
| 2082 | synchronized (mutex) {return m.toString();} | ||
| 2083 | } | ||
| 2084 | private void writeObject(ObjectOutputStream s) throws IOException { | ||
| 2085 | synchronized (mutex) {s.defaultWriteObject();} | ||
| 2086 | } | ||
| 2087 | } | ||
| 2088 | |||
| 2089 | /** | ||
| 2090 | * Returns a synchronized (thread-safe) sorted map backed by the specified | ||
| 2091 | * sorted map. In order to guarantee serial access, it is critical that | ||
| 2092 | * <strong>all</strong> access to the backing sorted map is accomplished | ||
| 2093 | * through the returned sorted map (or its views).<p> | ||
| 2094 | * | ||
| 2095 | * It is imperative that the user manually synchronize on the returned | ||
| 2096 | * sorted map when iterating over any of its collection views, or the | ||
| 2097 | * collections views of any of its <tt>subMap</tt>, <tt>headMap</tt> or | ||
| 2098 | * <tt>tailMap</tt> views. | ||
| 2099 | * <pre> | ||
| 2100 | * SortedMap m = Collections.synchronizedSortedMap(new TreeMap()); | ||
| 2101 | * ... | ||
| 2102 | * Set s = m.keySet(); // Needn't be in synchronized block | ||
| 2103 | * ... | ||
| 2104 | * synchronized (m) { // Synchronizing on m, not s! | ||
| 2105 | * Iterator i = s.iterator(); // Must be in synchronized block | ||
| 2106 | * while (i.hasNext()) | ||
| 2107 | * foo(i.next()); | ||
| 2108 | * } | ||
| 2109 | * </pre> | ||
| 2110 | * or: | ||
| 2111 | * <pre> | ||
| 2112 | * SortedMap m = Collections.synchronizedSortedMap(new TreeMap()); | ||
| 2113 | * SortedMap m2 = m.subMap(foo, bar); | ||
| 2114 | * ... | ||
| 2115 | * Set s2 = m2.keySet(); // Needn't be in synchronized block | ||
| 2116 | * ... | ||
| 2117 | * synchronized (m) { // Synchronizing on m, not m2 or s2! | ||
| 2118 | * Iterator i = s.iterator(); // Must be in synchronized block | ||
| 2119 | * while (i.hasNext()) | ||
| 2120 | * foo(i.next()); | ||
| 2121 | * } | ||
| 2122 | * </pre> | ||
| 2123 | * Failure to follow this advice may result in non-deterministic behavior. | ||
| 2124 | * | ||
| 2125 | * <p>The returned sorted map will be serializable if the specified | ||
| 2126 | * sorted map is serializable. | ||
| 2127 | * | ||
| 2128 | * @param m the sorted map to be "wrapped" in a synchronized sorted map. | ||
| 2129 | * @return a synchronized view of the specified sorted map. | ||
| 2130 | */ | ||
| 2131 | public static <K,V> SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> m) { | ||
| 2132 | return new SynchronizedSortedMap<>(m); | ||
| 2133 | } | ||
| 2134 | |||
| 2135 | |||
| 2136 | /** | ||
| 2137 | * @serial include | ||
| 2138 | */ | ||
| 2139 | static class SynchronizedSortedMap<K,V> | ||
| 2140 | extends SynchronizedMap<K,V> | ||
| 2141 | implements SortedMap<K,V> | ||
| 2142 | { | ||
| 2143 | private static final long serialVersionUID = -8798146769416483793L; | ||
| 2144 | |||
| 2145 | private final SortedMap<K,V> sm; | ||
| 2146 | |||
| 2147 | SynchronizedSortedMap(SortedMap<K,V> m) { | ||
| 2148 | super(m); | ||
| 2149 | sm = m; | ||
| 2150 | } | ||
| 2151 | SynchronizedSortedMap(SortedMap<K,V> m, Object mutex) { | ||
| 2152 | super(m, mutex); | ||
| 2153 | sm = m; | ||
| 2154 | } | ||
| 2155 | |||
| 2156 | public Comparator<? super K> comparator() { | ||
| 2157 | synchronized (mutex) {return sm.comparator();} | ||
| 2158 | } | ||
| 2159 | |||
| 2160 | public SortedMap<K,V> subMap(K fromKey, K toKey) { | ||
| 2161 | synchronized (mutex) { | ||
| 2162 | return new SynchronizedSortedMap<>( | ||
| 2163 | sm.subMap(fromKey, toKey), mutex); | ||
| 2164 | } | ||
| 2165 | } | ||
| 2166 | public SortedMap<K,V> headMap(K toKey) { | ||
| 2167 | synchronized (mutex) { | ||
| 2168 | return new SynchronizedSortedMap<>(sm.headMap(toKey), mutex); | ||
| 2169 | } | ||
| 2170 | } | ||
| 2171 | public SortedMap<K,V> tailMap(K fromKey) { | ||
| 2172 | synchronized (mutex) { | ||
| 2173 | return new SynchronizedSortedMap<>(sm.tailMap(fromKey),mutex); | ||
| 2174 | } | ||
| 2175 | } | ||
| 2176 | |||
| 2177 | public K firstKey() { | ||
| 2178 | synchronized (mutex) {return sm.firstKey();} | ||
| 2179 | } | ||
| 2180 | public K lastKey() { | ||
| 2181 | synchronized (mutex) {return sm.lastKey();} | ||
| 2182 | } | ||
| 2183 | } | ||
| 2184 | |||
| 2185 | // Dynamically typesafe collection wrappers | ||
| 2186 | |||
| 2187 | /** | ||
| 2188 | * Returns a dynamically typesafe view of the specified collection. | ||
| 2189 | * Any attempt to insert an element of the wrong type will result in an | ||
| 2190 | * immediate {@link ClassCastException}. Assuming a collection | ||
| 2191 | * contains no incorrectly typed elements prior to the time a | ||
| 2192 | * dynamically typesafe view is generated, and that all subsequent | ||
| 2193 | * access to the collection takes place through the view, it is | ||
| 2194 | * <i>guaranteed</i> that the collection cannot contain an incorrectly | ||
| 2195 | * typed element. | ||
| 2196 | * | ||
| 2197 | * <p>The generics mechanism in the language provides compile-time | ||
| 2198 | * (static) type checking, but it is possible to defeat this mechanism | ||
| 2199 | * with unchecked casts. Usually this is not a problem, as the compiler | ||
| 2200 | * issues warnings on all such unchecked operations. There are, however, | ||
| 2201 | * times when static type checking alone is not sufficient. For example, | ||
| 2202 | * suppose a collection is passed to a third-party library and it is | ||
| 2203 | * imperative that the library code not corrupt the collection by | ||
| 2204 | * inserting an element of the wrong type. | ||
| 2205 | * | ||
| 2206 | * <p>Another use of dynamically typesafe views is debugging. Suppose a | ||
| 2207 | * program fails with a {@code ClassCastException}, indicating that an | ||
| 2208 | * incorrectly typed element was put into a parameterized collection. | ||
| 2209 | * Unfortunately, the exception can occur at any time after the erroneous | ||
| 2210 | * element is inserted, so it typically provides little or no information | ||
| 2211 | * as to the real source of the problem. If the problem is reproducible, | ||
| 2212 | * one can quickly determine its source by temporarily modifying the | ||
| 2213 | * program to wrap the collection with a dynamically typesafe view. | ||
| 2214 | * For example, this declaration: | ||
| 2215 | * <pre> {@code | ||
| 2216 | * Collection<String> c = new HashSet<String>(); | ||
| 2217 | * }</pre> | ||
| 2218 | * may be replaced temporarily by this one: | ||
| 2219 | * <pre> {@code | ||
| 2220 | * Collection<String> c = Collections.checkedCollection( | ||
| 2221 | * new HashSet<String>(), String.class); | ||
| 2222 | * }</pre> | ||
| 2223 | * Running the program again will cause it to fail at the point where | ||
| 2224 | * an incorrectly typed element is inserted into the collection, clearly | ||
| 2225 | * identifying the source of the problem. Once the problem is fixed, the | ||
| 2226 | * modified declaration may be reverted back to the original. | ||
| 2227 | * | ||
| 2228 | * <p>The returned collection does <i>not</i> pass the hashCode and equals | ||
| 2229 | * operations through to the backing collection, but relies on | ||
| 2230 | * {@code Object}'s {@code equals} and {@code hashCode} methods. This | ||
| 2231 | * is necessary to preserve the contracts of these operations in the case | ||
| 2232 | * that the backing collection is a set or a list. | ||
| 2233 | * | ||
| 2234 | * <p>The returned collection will be serializable if the specified | ||
| 2235 | * collection is serializable. | ||
| 2236 | * | ||
| 2237 | * <p>Since {@code null} is considered to be a value of any reference | ||
| 2238 | * type, the returned collection permits insertion of null elements | ||
| 2239 | * whenever the backing collection does. | ||
| 2240 | * | ||
| 2241 | * @param c the collection for which a dynamically typesafe view is to be | ||
| 2242 | * returned | ||
| 2243 | * @param type the type of element that {@code c} is permitted to hold | ||
| 2244 | * @return a dynamically typesafe view of the specified collection | ||
| 2245 | * @since 1.5 | ||
| 2246 | */ | ||
| 2247 | public static <E> Collection<E> checkedCollection(Collection<E> c, | ||
| 2248 | Class<E> type) { | ||
| 2249 | return new CheckedCollection<>(c, type); | ||
| 2250 | } | ||
| 2251 | |||
| 2252 | @SuppressWarnings("unchecked") | ||
| 2253 | static <T> T[] zeroLengthArray(Class<T> type) { | ||
| 2254 | return (T[]) Array.newInstance(type, 0); | ||
| 2255 | } | ||
| 2256 | |||
| 2257 | /** | ||
| 2258 | * @serial include | ||
| 2259 | */ | ||
| 2260 | static class CheckedCollection<E> implements Collection<E>, Serializable { | ||
| 2261 | private static final long serialVersionUID = 1578914078182001775L; | ||
| 2262 | |||
| 2263 | final Collection<E> c; | ||
| 2264 | final Class<E> type; | ||
| 2265 | |||
| 2266 | void typeCheck(Object o) { | ||
| 2267 | if (o != null && !type.isInstance(o)) | ||
| 2268 | throw new ClassCastException(badElementMsg(o)); | ||
| 2269 | } | ||
| 2270 | |||
| 2271 | private String badElementMsg(Object o) { | ||
| 2272 | return "Attempt to insert " + o.getClass() + | ||
| 2273 | " element into collection with element type " + type; | ||
| 2274 | } | ||
| 2275 | |||
| 2276 | CheckedCollection(Collection<E> c, Class<E> type) { | ||
| 2277 | if (c==null || type == null) | ||
| 2278 | throw new NullPointerException(); | ||
| 2279 | this.c = c; | ||
| 2280 | this.type = type; | ||
| 2281 | } | ||
| 2282 | |||
| 2283 | public int size() { return c.size(); } | ||
| 2284 | public boolean isEmpty() { return c.isEmpty(); } | ||
| 2285 | public boolean contains(Object o) { return c.contains(o); } | ||
| 2286 | public Object[] toArray() { return c.toArray(); } | ||
| 2287 | public <T> T[] toArray(T[] a) { return c.toArray(a); } | ||
| 2288 | public String toString() { return c.toString(); } | ||
| 2289 | public boolean remove(Object o) { return c.remove(o); } | ||
| 2290 | public void clear() { c.clear(); } | ||
| 2291 | |||
| 2292 | public boolean containsAll(Collection<?> coll) { | ||
| 2293 | return c.containsAll(coll); | ||
| 2294 | } | ||
| 2295 | public boolean removeAll(Collection<?> coll) { | ||
| 2296 | return c.removeAll(coll); | ||
| 2297 | } | ||
| 2298 | public boolean retainAll(Collection<?> coll) { | ||
| 2299 | return c.retainAll(coll); | ||
| 2300 | } | ||
| 2301 | |||
| 2302 | public Iterator<E> iterator() { | ||
| 2303 | final Iterator<E> it = c.iterator(); | ||
| 2304 | return new Iterator<E>() { | ||
| 2305 | public boolean hasNext() { return it.hasNext(); } | ||
| 2306 | public E next() { return it.next(); } | ||
| 2307 | public void remove() { it.remove(); }}; | ||
| 2308 | } | ||
| 2309 | |||
| 2310 | public boolean add(E e) { | ||
| 2311 | typeCheck(e); | ||
| 2312 | return c.add(e); | ||
| 2313 | } | ||
| 2314 | |||
| 2315 | private E[] zeroLengthElementArray = null; // Lazily initialized | ||
| 2316 | |||
| 2317 | private E[] zeroLengthElementArray() { | ||
| 2318 | return zeroLengthElementArray != null ? zeroLengthElementArray : | ||
| 2319 | (zeroLengthElementArray = zeroLengthArray(type)); | ||
| 2320 | } | ||
| 2321 | |||
| 2322 | @SuppressWarnings("unchecked") | ||
| 2323 | Collection<E> checkedCopyOf(Collection<? extends E> coll) { | ||
| 2324 | Object[] a = null; | ||
| 2325 | try { | ||
| 2326 | E[] z = zeroLengthElementArray(); | ||
| 2327 | a = coll.toArray(z); | ||
| 2328 | // Defend against coll violating the toArray contract | ||
| 2329 | if (a.getClass() != z.getClass()) | ||
| 2330 | a = Arrays.copyOf(a, a.length, z.getClass()); | ||
| 2331 | } catch (ArrayStoreException ignore) { | ||
| 2332 | // To get better and consistent diagnostics, | ||
| 2333 | // we call typeCheck explicitly on each element. | ||
| 2334 | // We call clone() to defend against coll retaining a | ||
| 2335 | // reference to the returned array and storing a bad | ||
| 2336 | // element into it after it has been type checked. | ||
| 2337 | a = coll.toArray().clone(); | ||
| 2338 | for (Object o : a) | ||
| 2339 | typeCheck(o); | ||
| 2340 | } | ||
| 2341 | // A slight abuse of the type system, but safe here. | ||
| 2342 | return (Collection<E>) Arrays.asList(a); | ||
| 2343 | } | ||
| 2344 | |||
| 2345 | public boolean addAll(Collection<? extends E> coll) { | ||
| 2346 | // Doing things this way insulates us from concurrent changes | ||
| 2347 | // in the contents of coll and provides all-or-nothing | ||
| 2348 | // semantics (which we wouldn't get if we type-checked each | ||
| 2349 | // element as we added it) | ||
| 2350 | return c.addAll(checkedCopyOf(coll)); | ||
| 2351 | } | ||
| 2352 | } | ||
| 2353 | |||
| 2354 | /** | ||
| 2355 | * Returns a dynamically typesafe view of the specified set. | ||
| 2356 | * Any attempt to insert an element of the wrong type will result in | ||
| 2357 | * an immediate {@link ClassCastException}. Assuming a set contains | ||
| 2358 | * no incorrectly typed elements prior to the time a dynamically typesafe | ||
| 2359 | * view is generated, and that all subsequent access to the set | ||
| 2360 | * takes place through the view, it is <i>guaranteed</i> that the | ||
| 2361 | * set cannot contain an incorrectly typed element. | ||
| 2362 | * | ||
| 2363 | * <p>A discussion of the use of dynamically typesafe views may be | ||
| 2364 | * found in the documentation for the {@link #checkedCollection | ||
| 2365 | * checkedCollection} method. | ||
| 2366 | * | ||
| 2367 | * <p>The returned set will be serializable if the specified set is | ||
| 2368 | * serializable. | ||
| 2369 | * | ||
| 2370 | * <p>Since {@code null} is considered to be a value of any reference | ||
| 2371 | * type, the returned set permits insertion of null elements whenever | ||
| 2372 | * the backing set does. | ||
| 2373 | * | ||
| 2374 | * @param s the set for which a dynamically typesafe view is to be | ||
| 2375 | * returned | ||
| 2376 | * @param type the type of element that {@code s} is permitted to hold | ||
| 2377 | * @return a dynamically typesafe view of the specified set | ||
| 2378 | * @since 1.5 | ||
| 2379 | */ | ||
| 2380 | public static <E> Set<E> checkedSet(Set<E> s, Class<E> type) { | ||
| 2381 | return new CheckedSet<>(s, type); | ||
| 2382 | } | ||
| 2383 | |||
| 2384 | /** | ||
| 2385 | * @serial include | ||
| 2386 | */ | ||
| 2387 | static class CheckedSet<E> extends CheckedCollection<E> | ||
| 2388 | implements Set<E>, Serializable | ||
| 2389 | { | ||
| 2390 | private static final long serialVersionUID = 4694047833775013803L; | ||
| 2391 | |||
| 2392 | CheckedSet(Set<E> s, Class<E> elementType) { super(s, elementType); } | ||
| 2393 | |||
| 2394 | public boolean equals(Object o) { return o == this || c.equals(o); } | ||
| 2395 | public int hashCode() { return c.hashCode(); } | ||
| 2396 | } | ||
| 2397 | |||
| 2398 | /** | ||
| 2399 | * Returns a dynamically typesafe view of the specified sorted set. | ||
| 2400 | * Any attempt to insert an element of the wrong type will result in an | ||
| 2401 | * immediate {@link ClassCastException}. Assuming a sorted set | ||
| 2402 | * contains no incorrectly typed elements prior to the time a | ||
| 2403 | * dynamically typesafe view is generated, and that all subsequent | ||
| 2404 | * access to the sorted set takes place through the view, it is | ||
| 2405 | * <i>guaranteed</i> that the sorted set cannot contain an incorrectly | ||
| 2406 | * typed element. | ||
| 2407 | * | ||
| 2408 | * <p>A discussion of the use of dynamically typesafe views may be | ||
| 2409 | * found in the documentation for the {@link #checkedCollection | ||
| 2410 | * checkedCollection} method. | ||
| 2411 | * | ||
| 2412 | * <p>The returned sorted set will be serializable if the specified sorted | ||
| 2413 | * set is serializable. | ||
| 2414 | * | ||
| 2415 | * <p>Since {@code null} is considered to be a value of any reference | ||
| 2416 | * type, the returned sorted set permits insertion of null elements | ||
| 2417 | * whenever the backing sorted set does. | ||
| 2418 | * | ||
| 2419 | * @param s the sorted set for which a dynamically typesafe view is to be | ||
| 2420 | * returned | ||
| 2421 | * @param type the type of element that {@code s} is permitted to hold | ||
| 2422 | * @return a dynamically typesafe view of the specified sorted set | ||
| 2423 | * @since 1.5 | ||
| 2424 | */ | ||
| 2425 | public static <E> SortedSet<E> checkedSortedSet(SortedSet<E> s, | ||
| 2426 | Class<E> type) { | ||
| 2427 | return new CheckedSortedSet<>(s, type); | ||
| 2428 | } | ||
| 2429 | |||
| 2430 | /** | ||
| 2431 | * @serial include | ||
| 2432 | */ | ||
| 2433 | static class CheckedSortedSet<E> extends CheckedSet<E> | ||
| 2434 | implements SortedSet<E>, Serializable | ||
| 2435 | { | ||
| 2436 | private static final long serialVersionUID = 1599911165492914959L; | ||
| 2437 | private final SortedSet<E> ss; | ||
| 2438 | |||
| 2439 | CheckedSortedSet(SortedSet<E> s, Class<E> type) { | ||
| 2440 | super(s, type); | ||
| 2441 | ss = s; | ||
| 2442 | } | ||
| 2443 | |||
| 2444 | public Comparator<? super E> comparator() { return ss.comparator(); } | ||
| 2445 | public E first() { return ss.first(); } | ||
| 2446 | public E last() { return ss.last(); } | ||
| 2447 | |||
| 2448 | public SortedSet<E> subSet(E fromElement, E toElement) { | ||
| 2449 | return checkedSortedSet(ss.subSet(fromElement,toElement), type); | ||
| 2450 | } | ||
| 2451 | public SortedSet<E> headSet(E toElement) { | ||
| 2452 | return checkedSortedSet(ss.headSet(toElement), type); | ||
| 2453 | } | ||
| 2454 | public SortedSet<E> tailSet(E fromElement) { | ||
| 2455 | return checkedSortedSet(ss.tailSet(fromElement), type); | ||
| 2456 | } | ||
| 2457 | } | ||
| 2458 | |||
| 2459 | /** | ||
| 2460 | * Returns a dynamically typesafe view of the specified list. | ||
| 2461 | * Any attempt to insert an element of the wrong type will result in | ||
| 2462 | * an immediate {@link ClassCastException}. Assuming a list contains | ||
| 2463 | * no incorrectly typed elements prior to the time a dynamically typesafe | ||
| 2464 | * view is generated, and that all subsequent access to the list | ||
| 2465 | * takes place through the view, it is <i>guaranteed</i> that the | ||
| 2466 | * list cannot contain an incorrectly typed element. | ||
| 2467 | * | ||
| 2468 | * <p>A discussion of the use of dynamically typesafe views may be | ||
| 2469 | * found in the documentation for the {@link #checkedCollection | ||
| 2470 | * checkedCollection} method. | ||
| 2471 | * | ||
| 2472 | * <p>The returned list will be serializable if the specified list | ||
| 2473 | * is serializable. | ||
| 2474 | * | ||
| 2475 | * <p>Since {@code null} is considered to be a value of any reference | ||
| 2476 | * type, the returned list permits insertion of null elements whenever | ||
| 2477 | * the backing list does. | ||
| 2478 | * | ||
| 2479 | * @param list the list for which a dynamically typesafe view is to be | ||
| 2480 | * returned | ||
| 2481 | * @param type the type of element that {@code list} is permitted to hold | ||
| 2482 | * @return a dynamically typesafe view of the specified list | ||
| 2483 | * @since 1.5 | ||
| 2484 | */ | ||
| 2485 | public static <E> List<E> checkedList(List<E> list, Class<E> type) { | ||
| 2486 | return (list instanceof RandomAccess ? | ||
| 2487 | new CheckedRandomAccessList<>(list, type) : | ||
| 2488 | new CheckedList<>(list, type)); | ||
| 2489 | } | ||
| 2490 | |||
| 2491 | /** | ||
| 2492 | * @serial include | ||
| 2493 | */ | ||
| 2494 | static class CheckedList<E> | ||
| 2495 | extends CheckedCollection<E> | ||
| 2496 | implements List<E> | ||
| 2497 | { | ||
| 2498 | private static final long serialVersionUID = 65247728283967356L; | ||
| 2499 | final List<E> list; | ||
| 2500 | |||
| 2501 | CheckedList(List<E> list, Class<E> type) { | ||
| 2502 | super(list, type); | ||
| 2503 | this.list = list; | ||
| 2504 | } | ||
| 2505 | |||
| 2506 | public boolean equals(Object o) { return o == this || list.equals(o); } | ||
| 2507 | public int hashCode() { return list.hashCode(); } | ||
| 2508 | public E get(int index) { return list.get(index); } | ||
| 2509 | public E remove(int index) { return list.remove(index); } | ||
| 2510 | public int indexOf(Object o) { return list.indexOf(o); } | ||
| 2511 | public int lastIndexOf(Object o) { return list.lastIndexOf(o); } | ||
| 2512 | |||
| 2513 | public E set(int index, E element) { | ||
| 2514 | typeCheck(element); | ||
| 2515 | return list.set(index, element); | ||
| 2516 | } | ||
| 2517 | |||
| 2518 | public void add(int index, E element) { | ||
| 2519 | typeCheck(element); | ||
| 2520 | list.add(index, element); | ||
| 2521 | } | ||
| 2522 | |||
| 2523 | public boolean addAll(int index, Collection<? extends E> c) { | ||
| 2524 | return list.addAll(index, checkedCopyOf(c)); | ||
| 2525 | } | ||
| 2526 | public ListIterator<E> listIterator() { return listIterator(0); } | ||
| 2527 | |||
| 2528 | public ListIterator<E> listIterator(final int index) { | ||
| 2529 | final ListIterator<E> i = list.listIterator(index); | ||
| 2530 | |||
| 2531 | return new ListIterator<E>() { | ||
| 2532 | public boolean hasNext() { return i.hasNext(); } | ||
| 2533 | public E next() { return i.next(); } | ||
| 2534 | public boolean hasPrevious() { return i.hasPrevious(); } | ||
| 2535 | public E previous() { return i.previous(); } | ||
| 2536 | public int nextIndex() { return i.nextIndex(); } | ||
| 2537 | public int previousIndex() { return i.previousIndex(); } | ||
| 2538 | public void remove() { i.remove(); } | ||
| 2539 | |||
| 2540 | public void set(E e) { | ||
| 2541 | typeCheck(e); | ||
| 2542 | i.set(e); | ||
| 2543 | } | ||
| 2544 | |||
| 2545 | public void add(E e) { | ||
| 2546 | typeCheck(e); | ||
| 2547 | i.add(e); | ||
| 2548 | } | ||
| 2549 | }; | ||
| 2550 | } | ||
| 2551 | |||
| 2552 | public List<E> subList(int fromIndex, int toIndex) { | ||
| 2553 | return new CheckedList<>(list.subList(fromIndex, toIndex), type); | ||
| 2554 | } | ||
| 2555 | } | ||
| 2556 | |||
| 2557 | /** | ||
| 2558 | * @serial include | ||
| 2559 | */ | ||
| 2560 | static class CheckedRandomAccessList<E> extends CheckedList<E> | ||
| 2561 | implements RandomAccess | ||
| 2562 | { | ||
| 2563 | private static final long serialVersionUID = 1638200125423088369L; | ||
| 2564 | |||
| 2565 | CheckedRandomAccessList(List<E> list, Class<E> type) { | ||
| 2566 | super(list, type); | ||
| 2567 | } | ||
| 2568 | |||
| 2569 | public List<E> subList(int fromIndex, int toIndex) { | ||
| 2570 | return new CheckedRandomAccessList<>( | ||
| 2571 | list.subList(fromIndex, toIndex), type); | ||
| 2572 | } | ||
| 2573 | } | ||
| 2574 | |||
| 2575 | /** | ||
| 2576 | * Returns a dynamically typesafe view of the specified map. | ||
| 2577 | * Any attempt to insert a mapping whose key or value have the wrong | ||
| 2578 | * type will result in an immediate {@link ClassCastException}. | ||
| 2579 | * Similarly, any attempt to modify the value currently associated with | ||
| 2580 | * a key will result in an immediate {@link ClassCastException}, | ||
| 2581 | * whether the modification is attempted directly through the map | ||
| 2582 | * itself, or through a {@link Map.Entry} instance obtained from the | ||
| 2583 | * map's {@link Map#entrySet() entry set} view. | ||
| 2584 | * | ||
| 2585 | * <p>Assuming a map contains no incorrectly typed keys or values | ||
| 2586 | * prior to the time a dynamically typesafe view is generated, and | ||
| 2587 | * that all subsequent access to the map takes place through the view | ||
| 2588 | * (or one of its collection views), it is <i>guaranteed</i> that the | ||
| 2589 | * map cannot contain an incorrectly typed key or value. | ||
| 2590 | * | ||
| 2591 | * <p>A discussion of the use of dynamically typesafe views may be | ||
| 2592 | * found in the documentation for the {@link #checkedCollection | ||
| 2593 | * checkedCollection} method. | ||
| 2594 | * | ||
| 2595 | * <p>The returned map will be serializable if the specified map is | ||
| 2596 | * serializable. | ||
| 2597 | * | ||
| 2598 | * <p>Since {@code null} is considered to be a value of any reference | ||
| 2599 | * type, the returned map permits insertion of null keys or values | ||
| 2600 | * whenever the backing map does. | ||
| 2601 | * | ||
| 2602 | * @param m the map for which a dynamically typesafe view is to be | ||
| 2603 | * returned | ||
| 2604 | * @param keyType the type of key that {@code m} is permitted to hold | ||
| 2605 | * @param valueType the type of value that {@code m} is permitted to hold | ||
| 2606 | * @return a dynamically typesafe view of the specified map | ||
| 2607 | * @since 1.5 | ||
| 2608 | */ | ||
| 2609 | public static <K, V> Map<K, V> checkedMap(Map<K, V> m, | ||
| 2610 | Class<K> keyType, | ||
| 2611 | Class<V> valueType) { | ||
| 2612 | return new CheckedMap<>(m, keyType, valueType); | ||
| 2613 | } | ||
| 2614 | |||
| 2615 | |||
| 2616 | /** | ||
| 2617 | * @serial include | ||
| 2618 | */ | ||
| 2619 | private static class CheckedMap<K,V> | ||
| 2620 | implements Map<K,V>, Serializable | ||
| 2621 | { | ||
| 2622 | private static final long serialVersionUID = 5742860141034234728L; | ||
| 2623 | |||
| 2624 | private final Map<K, V> m; | ||
| 2625 | final Class<K> keyType; | ||
| 2626 | final Class<V> valueType; | ||
| 2627 | |||
| 2628 | private void typeCheck(Object key, Object value) { | ||
| 2629 | if (key != null && !keyType.isInstance(key)) | ||
| 2630 | throw new ClassCastException(badKeyMsg(key)); | ||
| 2631 | |||
| 2632 | if (value != null && !valueType.isInstance(value)) | ||
| 2633 | throw new ClassCastException(badValueMsg(value)); | ||
| 2634 | } | ||
| 2635 | |||
| 2636 | private String badKeyMsg(Object key) { | ||
| 2637 | return "Attempt to insert " + key.getClass() + | ||
| 2638 | " key into map with key type " + keyType; | ||
| 2639 | } | ||
| 2640 | |||
| 2641 | private String badValueMsg(Object value) { | ||
| 2642 | return "Attempt to insert " + value.getClass() + | ||
| 2643 | " value into map with value type " + valueType; | ||
| 2644 | } | ||
| 2645 | |||
| 2646 | CheckedMap(Map<K, V> m, Class<K> keyType, Class<V> valueType) { | ||
| 2647 | if (m == null || keyType == null || valueType == null) | ||
| 2648 | throw new NullPointerException(); | ||
| 2649 | this.m = m; | ||
| 2650 | this.keyType = keyType; | ||
| 2651 | this.valueType = valueType; | ||
| 2652 | } | ||
| 2653 | |||
| 2654 | public int size() { return m.size(); } | ||
| 2655 | public boolean isEmpty() { return m.isEmpty(); } | ||
| 2656 | public boolean containsKey(Object key) { return m.containsKey(key); } | ||
| 2657 | public boolean containsValue(Object v) { return m.containsValue(v); } | ||
| 2658 | public V get(Object key) { return m.get(key); } | ||
| 2659 | public V remove(Object key) { return m.remove(key); } | ||
| 2660 | public void clear() { m.clear(); } | ||
| 2661 | public Set<K> keySet() { return m.keySet(); } | ||
| 2662 | public Collection<V> values() { return m.values(); } | ||
| 2663 | public boolean equals(Object o) { return o == this || m.equals(o); } | ||
| 2664 | public int hashCode() { return m.hashCode(); } | ||
| 2665 | public String toString() { return m.toString(); } | ||
| 2666 | |||
| 2667 | public V put(K key, V value) { | ||
| 2668 | typeCheck(key, value); | ||
| 2669 | return m.put(key, value); | ||
| 2670 | } | ||
| 2671 | |||
| 2672 | @SuppressWarnings("unchecked") | ||
| 2673 | public void putAll(Map<? extends K, ? extends V> t) { | ||
| 2674 | // Satisfy the following goals: | ||
| 2675 | // - good diagnostics in case of type mismatch | ||
| 2676 | // - all-or-nothing semantics | ||
| 2677 | // - protection from malicious t | ||
| 2678 | // - correct behavior if t is a concurrent map | ||
| 2679 | Object[] entries = t.entrySet().toArray(); | ||
| 2680 | List<Map.Entry<K,V>> checked = new ArrayList<>(entries.length); | ||
| 2681 | for (Object o : entries) { | ||
| 2682 | Map.Entry<?,?> e = (Map.Entry<?,?>) o; | ||
| 2683 | Object k = e.getKey(); | ||
| 2684 | Object v = e.getValue(); | ||
| 2685 | typeCheck(k, v); | ||
| 2686 | checked.add( | ||
| 2687 | new AbstractMap.SimpleImmutableEntry<>((K) k, (V) v)); | ||
| 2688 | } | ||
| 2689 | for (Map.Entry<K,V> e : checked) | ||
| 2690 | m.put(e.getKey(), e.getValue()); | ||
| 2691 | } | ||
| 2692 | |||
| 2693 | private transient Set<Map.Entry<K,V>> entrySet = null; | ||
| 2694 | |||
| 2695 | public Set<Map.Entry<K,V>> entrySet() { | ||
| 2696 | if (entrySet==null) | ||
| 2697 | entrySet = new CheckedEntrySet<>(m.entrySet(), valueType); | ||
| 2698 | return entrySet; | ||
| 2699 | } | ||
| 2700 | |||
| 2701 | /** | ||
| 2702 | * We need this class in addition to CheckedSet as Map.Entry permits | ||
| 2703 | * modification of the backing Map via the setValue operation. This | ||
| 2704 | * class is subtle: there are many possible attacks that must be | ||
| 2705 | * thwarted. | ||
| 2706 | * | ||
| 2707 | * @serial exclude | ||
| 2708 | */ | ||
| 2709 | static class CheckedEntrySet<K,V> implements Set<Map.Entry<K,V>> { | ||
| 2710 | private final Set<Map.Entry<K,V>> s; | ||
| 2711 | private final Class<V> valueType; | ||
| 2712 | |||
| 2713 | CheckedEntrySet(Set<Map.Entry<K, V>> s, Class<V> valueType) { | ||
| 2714 | this.s = s; | ||
| 2715 | this.valueType = valueType; | ||
| 2716 | } | ||
| 2717 | |||
| 2718 | public int size() { return s.size(); } | ||
| 2719 | public boolean isEmpty() { return s.isEmpty(); } | ||
| 2720 | public String toString() { return s.toString(); } | ||
| 2721 | public int hashCode() { return s.hashCode(); } | ||
| 2722 | public void clear() { s.clear(); } | ||
| 2723 | |||
| 2724 | public boolean add(Map.Entry<K, V> e) { | ||
| 2725 | throw new UnsupportedOperationException(); | ||
| 2726 | } | ||
| 2727 | public boolean addAll(Collection<? extends Map.Entry<K, V>> coll) { | ||
| 2728 | throw new UnsupportedOperationException(); | ||
| 2729 | } | ||
| 2730 | |||
| 2731 | public Iterator<Map.Entry<K,V>> iterator() { | ||
| 2732 | final Iterator<Map.Entry<K, V>> i = s.iterator(); | ||
| 2733 | final Class<V> valueType = this.valueType; | ||
| 2734 | |||
| 2735 | return new Iterator<Map.Entry<K,V>>() { | ||
| 2736 | public boolean hasNext() { return i.hasNext(); } | ||
| 2737 | public void remove() { i.remove(); } | ||
| 2738 | |||
| 2739 | public Map.Entry<K,V> next() { | ||
| 2740 | return checkedEntry(i.next(), valueType); | ||
| 2741 | } | ||
| 2742 | }; | ||
| 2743 | } | ||
| 2744 | |||
| 2745 | @SuppressWarnings("unchecked") | ||
| 2746 | public Object[] toArray() { | ||
| 2747 | Object[] source = s.toArray(); | ||
| 2748 | |||
| 2749 | /* | ||
| 2750 | * Ensure that we don't get an ArrayStoreException even if | ||
| 2751 | * s.toArray returns an array of something other than Object | ||
| 2752 | */ | ||
| 2753 | Object[] dest = (CheckedEntry.class.isInstance( | ||
| 2754 | source.getClass().getComponentType()) ? source : | ||
| 2755 | new Object[source.length]); | ||
| 2756 | |||
| 2757 | for (int i = 0; i < source.length; i++) | ||
| 2758 | dest[i] = checkedEntry((Map.Entry<K,V>)source[i], | ||
| 2759 | valueType); | ||
| 2760 | return dest; | ||
| 2761 | } | ||
| 2762 | |||
| 2763 | @SuppressWarnings("unchecked") | ||
| 2764 | public <T> T[] toArray(T[] a) { | ||
| 2765 | // We don't pass a to s.toArray, to avoid window of | ||
| 2766 | // vulnerability wherein an unscrupulous multithreaded client | ||
| 2767 | // could get his hands on raw (unwrapped) Entries from s. | ||
| 2768 | T[] arr = s.toArray(a.length==0 ? a : Arrays.copyOf(a, 0)); | ||
| 2769 | |||
| 2770 | for (int i=0; i<arr.length; i++) | ||
| 2771 | arr[i] = (T) checkedEntry((Map.Entry<K,V>)arr[i], | ||
| 2772 | valueType); | ||
| 2773 | if (arr.length > a.length) | ||
| 2774 | return arr; | ||
| 2775 | |||
| 2776 | System.arraycopy(arr, 0, a, 0, arr.length); | ||
| 2777 | if (a.length > arr.length) | ||
| 2778 | a[arr.length] = null; | ||
| 2779 | return a; | ||
| 2780 | } | ||
| 2781 | |||
| 2782 | /** | ||
| 2783 | * This method is overridden to protect the backing set against | ||
| 2784 | * an object with a nefarious equals function that senses | ||
| 2785 | * that the equality-candidate is Map.Entry and calls its | ||
| 2786 | * setValue method. | ||
| 2787 | */ | ||
| 2788 | public boolean contains(Object o) { | ||
| 2789 | if (!(o instanceof Map.Entry)) | ||
| 2790 | return false; | ||
| 2791 | Map.Entry<?,?> e = (Map.Entry<?,?>) o; | ||
| 2792 | return s.contains( | ||
| 2793 | (e instanceof CheckedEntry) ? e : checkedEntry(e, valueType)); | ||
| 2794 | } | ||
| 2795 | |||
| 2796 | /** | ||
| 2797 | * The bulk collection methods are overridden to protect | ||
| 2798 | * against an unscrupulous collection whose contains(Object o) | ||
| 2799 | * method senses when o is a Map.Entry, and calls o.setValue. | ||
| 2800 | */ | ||
| 2801 | public boolean containsAll(Collection<?> c) { | ||
| 2802 | for (Object o : c) | ||
| 2803 | if (!contains(o)) // Invokes safe contains() above | ||
| 2804 | return false; | ||
| 2805 | return true; | ||
| 2806 | } | ||
| 2807 | |||
| 2808 | public boolean remove(Object o) { | ||
| 2809 | if (!(o instanceof Map.Entry)) | ||
| 2810 | return false; | ||
| 2811 | return s.remove(new AbstractMap.SimpleImmutableEntry | ||
| 2812 | <>((Map.Entry<?,?>)o)); | ||
| 2813 | } | ||
| 2814 | |||
| 2815 | public boolean removeAll(Collection<?> c) { | ||
| 2816 | return batchRemove(c, false); | ||
| 2817 | } | ||
| 2818 | public boolean retainAll(Collection<?> c) { | ||
| 2819 | return batchRemove(c, true); | ||
| 2820 | } | ||
| 2821 | private boolean batchRemove(Collection<?> c, boolean complement) { | ||
| 2822 | boolean modified = false; | ||
| 2823 | Iterator<Map.Entry<K,V>> it = iterator(); | ||
| 2824 | while (it.hasNext()) { | ||
| 2825 | if (c.contains(it.next()) != complement) { | ||
| 2826 | it.remove(); | ||
| 2827 | modified = true; | ||
| 2828 | } | ||
| 2829 | } | ||
| 2830 | return modified; | ||
| 2831 | } | ||
| 2832 | |||
| 2833 | public boolean equals(Object o) { | ||
| 2834 | if (o == this) | ||
| 2835 | return true; | ||
| 2836 | if (!(o instanceof Set)) | ||
| 2837 | return false; | ||
| 2838 | Set<?> that = (Set<?>) o; | ||
| 2839 | return that.size() == s.size() | ||
| 2840 | && containsAll(that); // Invokes safe containsAll() above | ||
| 2841 | } | ||
| 2842 | |||
| 2843 | static <K,V,T> CheckedEntry<K,V,T> checkedEntry(Map.Entry<K,V> e, | ||
| 2844 | Class<T> valueType) { | ||
| 2845 | return new CheckedEntry<>(e, valueType); | ||
| 2846 | } | ||
| 2847 | |||
| 2848 | /** | ||
| 2849 | * This "wrapper class" serves two purposes: it prevents | ||
| 2850 | * the client from modifying the backing Map, by short-circuiting | ||
| 2851 | * the setValue method, and it protects the backing Map against | ||
| 2852 | * an ill-behaved Map.Entry that attempts to modify another | ||
| 2853 | * Map.Entry when asked to perform an equality check. | ||
| 2854 | */ | ||
| 2855 | private static class CheckedEntry<K,V,T> implements Map.Entry<K,V> { | ||
| 2856 | private final Map.Entry<K, V> e; | ||
| 2857 | private final Class<T> valueType; | ||
| 2858 | |||
| 2859 | CheckedEntry(Map.Entry<K, V> e, Class<T> valueType) { | ||
| 2860 | this.e = e; | ||
| 2861 | this.valueType = valueType; | ||
| 2862 | } | ||
| 2863 | |||
| 2864 | public K getKey() { return e.getKey(); } | ||
| 2865 | public V getValue() { return e.getValue(); } | ||
| 2866 | public int hashCode() { return e.hashCode(); } | ||
| 2867 | public String toString() { return e.toString(); } | ||
| 2868 | |||
| 2869 | public V setValue(V value) { | ||
| 2870 | if (value != null && !valueType.isInstance(value)) | ||
| 2871 | throw new ClassCastException(badValueMsg(value)); | ||
| 2872 | return e.setValue(value); | ||
| 2873 | } | ||
| 2874 | |||
| 2875 | private String badValueMsg(Object value) { | ||
| 2876 | return "Attempt to insert " + value.getClass() + | ||
| 2877 | " value into map with value type " + valueType; | ||
| 2878 | } | ||
| 2879 | |||
| 2880 | public boolean equals(Object o) { | ||
| 2881 | if (o == this) | ||
| 2882 | return true; | ||
| 2883 | if (!(o instanceof Map.Entry)) | ||
| 2884 | return false; | ||
| 2885 | return e.equals(new AbstractMap.SimpleImmutableEntry | ||
| 2886 | <>((Map.Entry<?,?>)o)); | ||
| 2887 | } | ||
| 2888 | } | ||
| 2889 | } | ||
| 2890 | } | ||
| 2891 | |||
| 2892 | /** | ||
| 2893 | * Returns a dynamically typesafe view of the specified sorted map. | ||
| 2894 | * Any attempt to insert a mapping whose key or value have the wrong | ||
| 2895 | * type will result in an immediate {@link ClassCastException}. | ||
| 2896 | * Similarly, any attempt to modify the value currently associated with | ||
| 2897 | * a key will result in an immediate {@link ClassCastException}, | ||
| 2898 | * whether the modification is attempted directly through the map | ||
| 2899 | * itself, or through a {@link Map.Entry} instance obtained from the | ||
| 2900 | * map's {@link Map#entrySet() entry set} view. | ||
| 2901 | * | ||
| 2902 | * <p>Assuming a map contains no incorrectly typed keys or values | ||
| 2903 | * prior to the time a dynamically typesafe view is generated, and | ||
| 2904 | * that all subsequent access to the map takes place through the view | ||
| 2905 | * (or one of its collection views), it is <i>guaranteed</i> that the | ||
| 2906 | * map cannot contain an incorrectly typed key or value. | ||
| 2907 | * | ||
| 2908 | * <p>A discussion of the use of dynamically typesafe views may be | ||
| 2909 | * found in the documentation for the {@link #checkedCollection | ||
| 2910 | * checkedCollection} method. | ||
| 2911 | * | ||
| 2912 | * <p>The returned map will be serializable if the specified map is | ||
| 2913 | * serializable. | ||
| 2914 | * | ||
| 2915 | * <p>Since {@code null} is considered to be a value of any reference | ||
| 2916 | * type, the returned map permits insertion of null keys or values | ||
| 2917 | * whenever the backing map does. | ||
| 2918 | * | ||
| 2919 | * @param m the map for which a dynamically typesafe view is to be | ||
| 2920 | * returned | ||
| 2921 | * @param keyType the type of key that {@code m} is permitted to hold | ||
| 2922 | * @param valueType the type of value that {@code m} is permitted to hold | ||
| 2923 | * @return a dynamically typesafe view of the specified map | ||
| 2924 | * @since 1.5 | ||
| 2925 | */ | ||
| 2926 | public static <K,V> SortedMap<K,V> checkedSortedMap(SortedMap<K, V> m, | ||
| 2927 | Class<K> keyType, | ||
| 2928 | Class<V> valueType) { | ||
| 2929 | return new CheckedSortedMap<>(m, keyType, valueType); | ||
| 2930 | } | ||
| 2931 | |||
| 2932 | /** | ||
| 2933 | * @serial include | ||
| 2934 | */ | ||
| 2935 | static class CheckedSortedMap<K,V> extends CheckedMap<K,V> | ||
| 2936 | implements SortedMap<K,V>, Serializable | ||
| 2937 | { | ||
| 2938 | private static final long serialVersionUID = 1599671320688067438L; | ||
| 2939 | |||
| 2940 | private final SortedMap<K, V> sm; | ||
| 2941 | |||
| 2942 | CheckedSortedMap(SortedMap<K, V> m, | ||
| 2943 | Class<K> keyType, Class<V> valueType) { | ||
| 2944 | super(m, keyType, valueType); | ||
| 2945 | sm = m; | ||
| 2946 | } | ||
| 2947 | |||
| 2948 | public Comparator<? super K> comparator() { return sm.comparator(); } | ||
| 2949 | public K firstKey() { return sm.firstKey(); } | ||
| 2950 | public K lastKey() { return sm.lastKey(); } | ||
| 2951 | |||
| 2952 | public SortedMap<K,V> subMap(K fromKey, K toKey) { | ||
| 2953 | return checkedSortedMap(sm.subMap(fromKey, toKey), | ||
| 2954 | keyType, valueType); | ||
| 2955 | } | ||
| 2956 | public SortedMap<K,V> headMap(K toKey) { | ||
| 2957 | return checkedSortedMap(sm.headMap(toKey), keyType, valueType); | ||
| 2958 | } | ||
| 2959 | public SortedMap<K,V> tailMap(K fromKey) { | ||
| 2960 | return checkedSortedMap(sm.tailMap(fromKey), keyType, valueType); | ||
| 2961 | } | ||
| 2962 | } | ||
| 2963 | |||
| 2964 | // Empty collections | ||
| 2965 | |||
| 2966 | /** | ||
| 2967 | * Returns an iterator that has no elements. More precisely, | ||
| 2968 | * | ||
| 2969 | * <ul compact> | ||
| 2970 | * | ||
| 2971 | * <li>{@link Iterator#hasNext hasNext} always returns {@code | ||
| 2972 | * false}. | ||
| 2973 | * | ||
| 2974 | * <li>{@link Iterator#next next} always throws {@link | ||
| 2975 | * NoSuchElementException}. | ||
| 2976 | * | ||
| 2977 | * <li>{@link Iterator#remove remove} always throws {@link | ||
| 2978 | * IllegalStateException}. | ||
| 2979 | * | ||
| 2980 | * </ul> | ||
| 2981 | * | ||
| 2982 | * <p>Implementations of this method are permitted, but not | ||
| 2983 | * required, to return the same object from multiple invocations. | ||
| 2984 | * | ||
| 2985 | * @return an empty iterator | ||
| 2986 | * @since 1.7 | ||
| 2987 | */ | ||
| 2988 | @SuppressWarnings("unchecked") | ||
| 2989 | public static <T> Iterator<T> emptyIterator() { | ||
| 2990 | return (Iterator<T>) EmptyIterator.EMPTY_ITERATOR; | ||
| 2991 | } | ||
| 2992 | |||
| 2993 | private static class EmptyIterator<E> implements Iterator<E> { | ||
| 2994 | static final EmptyIterator<Object> EMPTY_ITERATOR | ||
| 2995 | = new EmptyIterator<>(); | ||
| 2996 | |||
| 2997 | public boolean hasNext() { return false; } | ||
| 2998 | public E next() { throw new NoSuchElementException(); } | ||
| 2999 | public void remove() { throw new IllegalStateException(); } | ||
| 3000 | } | ||
| 3001 | |||
| 3002 | /** | ||
| 3003 | * Returns a list iterator that has no elements. More precisely, | ||
| 3004 | * | ||
| 3005 | * <ul compact> | ||
| 3006 | * | ||
| 3007 | * <li>{@link Iterator#hasNext hasNext} and {@link | ||
| 3008 | * ListIterator#hasPrevious hasPrevious} always return {@code | ||
| 3009 | * false}. | ||
| 3010 | * | ||
| 3011 | * <li>{@link Iterator#next next} and {@link ListIterator#previous | ||
| 3012 | * previous} always throw {@link NoSuchElementException}. | ||
| 3013 | * | ||
| 3014 | * <li>{@link Iterator#remove remove} and {@link ListIterator#set | ||
| 3015 | * set} always throw {@link IllegalStateException}. | ||
| 3016 | * | ||
| 3017 | * <li>{@link ListIterator#add add} always throws {@link | ||
| 3018 | * UnsupportedOperationException}. | ||
| 3019 | * | ||
| 3020 | * <li>{@link ListIterator#nextIndex nextIndex} always returns | ||
| 3021 | * {@code 0} . | ||
| 3022 | * | ||
| 3023 | * <li>{@link ListIterator#previousIndex previousIndex} always | ||
| 3024 | * returns {@code -1}. | ||
| 3025 | * | ||
| 3026 | * </ul> | ||
| 3027 | * | ||
| 3028 | * <p>Implementations of this method are permitted, but not | ||
| 3029 | * required, to return the same object from multiple invocations. | ||
| 3030 | * | ||
| 3031 | * @return an empty list iterator | ||
| 3032 | * @since 1.7 | ||
| 3033 | */ | ||
| 3034 | @SuppressWarnings("unchecked") | ||
| 3035 | public static <T> ListIterator<T> emptyListIterator() { | ||
| 3036 | return (ListIterator<T>) EmptyListIterator.EMPTY_ITERATOR; | ||
| 3037 | } | ||
| 3038 | |||
| 3039 | private static class EmptyListIterator<E> | ||
| 3040 | extends EmptyIterator<E> | ||
| 3041 | implements ListIterator<E> | ||
| 3042 | { | ||
| 3043 | static final EmptyListIterator<Object> EMPTY_ITERATOR | ||
| 3044 | = new EmptyListIterator<>(); | ||
| 3045 | |||
| 3046 | public boolean hasPrevious() { return false; } | ||
| 3047 | public E previous() { throw new NoSuchElementException(); } | ||
| 3048 | public int nextIndex() { return 0; } | ||
| 3049 | public int previousIndex() { return -1; } | ||
| 3050 | public void set(E e) { throw new IllegalStateException(); } | ||
| 3051 | public void add(E e) { throw new UnsupportedOperationException(); } | ||
| 3052 | } | ||
| 3053 | |||
| 3054 | /** | ||
| 3055 | * Returns an enumeration that has no elements. More precisely, | ||
| 3056 | * | ||
| 3057 | * <ul compact> | ||
| 3058 | * | ||
| 3059 | * <li>{@link Enumeration#hasMoreElements hasMoreElements} always | ||
| 3060 | * returns {@code false}. | ||
| 3061 | * | ||
| 3062 | * <li> {@link Enumeration#nextElement nextElement} always throws | ||
| 3063 | * {@link NoSuchElementException}. | ||
| 3064 | * | ||
| 3065 | * </ul> | ||
| 3066 | * | ||
| 3067 | * <p>Implementations of this method are permitted, but not | ||
| 3068 | * required, to return the same object from multiple invocations. | ||
| 3069 | * | ||
| 3070 | * @return an empty enumeration | ||
| 3071 | * @since 1.7 | ||
| 3072 | */ | ||
| 3073 | @SuppressWarnings("unchecked") | ||
| 3074 | public static <T> Enumeration<T> emptyEnumeration() { | ||
| 3075 | return (Enumeration<T>) EmptyEnumeration.EMPTY_ENUMERATION; | ||
| 3076 | } | ||
| 3077 | |||
| 3078 | private static class EmptyEnumeration<E> implements Enumeration<E> { | ||
| 3079 | static final EmptyEnumeration<Object> EMPTY_ENUMERATION | ||
| 3080 | = new EmptyEnumeration<>(); | ||
| 3081 | |||
| 3082 | public boolean hasMoreElements() { return false; } | ||
| 3083 | public E nextElement() { throw new NoSuchElementException(); } | ||
| 3084 | } | ||
| 3085 | |||
| 3086 | /** | ||
| 3087 | * The empty set (immutable). This set is serializable. | ||
| 3088 | * | ||
| 3089 | * @see #emptySet() | ||
| 3090 | */ | ||
| 3091 | @SuppressWarnings("unchecked") | ||
| 3092 | public static final Set EMPTY_SET = new EmptySet<>(); | ||
| 3093 | |||
| 3094 | /** | ||
| 3095 | * Returns the empty set (immutable). This set is serializable. | ||
| 3096 | * Unlike the like-named field, this method is parameterized. | ||
| 3097 | * | ||
| 3098 | * <p>This example illustrates the type-safe way to obtain an empty set: | ||
| 3099 | * <pre> | ||
| 3100 | * Set<String> s = Collections.emptySet(); | ||
| 3101 | * </pre> | ||
| 3102 | * Implementation note: Implementations of this method need not | ||
| 3103 | * create a separate <tt>Set</tt> object for each call. Using this | ||
| 3104 | * method is likely to have comparable cost to using the like-named | ||
| 3105 | * field. (Unlike this method, the field does not provide type safety.) | ||
| 3106 | * | ||
| 3107 | * @see #EMPTY_SET | ||
| 3108 | * @since 1.5 | ||
| 3109 | */ | ||
| 3110 | @SuppressWarnings("unchecked") | ||
| 3111 | public static final <T> Set<T> emptySet() { | ||
| 3112 | return (Set<T>) EMPTY_SET; | ||
| 3113 | } | ||
| 3114 | |||
| 3115 | /** | ||
| 3116 | * @serial include | ||
| 3117 | */ | ||
| 3118 | private static class EmptySet<E> | ||
| 3119 | extends AbstractSet<E> | ||
| 3120 | implements Serializable | ||
| 3121 | { | ||
| 3122 | private static final long serialVersionUID = 1582296315990362920L; | ||
| 3123 | |||
| 3124 | public Iterator<E> iterator() { return emptyIterator(); } | ||
| 3125 | |||
| 3126 | public int size() {return 0;} | ||
| 3127 | public boolean isEmpty() {return true;} | ||
| 3128 | |||
| 3129 | public boolean contains(Object obj) {return false;} | ||
| 3130 | public boolean containsAll(Collection<?> c) { return c.isEmpty(); } | ||
| 3131 | |||
| 3132 | public Object[] toArray() { return new Object[0]; } | ||
| 3133 | |||
| 3134 | public <T> T[] toArray(T[] a) { | ||
| 3135 | if (a.length > 0) | ||
| 3136 | a[0] = null; | ||
| 3137 | return a; | ||
| 3138 | } | ||
| 3139 | |||
| 3140 | // Preserves singleton property | ||
| 3141 | private Object readResolve() { | ||
| 3142 | return EMPTY_SET; | ||
| 3143 | } | ||
| 3144 | } | ||
| 3145 | |||
| 3146 | /** | ||
| 3147 | * The empty list (immutable). This list is serializable. | ||
| 3148 | * | ||
| 3149 | * @see #emptyList() | ||
| 3150 | */ | ||
| 3151 | @SuppressWarnings("unchecked") | ||
| 3152 | public static final List EMPTY_LIST = new EmptyList<>(); | ||
| 3153 | |||
| 3154 | /** | ||
| 3155 | * Returns the empty list (immutable). This list is serializable. | ||
| 3156 | * | ||
| 3157 | * <p>This example illustrates the type-safe way to obtain an empty list: | ||
| 3158 | * <pre> | ||
| 3159 | * List<String> s = Collections.emptyList(); | ||
| 3160 | * </pre> | ||
| 3161 | * Implementation note: Implementations of this method need not | ||
| 3162 | * create a separate <tt>List</tt> object for each call. Using this | ||
| 3163 | * method is likely to have comparable cost to using the like-named | ||
| 3164 | * field. (Unlike this method, the field does not provide type safety.) | ||
| 3165 | * | ||
| 3166 | * @see #EMPTY_LIST | ||
| 3167 | * @since 1.5 | ||
| 3168 | */ | ||
| 3169 | @SuppressWarnings("unchecked") | ||
| 3170 | public static final <T> List<T> emptyList() { | ||
| 3171 | return (List<T>) EMPTY_LIST; | ||
| 3172 | } | ||
| 3173 | |||
| 3174 | /** | ||
| 3175 | * @serial include | ||
| 3176 | */ | ||
| 3177 | private static class EmptyList<E> | ||
| 3178 | extends AbstractList<E> | ||
| 3179 | implements RandomAccess, Serializable { | ||
| 3180 | private static final long serialVersionUID = 8842843931221139166L; | ||
| 3181 | |||
| 3182 | public Iterator<E> iterator() { | ||
| 3183 | return emptyIterator(); | ||
| 3184 | } | ||
| 3185 | public ListIterator<E> listIterator() { | ||
| 3186 | return emptyListIterator(); | ||
| 3187 | } | ||
| 3188 | |||
| 3189 | public int size() {return 0;} | ||
| 3190 | public boolean isEmpty() {return true;} | ||
| 3191 | |||
| 3192 | public boolean contains(Object obj) {return false;} | ||
| 3193 | public boolean containsAll(Collection<?> c) { return c.isEmpty(); } | ||
| 3194 | |||
| 3195 | public Object[] toArray() { return new Object[0]; } | ||
| 3196 | |||
| 3197 | public <T> T[] toArray(T[] a) { | ||
| 3198 | if (a.length > 0) | ||
| 3199 | a[0] = null; | ||
| 3200 | return a; | ||
| 3201 | } | ||
| 3202 | |||
| 3203 | public E get(int index) { | ||
| 3204 | throw new IndexOutOfBoundsException("Index: "+index); | ||
| 3205 | } | ||
| 3206 | |||
| 3207 | public boolean equals(Object o) { | ||
| 3208 | return (o instanceof List) && ((List<?>)o).isEmpty(); | ||
| 3209 | } | ||
| 3210 | |||
| 3211 | public int hashCode() { return 1; } | ||
| 3212 | |||
| 3213 | // Preserves singleton property | ||
| 3214 | private Object readResolve() { | ||
| 3215 | return EMPTY_LIST; | ||
| 3216 | } | ||
| 3217 | } | ||
| 3218 | |||
| 3219 | /** | ||
| 3220 | * The empty map (immutable). This map is serializable. | ||
| 3221 | * | ||
| 3222 | * @see #emptyMap() | ||
| 3223 | * @since 1.3 | ||
| 3224 | */ | ||
| 3225 | @SuppressWarnings("unchecked") | ||
| 3226 | public static final Map EMPTY_MAP = new EmptyMap<>(); | ||
| 3227 | |||
| 3228 | /** | ||
| 3229 | * Returns the empty map (immutable). This map is serializable. | ||
| 3230 | * | ||
| 3231 | * <p>This example illustrates the type-safe way to obtain an empty set: | ||
| 3232 | * <pre> | ||
| 3233 | * Map<String, Date> s = Collections.emptyMap(); | ||
| 3234 | * </pre> | ||
| 3235 | * Implementation note: Implementations of this method need not | ||
| 3236 | * create a separate <tt>Map</tt> object for each call. Using this | ||
| 3237 | * method is likely to have comparable cost to using the like-named | ||
| 3238 | * field. (Unlike this method, the field does not provide type safety.) | ||
| 3239 | * | ||
| 3240 | * @see #EMPTY_MAP | ||
| 3241 | * @since 1.5 | ||
| 3242 | */ | ||
| 3243 | @SuppressWarnings("unchecked") | ||
| 3244 | public static final <K,V> Map<K,V> emptyMap() { | ||
| 3245 | return (Map<K,V>) EMPTY_MAP; | ||
| 3246 | } | ||
| 3247 | |||
| 3248 | /** | ||
| 3249 | * @serial include | ||
| 3250 | */ | ||
| 3251 | private static class EmptyMap<K,V> | ||
| 3252 | extends AbstractMap<K,V> | ||
| 3253 | implements Serializable | ||
| 3254 | { | ||
| 3255 | private static final long serialVersionUID = 6428348081105594320L; | ||
| 3256 | |||
| 3257 | public int size() {return 0;} | ||
| 3258 | public boolean isEmpty() {return true;} | ||
| 3259 | public boolean containsKey(Object key) {return false;} | ||
| 3260 | public boolean containsValue(Object value) {return false;} | ||
| 3261 | public V get(Object key) {return null;} | ||
| 3262 | public Set<K> keySet() {return emptySet();} | ||
| 3263 | public Collection<V> values() {return emptySet();} | ||
| 3264 | public Set<Map.Entry<K,V>> entrySet() {return emptySet();} | ||
| 3265 | |||
| 3266 | public boolean equals(Object o) { | ||
| 3267 | return (o instanceof Map) && ((Map<?,?>)o).isEmpty(); | ||
| 3268 | } | ||
| 3269 | |||
| 3270 | public int hashCode() {return 0;} | ||
| 3271 | |||
| 3272 | // Preserves singleton property | ||
| 3273 | private Object readResolve() { | ||
| 3274 | return EMPTY_MAP; | ||
| 3275 | } | ||
| 3276 | } | ||
| 3277 | |||
| 3278 | // Singleton collections | ||
| 3279 | |||
| 3280 | /** | ||
| 3281 | * Returns an immutable set containing only the specified object. | ||
| 3282 | * The returned set is serializable. | ||
| 3283 | * | ||
| 3284 | * @param o the sole object to be stored in the returned set. | ||
| 3285 | * @return an immutable set containing only the specified object. | ||
| 3286 | */ | ||
| 3287 | public static <T> Set<T> singleton(T o) { | ||
| 3288 | return new SingletonSet<>(o); | ||
| 3289 | } | ||
| 3290 | |||
| 3291 | static <E> Iterator<E> singletonIterator(final E e) { | ||
| 3292 | return new Iterator<E>() { | ||
| 3293 | private boolean hasNext = true; | ||
| 3294 | public boolean hasNext() { | ||
| 3295 | return hasNext; | ||
| 3296 | } | ||
| 3297 | public E next() { | ||
| 3298 | if (hasNext) { | ||
| 3299 | hasNext = false; | ||
| 3300 | return e; | ||
| 3301 | } | ||
| 3302 | throw new NoSuchElementException(); | ||
| 3303 | } | ||
| 3304 | public void remove() { | ||
| 3305 | throw new UnsupportedOperationException(); | ||
| 3306 | } | ||
| 3307 | }; | ||
| 3308 | } | ||
| 3309 | |||
| 3310 | /** | ||
| 3311 | * @serial include | ||
| 3312 | */ | ||
| 3313 | private static class SingletonSet<E> | ||
| 3314 | extends AbstractSet<E> | ||
| 3315 | implements Serializable | ||
| 3316 | { | ||
| 3317 | private static final long serialVersionUID = 3193687207550431679L; | ||
| 3318 | |||
| 3319 | private final E element; | ||
| 3320 | |||
| 3321 | SingletonSet(E e) {element = e;} | ||
| 3322 | |||
| 3323 | public Iterator<E> iterator() { | ||
| 3324 | return singletonIterator(element); | ||
| 3325 | } | ||
| 3326 | |||
| 3327 | public int size() {return 1;} | ||
| 3328 | |||
| 3329 | public boolean contains(Object o) {return eq(o, element);} | ||
| 3330 | } | ||
| 3331 | |||
| 3332 | /** | ||
| 3333 | * Returns an immutable list containing only the specified object. | ||
| 3334 | * The returned list is serializable. | ||
| 3335 | * | ||
| 3336 | * @param o the sole object to be stored in the returned list. | ||
| 3337 | * @return an immutable list containing only the specified object. | ||
| 3338 | * @since 1.3 | ||
| 3339 | */ | ||
| 3340 | public static <T> List<T> singletonList(T o) { | ||
| 3341 | return new SingletonList<>(o); | ||
| 3342 | } | ||
| 3343 | |||
| 3344 | /** | ||
| 3345 | * @serial include | ||
| 3346 | */ | ||
| 3347 | private static class SingletonList<E> | ||
| 3348 | extends AbstractList<E> | ||
| 3349 | implements RandomAccess, Serializable { | ||
| 3350 | |||
| 3351 | private static final long serialVersionUID = 3093736618740652951L; | ||
| 3352 | |||
| 3353 | private final E element; | ||
| 3354 | |||
| 3355 | SingletonList(E obj) {element = obj;} | ||
| 3356 | |||
| 3357 | public Iterator<E> iterator() { | ||
| 3358 | return singletonIterator(element); | ||
| 3359 | } | ||
| 3360 | |||
| 3361 | public int size() {return 1;} | ||
| 3362 | |||
| 3363 | public boolean contains(Object obj) {return eq(obj, element);} | ||
| 3364 | |||
| 3365 | public E get(int index) { | ||
| 3366 | if (index != 0) | ||
| 3367 | throw new IndexOutOfBoundsException("Index: "+index+", Size: 1"); | ||
| 3368 | return element; | ||
| 3369 | } | ||
| 3370 | } | ||
| 3371 | |||
| 3372 | /** | ||
| 3373 | * Returns an immutable map, mapping only the specified key to the | ||
| 3374 | * specified value. The returned map is serializable. | ||
| 3375 | * | ||
| 3376 | * @param key the sole key to be stored in the returned map. | ||
| 3377 | * @param value the value to which the returned map maps <tt>key</tt>. | ||
| 3378 | * @return an immutable map containing only the specified key-value | ||
| 3379 | * mapping. | ||
| 3380 | * @since 1.3 | ||
| 3381 | */ | ||
| 3382 | public static <K,V> Map<K,V> singletonMap(K key, V value) { | ||
| 3383 | return new SingletonMap<>(key, value); | ||
| 3384 | } | ||
| 3385 | |||
| 3386 | /** | ||
| 3387 | * @serial include | ||
| 3388 | */ | ||
| 3389 | private static class SingletonMap<K,V> | ||
| 3390 | extends AbstractMap<K,V> | ||
| 3391 | implements Serializable { | ||
| 3392 | private static final long serialVersionUID = -6979724477215052911L; | ||
| 3393 | |||
| 3394 | private final K k; | ||
| 3395 | private final V v; | ||
| 3396 | |||
| 3397 | SingletonMap(K key, V value) { | ||
| 3398 | k = key; | ||
| 3399 | v = value; | ||
| 3400 | } | ||
| 3401 | |||
| 3402 | public int size() {return 1;} | ||
| 3403 | |||
| 3404 | public boolean isEmpty() {return false;} | ||
| 3405 | |||
| 3406 | public boolean containsKey(Object key) {return eq(key, k);} | ||
| 3407 | |||
| 3408 | public boolean containsValue(Object value) {return eq(value, v);} | ||
| 3409 | |||
| 3410 | public V get(Object key) {return (eq(key, k) ? v : null);} | ||
| 3411 | |||
| 3412 | private transient Set<K> keySet = null; | ||
| 3413 | private transient Set<Map.Entry<K,V>> entrySet = null; | ||
| 3414 | private transient Collection<V> values = null; | ||
| 3415 | |||
| 3416 | public Set<K> keySet() { | ||
| 3417 | if (keySet==null) | ||
| 3418 | keySet = singleton(k); | ||
| 3419 | return keySet; | ||
| 3420 | } | ||
| 3421 | |||
| 3422 | public Set<Map.Entry<K,V>> entrySet() { | ||
| 3423 | if (entrySet==null) | ||
| 3424 | entrySet = Collections.<Map.Entry<K,V>>singleton( | ||
| 3425 | new SimpleImmutableEntry<>(k, v)); | ||
| 3426 | return entrySet; | ||
| 3427 | } | ||
| 3428 | |||
| 3429 | public Collection<V> values() { | ||
| 3430 | if (values==null) | ||
| 3431 | values = singleton(v); | ||
| 3432 | return values; | ||
| 3433 | } | ||
| 3434 | |||
| 3435 | } | ||
| 3436 | |||
| 3437 | // Miscellaneous | ||
| 3438 | |||
| 3439 | /** | ||
| 3440 | * Returns an immutable list consisting of <tt>n</tt> copies of the | ||
| 3441 | * specified object. The newly allocated data object is tiny (it contains | ||
| 3442 | * a single reference to the data object). This method is useful in | ||
| 3443 | * combination with the <tt>List.addAll</tt> method to grow lists. | ||
| 3444 | * The returned list is serializable. | ||
| 3445 | * | ||
| 3446 | * @param n the number of elements in the returned list. | ||
| 3447 | * @param o the element to appear repeatedly in the returned list. | ||
| 3448 | * @return an immutable list consisting of <tt>n</tt> copies of the | ||
| 3449 | * specified object. | ||
| 3450 | * @throws IllegalArgumentException if {@code n < 0} | ||
| 3451 | * @see List#addAll(Collection) | ||
| 3452 | * @see List#addAll(int, Collection) | ||
| 3453 | */ | ||
| 3454 | public static <T> List<T> nCopies(int n, T o) { | ||
| 3455 | if (n < 0) | ||
| 3456 | throw new IllegalArgumentException("List length = " + n); | ||
| 3457 | return new CopiesList<>(n, o); | ||
| 3458 | } | ||
| 3459 | |||
| 3460 | /** | ||
| 3461 | * @serial include | ||
| 3462 | */ | ||
| 3463 | private static class CopiesList<E> | ||
| 3464 | extends AbstractList<E> | ||
| 3465 | implements RandomAccess, Serializable | ||
| 3466 | { | ||
| 3467 | private static final long serialVersionUID = 2739099268398711800L; | ||
| 3468 | |||
| 3469 | final int n; | ||
| 3470 | final E element; | ||
| 3471 | |||
| 3472 | CopiesList(int n, E e) { | ||
| 3473 | assert n >= 0; | ||
| 3474 | this.n = n; | ||
| 3475 | element = e; | ||
| 3476 | } | ||
| 3477 | |||
| 3478 | public int size() { | ||
| 3479 | return n; | ||
| 3480 | } | ||
| 3481 | |||
| 3482 | public boolean contains(Object obj) { | ||
| 3483 | return n != 0 && eq(obj, element); | ||
| 3484 | } | ||
| 3485 | |||
| 3486 | public int indexOf(Object o) { | ||
| 3487 | return contains(o) ? 0 : -1; | ||
| 3488 | } | ||
| 3489 | |||
| 3490 | public int lastIndexOf(Object o) { | ||
| 3491 | return contains(o) ? n - 1 : -1; | ||
| 3492 | } | ||
| 3493 | |||
| 3494 | public E get(int index) { | ||
| 3495 | if (index < 0 || index >= n) | ||
| 3496 | throw new IndexOutOfBoundsException("Index: "+index+ | ||
| 3497 | ", Size: "+n); | ||
| 3498 | return element; | ||
| 3499 | } | ||
| 3500 | |||
| 3501 | public Object[] toArray() { | ||
| 3502 | final Object[] a = new Object[n]; | ||
| 3503 | if (element != null) | ||
| 3504 | Arrays.fill(a, 0, n, element); | ||
| 3505 | return a; | ||
| 3506 | } | ||
| 3507 | |||
| 3508 | public <T> T[] toArray(T[] a) { | ||
| 3509 | final int n = this.n; | ||
| 3510 | if (a.length < n) { | ||
| 3511 | a = (T[])java.lang.reflect.Array | ||
| 3512 | .newInstance(a.getClass().getComponentType(), n); | ||
| 3513 | if (element != null) | ||
| 3514 | Arrays.fill(a, 0, n, element); | ||
| 3515 | } else { | ||
| 3516 | Arrays.fill(a, 0, n, element); | ||
| 3517 | if (a.length > n) | ||
| 3518 | a[n] = null; | ||
| 3519 | } | ||
| 3520 | return a; | ||
| 3521 | } | ||
| 3522 | |||
| 3523 | public List<E> subList(int fromIndex, int toIndex) { | ||
| 3524 | if (fromIndex < 0) | ||
| 3525 | throw new IndexOutOfBoundsException("fromIndex = " + fromIndex); | ||
| 3526 | if (toIndex > n) | ||
| 3527 | throw new IndexOutOfBoundsException("toIndex = " + toIndex); | ||
| 3528 | if (fromIndex > toIndex) | ||
| 3529 | throw new IllegalArgumentException("fromIndex(" + fromIndex + | ||
| 3530 | ") > toIndex(" + toIndex + ")"); | ||
| 3531 | return new CopiesList<>(toIndex - fromIndex, element); | ||
| 3532 | } | ||
| 3533 | } | ||
| 3534 | |||
| 3535 | /** | ||
| 3536 | * Returns a comparator that imposes the reverse of the <em>natural | ||
| 3537 | * ordering</em> on a collection of objects that implement the | ||
| 3538 | * {@code Comparable} interface. (The natural ordering is the ordering | ||
| 3539 | * imposed by the objects' own {@code compareTo} method.) This enables a | ||
| 3540 | * simple idiom for sorting (or maintaining) collections (or arrays) of | ||
| 3541 | * objects that implement the {@code Comparable} interface in | ||
| 3542 | * reverse-natural-order. For example, suppose {@code a} is an array of | ||
| 3543 | * strings. Then: <pre> | ||
| 3544 | * Arrays.sort(a, Collections.reverseOrder()); | ||
| 3545 | * </pre> sorts the array in reverse-lexicographic (alphabetical) order.<p> | ||
| 3546 | * | ||
| 3547 | * The returned comparator is serializable. | ||
| 3548 | * | ||
| 3549 | * @return A comparator that imposes the reverse of the <i>natural | ||
| 3550 | * ordering</i> on a collection of objects that implement | ||
| 3551 | * the <tt>Comparable</tt> interface. | ||
| 3552 | * @see Comparable | ||
| 3553 | */ | ||
| 3554 | public static <T> Comparator<T> reverseOrder() { | ||
| 3555 | return (Comparator<T>) ReverseComparator.REVERSE_ORDER; | ||
| 3556 | } | ||
| 3557 | |||
| 3558 | /** | ||
| 3559 | * @serial include | ||
| 3560 | */ | ||
| 3561 | private static class ReverseComparator | ||
| 3562 | implements Comparator<Comparable<Object>>, Serializable { | ||
| 3563 | |||
| 3564 | private static final long serialVersionUID = 7207038068494060240L; | ||
| 3565 | |||
| 3566 | static final ReverseComparator REVERSE_ORDER | ||
| 3567 | = new ReverseComparator(); | ||
| 3568 | |||
| 3569 | public int compare(Comparable<Object> c1, Comparable<Object> c2) { | ||
| 3570 | return c2.compareTo(c1); | ||
| 3571 | } | ||
| 3572 | |||
| 3573 | private Object readResolve() { return reverseOrder(); } | ||
| 3574 | } | ||
| 3575 | |||
| 3576 | /** | ||
| 3577 | * Returns a comparator that imposes the reverse ordering of the specified | ||
| 3578 | * comparator. If the specified comparator is {@code null}, this method is | ||
| 3579 | * equivalent to {@link #reverseOrder()} (in other words, it returns a | ||
| 3580 | * comparator that imposes the reverse of the <em>natural ordering</em> on | ||
| 3581 | * a collection of objects that implement the Comparable interface). | ||
| 3582 | * | ||
| 3583 | * <p>The returned comparator is serializable (assuming the specified | ||
| 3584 | * comparator is also serializable or {@code null}). | ||
| 3585 | * | ||
| 3586 | * @param cmp a comparator who's ordering is to be reversed by the returned | ||
| 3587 | * comparator or {@code null} | ||
| 3588 | * @return A comparator that imposes the reverse ordering of the | ||
| 3589 | * specified comparator. | ||
| 3590 | * @since 1.5 | ||
| 3591 | */ | ||
| 3592 | public static <T> Comparator<T> reverseOrder(Comparator<T> cmp) { | ||
| 3593 | if (cmp == null) | ||
| 3594 | return reverseOrder(); | ||
| 3595 | |||
| 3596 | if (cmp instanceof ReverseComparator2) | ||
| 3597 | return ((ReverseComparator2<T>)cmp).cmp; | ||
| 3598 | |||
| 3599 | return new ReverseComparator2<>(cmp); | ||
| 3600 | } | ||
| 3601 | |||
| 3602 | /** | ||
| 3603 | * @serial include | ||
| 3604 | */ | ||
| 3605 | private static class ReverseComparator2<T> implements Comparator<T>, | ||
| 3606 | Serializable | ||
| 3607 | { | ||
| 3608 | private static final long serialVersionUID = 4374092139857L; | ||
| 3609 | |||
| 3610 | /** | ||
| 3611 | * The comparator specified in the static factory. This will never | ||
| 3612 | * be null, as the static factory returns a ReverseComparator | ||
| 3613 | * instance if its argument is null. | ||
| 3614 | * | ||
| 3615 | * @serial | ||
| 3616 | */ | ||
| 3617 | final Comparator<T> cmp; | ||
| 3618 | |||
| 3619 | ReverseComparator2(Comparator<T> cmp) { | ||
| 3620 | assert cmp != null; | ||
| 3621 | this.cmp = cmp; | ||
| 3622 | } | ||
| 3623 | |||
| 3624 | public int compare(T t1, T t2) { | ||
| 3625 | return cmp.compare(t2, t1); | ||
| 3626 | } | ||
| 3627 | |||
| 3628 | public boolean equals(Object o) { | ||
| 3629 | return (o == this) || | ||
| 3630 | (o instanceof ReverseComparator2 && | ||
| 3631 | cmp.equals(((ReverseComparator2)o).cmp)); | ||
| 3632 | } | ||
| 3633 | |||
| 3634 | public int hashCode() { | ||
| 3635 | return cmp.hashCode() ^ Integer.MIN_VALUE; | ||
| 3636 | } | ||
| 3637 | } | ||
| 3638 | |||
| 3639 | /** | ||
| 3640 | * Returns an enumeration over the specified collection. This provides | ||
| 3641 | * interoperability with legacy APIs that require an enumeration | ||
| 3642 | * as input. | ||
| 3643 | * | ||
| 3644 | * @param c the collection for which an enumeration is to be returned. | ||
| 3645 | * @return an enumeration over the specified collection. | ||
| 3646 | * @see Enumeration | ||
| 3647 | */ | ||
| 3648 | public static <T> Enumeration<T> enumeration(final Collection<T> c) { | ||
| 3649 | return new Enumeration<T>() { | ||
| 3650 | private final Iterator<T> i = c.iterator(); | ||
| 3651 | |||
| 3652 | public boolean hasMoreElements() { | ||
| 3653 | return i.hasNext(); | ||
| 3654 | } | ||
| 3655 | |||
| 3656 | public T nextElement() { | ||
| 3657 | return i.next(); | ||
| 3658 | } | ||
| 3659 | }; | ||
| 3660 | } | ||
| 3661 | |||
| 3662 | /** | ||
| 3663 | * Returns an array list containing the elements returned by the | ||
| 3664 | * specified enumeration in the order they are returned by the | ||
| 3665 | * enumeration. This method provides interoperability between | ||
| 3666 | * legacy APIs that return enumerations and new APIs that require | ||
| 3667 | * collections. | ||
| 3668 | * | ||
| 3669 | * @param e enumeration providing elements for the returned | ||
| 3670 | * array list | ||
| 3671 | * @return an array list containing the elements returned | ||
| 3672 | * by the specified enumeration. | ||
| 3673 | * @since 1.4 | ||
| 3674 | * @see Enumeration | ||
| 3675 | * @see ArrayList | ||
| 3676 | */ | ||
| 3677 | public static <T> ArrayList<T> list(Enumeration<T> e) { | ||
| 3678 | ArrayList<T> l = new ArrayList<>(); | ||
| 3679 | while (e.hasMoreElements()) | ||
| 3680 | l.add(e.nextElement()); | ||
| 3681 | return l; | ||
| 3682 | } | ||
| 3683 | |||
| 3684 | /** | ||
| 3685 | * Returns true if the specified arguments are equal, or both null. | ||
| 3686 | */ | ||
| 3687 | static boolean eq(Object o1, Object o2) { | ||
| 3688 | return o1==null ? o2==null : o1.equals(o2); | ||
| 3689 | } | ||
| 3690 | |||
| 3691 | /** | ||
| 3692 | * Returns the number of elements in the specified collection equal to the | ||
| 3693 | * specified object. More formally, returns the number of elements | ||
| 3694 | * <tt>e</tt> in the collection such that | ||
| 3695 | * <tt>(o == null ? e == null : o.equals(e))</tt>. | ||
| 3696 | * | ||
| 3697 | * @param c the collection in which to determine the frequency | ||
| 3698 | * of <tt>o</tt> | ||
| 3699 | * @param o the object whose frequency is to be determined | ||
| 3700 | * @throws NullPointerException if <tt>c</tt> is null | ||
| 3701 | * @since 1.5 | ||
| 3702 | */ | ||
| 3703 | public static int frequency(Collection<?> c, Object o) { | ||
| 3704 | int result = 0; | ||
| 3705 | if (o == null) { | ||
| 3706 | for (Object e : c) | ||
| 3707 | if (e == null) | ||
| 3708 | result++; | ||
| 3709 | } else { | ||
| 3710 | for (Object e : c) | ||
| 3711 | if (o.equals(e)) | ||
| 3712 | result++; | ||
| 3713 | } | ||
| 3714 | return result; | ||
| 3715 | } | ||
| 3716 | |||
| 3717 | /** | ||
| 3718 | * Returns {@code true} if the two specified collections have no | ||
| 3719 | * elements in common. | ||
| 3720 | * | ||
| 3721 | * <p>Care must be exercised if this method is used on collections that | ||
| 3722 | * do not comply with the general contract for {@code Collection}. | ||
| 3723 | * Implementations may elect to iterate over either collection and test | ||
| 3724 | * for containment in the other collection (or to perform any equivalent | ||
| 3725 | * computation). If either collection uses a nonstandard equality test | ||
| 3726 | * (as does a {@link SortedSet} whose ordering is not <em>compatible with | ||
| 3727 | * equals</em>, or the key set of an {@link IdentityHashMap}), both | ||
| 3728 | * collections must use the same nonstandard equality test, or the | ||
| 3729 | * result of this method is undefined. | ||
| 3730 | * | ||
| 3731 | * <p>Care must also be exercised when using collections that have | ||
| 3732 | * restrictions on the elements that they may contain. Collection | ||
| 3733 | * implementations are allowed to throw exceptions for any operation | ||
| 3734 | * involving elements they deem ineligible. For absolute safety the | ||
| 3735 | * specified collections should contain only elements which are | ||
| 3736 | * eligible elements for both collections. | ||
| 3737 | * | ||
| 3738 | * <p>Note that it is permissible to pass the same collection in both | ||
| 3739 | * parameters, in which case the method will return {@code true} if and | ||
| 3740 | * only if the collection is empty. | ||
| 3741 | * | ||
| 3742 | * @param c1 a collection | ||
| 3743 | * @param c2 a collection | ||
| 3744 | * @return {@code true} if the two specified collections have no | ||
| 3745 | * elements in common. | ||
| 3746 | * @throws NullPointerException if either collection is {@code null}. | ||
| 3747 | * @throws NullPointerException if one collection contains a {@code null} | ||
| 3748 | * element and {@code null} is not an eligible element for the other collection. | ||
| 3749 | * (<a href="Collection.html#optional-restrictions">optional</a>) | ||
| 3750 | * @throws ClassCastException if one collection contains an element that is | ||
| 3751 | * of a type which is ineligible for the other collection. | ||
| 3752 | * (<a href="Collection.html#optional-restrictions">optional</a>) | ||
| 3753 | * @since 1.5 | ||
| 3754 | */ | ||
| 3755 | public static boolean disjoint(Collection<?> c1, Collection<?> c2) { | ||
| 3756 | // The collection to be used for contains(). Preference is given to | ||
| 3757 | // the collection who's contains() has lower O() complexity. | ||
| 3758 | Collection<?> contains = c2; | ||
| 3759 | // The collection to be iterated. If the collections' contains() impl | ||
| 3760 | // are of different O() complexity, the collection with slower | ||
| 3761 | // contains() will be used for iteration. For collections who's | ||
| 3762 | // contains() are of the same complexity then best performance is | ||
| 3763 | // achieved by iterating the smaller collection. | ||
| 3764 | Collection<?> iterate = c1; | ||
| 3765 | |||
| 3766 | // Performance optimization cases. The heuristics: | ||
| 3767 | // 1. Generally iterate over c1. | ||
| 3768 | // 2. If c1 is a Set then iterate over c2. | ||
| 3769 | // 3. If either collection is empty then result is always true. | ||
| 3770 | // 4. Iterate over the smaller Collection. | ||
| 3771 | if (c1 instanceof Set) { | ||
| 3772 | // Use c1 for contains as a Set's contains() is expected to perform | ||
| 3773 | // better than O(N/2) | ||
| 3774 | iterate = c2; | ||
| 3775 | contains = c1; | ||
| 3776 | } else if (!(c2 instanceof Set)) { | ||
| 3777 | // Both are mere Collections. Iterate over smaller collection. | ||
| 3778 | // Example: If c1 contains 3 elements and c2 contains 50 elements and | ||
| 3779 | // assuming contains() requires ceiling(N/2) comparisons then | ||
| 3780 | // checking for all c1 elements in c2 would require 75 comparisons | ||
| 3781 | // (3 * ceiling(50/2)) vs. checking all c2 elements in c1 requiring | ||
| 3782 | // 100 comparisons (50 * ceiling(3/2)). | ||
| 3783 | int c1size = c1.size(); | ||
| 3784 | int c2size = c2.size(); | ||
| 3785 | if (c1size == 0 || c2size == 0) { | ||
| 3786 | // At least one collection is empty. Nothing will match. | ||
| 3787 | return true; | ||
| 3788 | } | ||
| 3789 | |||
| 3790 | if (c1size > c2size) { | ||
| 3791 | iterate = c2; | ||
| 3792 | contains = c1; | ||
| 3793 | } | ||
| 3794 | } | ||
| 3795 | |||
| 3796 | for (Object e : iterate) { | ||
| 3797 | if (contains.contains(e)) { | ||
| 3798 | // Found a common element. Collections are not disjoint. | ||
| 3799 | return false; | ||
| 3800 | } | ||
| 3801 | } | ||
| 3802 | |||
| 3803 | // No common elements were found. | ||
| 3804 | return true; | ||
| 3805 | } | ||
| 3806 | |||
| 3807 | /** | ||
| 3808 | * Adds all of the specified elements to the specified collection. | ||
| 3809 | * Elements to be added may be specified individually or as an array. | ||
| 3810 | * The behavior of this convenience method is identical to that of | ||
| 3811 | * <tt>c.addAll(Arrays.asList(elements))</tt>, but this method is likely | ||
| 3812 | * to run significantly faster under most implementations. | ||
| 3813 | * | ||
| 3814 | * <p>When elements are specified individually, this method provides a | ||
| 3815 | * convenient way to add a few elements to an existing collection: | ||
| 3816 | * <pre> | ||
| 3817 | * Collections.addAll(flavors, "Peaches 'n Plutonium", "Rocky Racoon"); | ||
| 3818 | * </pre> | ||
| 3819 | * | ||
| 3820 | * @param c the collection into which <tt>elements</tt> are to be inserted | ||
| 3821 | * @param elements the elements to insert into <tt>c</tt> | ||
| 3822 | * @return <tt>true</tt> if the collection changed as a result of the call | ||
| 3823 | * @throws UnsupportedOperationException if <tt>c</tt> does not support | ||
| 3824 | * the <tt>add</tt> operation | ||
| 3825 | * @throws NullPointerException if <tt>elements</tt> contains one or more | ||
| 3826 | * null values and <tt>c</tt> does not permit null elements, or | ||
| 3827 | * if <tt>c</tt> or <tt>elements</tt> are <tt>null</tt> | ||
| 3828 | * @throws IllegalArgumentException if some property of a value in | ||
| 3829 | * <tt>elements</tt> prevents it from being added to <tt>c</tt> | ||
| 3830 | * @see Collection#addAll(Collection) | ||
| 3831 | * @since 1.5 | ||
| 3832 | */ | ||
| 3833 | @SafeVarargs | ||
| 3834 | public static <T> boolean addAll(Collection<? super T> c, T... elements) { | ||
| 3835 | boolean result = false; | ||
| 3836 | for (T element : elements) | ||
| 3837 | result |= c.add(element); | ||
| 3838 | return result; | ||
| 3839 | } | ||
| 3840 | |||
| 3841 | /** | ||
| 3842 | * Returns a set backed by the specified map. The resulting set displays | ||
| 3843 | * the same ordering, concurrency, and performance characteristics as the | ||
| 3844 | * backing map. In essence, this factory method provides a {@link Set} | ||
| 3845 | * implementation corresponding to any {@link Map} implementation. There | ||
| 3846 | * is no need to use this method on a {@link Map} implementation that | ||
| 3847 | * already has a corresponding {@link Set} implementation (such as {@link | ||
| 3848 | * HashMap} or {@link TreeMap}). | ||
| 3849 | * | ||
| 3850 | * <p>Each method invocation on the set returned by this method results in | ||
| 3851 | * exactly one method invocation on the backing map or its <tt>keySet</tt> | ||
| 3852 | * view, with one exception. The <tt>addAll</tt> method is implemented | ||
| 3853 | * as a sequence of <tt>put</tt> invocations on the backing map. | ||
| 3854 | * | ||
| 3855 | * <p>The specified map must be empty at the time this method is invoked, | ||
| 3856 | * and should not be accessed directly after this method returns. These | ||
| 3857 | * conditions are ensured if the map is created empty, passed directly | ||
| 3858 | * to this method, and no reference to the map is retained, as illustrated | ||
| 3859 | * in the following code fragment: | ||
| 3860 | * <pre> | ||
| 3861 | * Set<Object> weakHashSet = Collections.newSetFromMap( | ||
| 3862 | * new WeakHashMap<Object, Boolean>()); | ||
| 3863 | * </pre> | ||
| 3864 | * | ||
| 3865 | * @param map the backing map | ||
| 3866 | * @return the set backed by the map | ||
| 3867 | * @throws IllegalArgumentException if <tt>map</tt> is not empty | ||
| 3868 | * @since 1.6 | ||
| 3869 | */ | ||
| 3870 | public static <E> Set<E> newSetFromMap(Map<E, Boolean> map) { | ||
| 3871 | return new SetFromMap<>(map); | ||
| 3872 | } | ||
| 3873 | |||
| 3874 | /** | ||
| 3875 | * @serial include | ||
| 3876 | */ | ||
| 3877 | private static class SetFromMap<E> extends AbstractSet<E> | ||
| 3878 | implements Set<E>, Serializable | ||
| 3879 | { | ||
| 3880 | private final Map<E, Boolean> m; // The backing map | ||
| 3881 | private transient Set<E> s; // Its keySet | ||
| 3882 | |||
| 3883 | SetFromMap(Map<E, Boolean> map) { | ||
| 3884 | if (!map.isEmpty()) | ||
| 3885 | throw new IllegalArgumentException("Map is non-empty"); | ||
| 3886 | m = map; | ||
| 3887 | s = map.keySet(); | ||
| 3888 | } | ||
| 3889 | |||
| 3890 | public void clear() { m.clear(); } | ||
| 3891 | public int size() { return m.size(); } | ||
| 3892 | public boolean isEmpty() { return m.isEmpty(); } | ||
| 3893 | public boolean contains(Object o) { return m.containsKey(o); } | ||
| 3894 | public boolean remove(Object o) { return m.remove(o) != null; } | ||
| 3895 | public boolean add(E e) { return m.put(e, Boolean.TRUE) == null; } | ||
| 3896 | public Iterator<E> iterator() { return s.iterator(); } | ||
| 3897 | public Object[] toArray() { return s.toArray(); } | ||
| 3898 | public <T> T[] toArray(T[] a) { return s.toArray(a); } | ||
| 3899 | public String toString() { return s.toString(); } | ||
| 3900 | public int hashCode() { return s.hashCode(); } | ||
| 3901 | public boolean equals(Object o) { return o == this || s.equals(o); } | ||
| 3902 | public boolean containsAll(Collection<?> c) {return s.containsAll(c);} | ||
| 3903 | public boolean removeAll(Collection<?> c) {return s.removeAll(c);} | ||
| 3904 | public boolean retainAll(Collection<?> c) {return s.retainAll(c);} | ||
| 3905 | // addAll is the only inherited implementation | ||
| 3906 | |||
| 3907 | private static final long serialVersionUID = 2454657854757543876L; | ||
| 3908 | |||
| 3909 | private void readObject(java.io.ObjectInputStream stream) | ||
| 3910 | throws IOException, ClassNotFoundException | ||
| 3911 | { | ||
| 3912 | stream.defaultReadObject(); | ||
| 3913 | s = m.keySet(); | ||
| 3914 | } | ||
| 3915 | } | ||
| 3916 | |||
| 3917 | /** | ||
| 3918 | * Returns a view of a {@link Deque} as a Last-in-first-out (Lifo) | ||
| 3919 | * {@link Queue}. Method <tt>add</tt> is mapped to <tt>push</tt>, | ||
| 3920 | * <tt>remove</tt> is mapped to <tt>pop</tt> and so on. This | ||
| 3921 | * view can be useful when you would like to use a method | ||
| 3922 | * requiring a <tt>Queue</tt> but you need Lifo ordering. | ||
| 3923 | * | ||
| 3924 | * <p>Each method invocation on the queue returned by this method | ||
| 3925 | * results in exactly one method invocation on the backing deque, with | ||
| 3926 | * one exception. The {@link Queue#addAll addAll} method is | ||
| 3927 | * implemented as a sequence of {@link Deque#addFirst addFirst} | ||
| 3928 | * invocations on the backing deque. | ||
| 3929 | * | ||
| 3930 | * @param deque the deque | ||
| 3931 | * @return the queue | ||
| 3932 | * @since 1.6 | ||
| 3933 | */ | ||
| 3934 | public static <T> Queue<T> asLifoQueue(Deque<T> deque) { | ||
| 3935 | return new AsLIFOQueue<>(deque); | ||
| 3936 | } | ||
| 3937 | |||
| 3938 | /** | ||
| 3939 | * @serial include | ||
| 3940 | */ | ||
| 3941 | static class AsLIFOQueue<E> extends AbstractQueue<E> | ||
| 3942 | implements Queue<E>, Serializable { | ||
| 3943 | private static final long serialVersionUID = 1802017725587941708L; | ||
| 3944 | private final Deque<E> q; | ||
| 3945 | AsLIFOQueue(Deque<E> q) { this.q = q; } | ||
| 3946 | public boolean add(E e) { q.addFirst(e); return true; } | ||
| 3947 | public boolean offer(E e) { return q.offerFirst(e); } | ||
| 3948 | public E poll() { return q.pollFirst(); } | ||
| 3949 | public E remove() { return q.removeFirst(); } | ||
| 3950 | public E peek() { return q.peekFirst(); } | ||
| 3951 | public E element() { return q.getFirst(); } | ||
| 3952 | public void clear() { q.clear(); } | ||
| 3953 | public int size() { return q.size(); } | ||
| 3954 | public boolean isEmpty() { return q.isEmpty(); } | ||
| 3955 | public boolean contains(Object o) { return q.contains(o); } | ||
| 3956 | public boolean remove(Object o) { return q.remove(o); } | ||
| 3957 | public Iterator<E> iterator() { return q.iterator(); } | ||
| 3958 | public Object[] toArray() { return q.toArray(); } | ||
| 3959 | public <T> T[] toArray(T[] a) { return q.toArray(a); } | ||
| 3960 | public String toString() { return q.toString(); } | ||
| 3961 | public boolean containsAll(Collection<?> c) {return q.containsAll(c);} | ||
| 3962 | public boolean removeAll(Collection<?> c) {return q.removeAll(c);} | ||
| 3963 | public boolean retainAll(Collection<?> c) {return q.retainAll(c);} | ||
| 3964 | // We use inherited addAll; forwarding addAll would be wrong | ||
| 3965 | } | ||
| 3966 | } | ||
Binary file not shown.
| @@ -0,0 +1,895 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2009 Google Inc. All Rights Reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package java.util; | ||
| 27 | |||
| 28 | /** | ||
| 29 | * This is a near duplicate of {@link TimSort}, modified for use with | ||
| 30 | * arrays of objects that implement {@link Comparable}, instead of using | ||
| 31 | * explicit comparators. | ||
| 32 | * | ||
| 33 | * <p>If you are using an optimizing VM, you may find that ComparableTimSort | ||
| 34 | * offers no performance benefit over TimSort in conjunction with a | ||
| 35 | * comparator that simply returns {@code ((Comparable)first).compareTo(Second)}. | ||
| 36 | * If this is the case, you are better off deleting ComparableTimSort to | ||
| 37 | * eliminate the code duplication. (See Arrays.java for details.) | ||
| 38 | * | ||
| 39 | * @author Josh Bloch | ||
| 40 | */ | ||
| 41 | class ComparableTimSort { | ||
| 42 | /** | ||
| 43 | * This is the minimum sized sequence that will be merged. Shorter | ||
| 44 | * sequences will be lengthened by calling binarySort. If the entire | ||
| 45 | * array is less than this length, no merges will be performed. | ||
| 46 | * | ||
| 47 | * This constant should be a power of two. It was 64 in Tim Peter's C | ||
| 48 | * implementation, but 32 was empirically determined to work better in | ||
| 49 | * this implementation. In the unlikely event that you set this constant | ||
| 50 | * to be a number that's not a power of two, you'll need to change the | ||
| 51 | * {@link #minRunLength} computation. | ||
| 52 | * | ||
| 53 | * If you decrease this constant, you must change the stackLen | ||
| 54 | * computation in the TimSort constructor, or you risk an | ||
| 55 | * ArrayOutOfBounds exception. See listsort.txt for a discussion | ||
| 56 | * of the minimum stack length required as a function of the length | ||
| 57 | * of the array being sorted and the minimum merge sequence length. | ||
| 58 | */ | ||
| 59 | private static final int MIN_MERGE = 32; | ||
| 60 | |||
| 61 | /** | ||
| 62 | * The array being sorted. | ||
| 63 | */ | ||
| 64 | private final Object[] a; | ||
| 65 | |||
| 66 | /** | ||
| 67 | * When we get into galloping mode, we stay there until both runs win less | ||
| 68 | * often than MIN_GALLOP consecutive times. | ||
| 69 | */ | ||
| 70 | private static final int MIN_GALLOP = 7; | ||
| 71 | |||
| 72 | /** | ||
| 73 | * This controls when we get *into* galloping mode. It is initialized | ||
| 74 | * to MIN_GALLOP. The mergeLo and mergeHi methods nudge it higher for | ||
| 75 | * random data, and lower for highly structured data. | ||
| 76 | */ | ||
| 77 | private int minGallop = MIN_GALLOP; | ||
| 78 | |||
| 79 | /** | ||
| 80 | * Maximum initial size of tmp array, which is used for merging. The array | ||
| 81 | * can grow to accommodate demand. | ||
| 82 | * | ||
| 83 | * Unlike Tim's original C version, we do not allocate this much storage | ||
| 84 | * when sorting smaller arrays. This change was required for performance. | ||
| 85 | */ | ||
| 86 | private static final int INITIAL_TMP_STORAGE_LENGTH = 256; | ||
| 87 | |||
| 88 | /** | ||
| 89 | * Temp storage for merges. | ||
| 90 | */ | ||
| 91 | private Object[] tmp; | ||
| 92 | |||
| 93 | /** | ||
| 94 | * A stack of pending runs yet to be merged. Run i starts at | ||
| 95 | * address base[i] and extends for len[i] elements. It's always | ||
| 96 | * true (so long as the indices are in bounds) that: | ||
| 97 | * | ||
| 98 | * runBase[i] + runLen[i] == runBase[i + 1] | ||
| 99 | * | ||
| 100 | * so we could cut the storage for this, but it's a minor amount, | ||
| 101 | * and keeping all the info explicit simplifies the code. | ||
| 102 | */ | ||
| 103 | private int stackSize = 0; // Number of pending runs on stack | ||
| 104 | private final int[] runBase; | ||
| 105 | private final int[] runLen; | ||
| 106 | |||
| 107 | /** | ||
| 108 | * Creates a TimSort instance to maintain the state of an ongoing sort. | ||
| 109 | * | ||
| 110 | * @param a the array to be sorted | ||
| 111 | */ | ||
| 112 | private ComparableTimSort(Object[] a) { | ||
| 113 | this.a = a; | ||
| 114 | |||
| 115 | // Allocate temp storage (which may be increased later if necessary) | ||
| 116 | int len = a.length; | ||
| 117 | @SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"}) | ||
| 118 | Object[] newArray = new Object[len < 2 * INITIAL_TMP_STORAGE_LENGTH ? | ||
| 119 | len >>> 1 : INITIAL_TMP_STORAGE_LENGTH]; | ||
| 120 | tmp = newArray; | ||
| 121 | |||
| 122 | /* | ||
| 123 | * Allocate runs-to-be-merged stack (which cannot be expanded). The | ||
| 124 | * stack length requirements are described in listsort.txt. The C | ||
| 125 | * version always uses the same stack length (85), but this was | ||
| 126 | * measured to be too expensive when sorting "mid-sized" arrays (e.g., | ||
| 127 | * 100 elements) in Java. Therefore, we use smaller (but sufficiently | ||
| 128 | * large) stack lengths for smaller arrays. The "magic numbers" in the | ||
| 129 | * computation below must be changed if MIN_MERGE is decreased. See | ||
| 130 | * the MIN_MERGE declaration above for more information. | ||
| 131 | */ | ||
| 132 | int stackLen = (len < 120 ? 5 : | ||
| 133 | len < 1542 ? 10 : | ||
| 134 | len < 119151 ? 19 : 40); | ||
| 135 | runBase = new int[stackLen]; | ||
| 136 | runLen = new int[stackLen]; | ||
| 137 | } | ||
| 138 | |||
| 139 | /* | ||
| 140 | * The next two methods (which are package private and static) constitute | ||
| 141 | * the entire API of this class. Each of these methods obeys the contract | ||
| 142 | * of the public method with the same signature in java.util.Arrays. | ||
| 143 | */ | ||
| 144 | |||
| 145 | static void sort(Object[] a) { | ||
| 146 | sort(a, 0, a.length); | ||
| 147 | } | ||
| 148 | |||
| 149 | static void sort(Object[] a, int lo, int hi) { | ||
| 150 | rangeCheck(a.length, lo, hi); | ||
| 151 | int nRemaining = hi - lo; | ||
| 152 | if (nRemaining < 2) | ||
| 153 | return; // Arrays of size 0 and 1 are always sorted | ||
| 154 | |||
| 155 | // If array is small, do a "mini-TimSort" with no merges | ||
| 156 | if (nRemaining < MIN_MERGE) { | ||
| 157 | int initRunLen = countRunAndMakeAscending(a, lo, hi); | ||
| 158 | binarySort(a, lo, hi, lo + initRunLen); | ||
| 159 | return; | ||
| 160 | } | ||
| 161 | |||
| 162 | /** | ||
| 163 | * March over the array once, left to right, finding natural runs, | ||
| 164 | * extending short natural runs to minRun elements, and merging runs | ||
| 165 | * to maintain stack invariant. | ||
| 166 | */ | ||
| 167 | ComparableTimSort ts = new ComparableTimSort(a); | ||
| 168 | int minRun = minRunLength(nRemaining); | ||
| 169 | do { | ||
| 170 | // Identify next run | ||
| 171 | int runLen = countRunAndMakeAscending(a, lo, hi); | ||
| 172 | |||
| 173 | // If run is short, extend to min(minRun, nRemaining) | ||
| 174 | if (runLen < minRun) { | ||
| 175 | int force = nRemaining <= minRun ? nRemaining : minRun; | ||
| 176 | binarySort(a, lo, lo + force, lo + runLen); | ||
| 177 | runLen = force; | ||
| 178 | } | ||
| 179 | |||
| 180 | // Push run onto pending-run stack, and maybe merge | ||
| 181 | ts.pushRun(lo, runLen); | ||
| 182 | ts.mergeCollapse(); | ||
| 183 | |||
| 184 | // Advance to find next run | ||
| 185 | lo += runLen; | ||
| 186 | nRemaining -= runLen; | ||
| 187 | } while (nRemaining != 0); | ||
| 188 | |||
| 189 | // Merge all remaining runs to complete sort | ||
| 190 | assert lo == hi; | ||
| 191 | ts.mergeForceCollapse(); | ||
| 192 | assert ts.stackSize == 1; | ||
| 193 | } | ||
| 194 | |||
| 195 | /** | ||
| 196 | * Sorts the specified portion of the specified array using a binary | ||
| 197 | * insertion sort. This is the best method for sorting small numbers | ||
| 198 | * of elements. It requires O(n log n) compares, but O(n^2) data | ||
| 199 | * movement (worst case). | ||
| 200 | * | ||
| 201 | * If the initial part of the specified range is already sorted, | ||
| 202 | * this method can take advantage of it: the method assumes that the | ||
| 203 | * elements from index {@code lo}, inclusive, to {@code start}, | ||
| 204 | * exclusive are already sorted. | ||
| 205 | * | ||
| 206 | * @param a the array in which a range is to be sorted | ||
| 207 | * @param lo the index of the first element in the range to be sorted | ||
| 208 | * @param hi the index after the last element in the range to be sorted | ||
| 209 | * @param start the index of the first element in the range that is | ||
| 210 | * not already known to be sorted ({@code lo <= start <= hi}) | ||
| 211 | */ | ||
| 212 | @SuppressWarnings("fallthrough") | ||
| 213 | private static void binarySort(Object[] a, int lo, int hi, int start) { | ||
| 214 | assert lo <= start && start <= hi; | ||
| 215 | if (start == lo) | ||
| 216 | start++; | ||
| 217 | for ( ; start < hi; start++) { | ||
| 218 | @SuppressWarnings("unchecked") | ||
| 219 | Comparable<Object> pivot = (Comparable) a[start]; | ||
| 220 | |||
| 221 | // Set left (and right) to the index where a[start] (pivot) belongs | ||
| 222 | int left = lo; | ||
| 223 | int right = start; | ||
| 224 | assert left <= right; | ||
| 225 | /* | ||
| 226 | * Invariants: | ||
| 227 | * pivot >= all in [lo, left). | ||
| 228 | * pivot < all in [right, start). | ||
| 229 | */ | ||
| 230 | while (left < right) { | ||
| 231 | int mid = (left + right) >>> 1; | ||
| 232 | if (pivot.compareTo(a[mid]) < 0) | ||
| 233 | right = mid; | ||
| 234 | else | ||
| 235 | left = mid + 1; | ||
| 236 | } | ||
| 237 | assert left == right; | ||
| 238 | |||
| 239 | /* | ||
| 240 | * The invariants still hold: pivot >= all in [lo, left) and | ||
| 241 | * pivot < all in [left, start), so pivot belongs at left. Note | ||
| 242 | * that if there are elements equal to pivot, left points to the | ||
| 243 | * first slot after them -- that's why this sort is stable. | ||
| 244 | * Slide elements over to make room for pivot. | ||
| 245 | */ | ||
| 246 | int n = start - left; // The number of elements to move | ||
| 247 | // Switch is just an optimization for arraycopy in default case | ||
| 248 | switch (n) { | ||
| 249 | case 2: a[left + 2] = a[left + 1]; | ||
| 250 | case 1: a[left + 1] = a[left]; | ||
| 251 | break; | ||
| 252 | default: System.arraycopy(a, left, a, left + 1, n); | ||
| 253 | } | ||
| 254 | a[left] = pivot; | ||
| 255 | } | ||
| 256 | } | ||
| 257 | |||
| 258 | /** | ||
| 259 | * Returns the length of the run beginning at the specified position in | ||
| 260 | * the specified array and reverses the run if it is descending (ensuring | ||
| 261 | * that the run will always be ascending when the method returns). | ||
| 262 | * | ||
| 263 | * A run is the longest ascending sequence with: | ||
| 264 | * | ||
| 265 | * a[lo] <= a[lo + 1] <= a[lo + 2] <= ... | ||
| 266 | * | ||
| 267 | * or the longest descending sequence with: | ||
| 268 | * | ||
| 269 | * a[lo] > a[lo + 1] > a[lo + 2] > ... | ||
| 270 | * | ||
| 271 | * For its intended use in a stable mergesort, the strictness of the | ||
| 272 | * definition of "descending" is needed so that the call can safely | ||
| 273 | * reverse a descending sequence without violating stability. | ||
| 274 | * | ||
| 275 | * @param a the array in which a run is to be counted and possibly reversed | ||
| 276 | * @param lo index of the first element in the run | ||
| 277 | * @param hi index after the last element that may be contained in the run. | ||
| 278 | It is required that {@code lo < hi}. | ||
| 279 | * @return the length of the run beginning at the specified position in | ||
| 280 | * the specified array | ||
| 281 | */ | ||
| 282 | @SuppressWarnings("unchecked") | ||
| 283 | private static int countRunAndMakeAscending(Object[] a, int lo, int hi) { | ||
| 284 | assert lo < hi; | ||
| 285 | int runHi = lo + 1; | ||
| 286 | if (runHi == hi) | ||
| 287 | return 1; | ||
| 288 | |||
| 289 | // Find end of run, and reverse range if descending | ||
| 290 | if (((Comparable) a[runHi++]).compareTo(a[lo]) < 0) { // Descending | ||
| 291 | while (runHi < hi && ((Comparable) a[runHi]).compareTo(a[runHi - 1]) < 0) | ||
| 292 | runHi++; | ||
| 293 | reverseRange(a, lo, runHi); | ||
| 294 | } else { // Ascending | ||
| 295 | while (runHi < hi && ((Comparable) a[runHi]).compareTo(a[runHi - 1]) >= 0) | ||
| 296 | runHi++; | ||
| 297 | } | ||
| 298 | |||
| 299 | return runHi - lo; | ||
| 300 | } | ||
| 301 | |||
| 302 | /** | ||
| 303 | * Reverse the specified range of the specified array. | ||
| 304 | * | ||
| 305 | * @param a the array in which a range is to be reversed | ||
| 306 | * @param lo the index of the first element in the range to be reversed | ||
| 307 | * @param hi the index after the last element in the range to be reversed | ||
| 308 | */ | ||
| 309 | private static void reverseRange(Object[] a, int lo, int hi) { | ||
| 310 | hi--; | ||
| 311 | while (lo < hi) { | ||
| 312 | Object t = a[lo]; | ||
| 313 | a[lo++] = a[hi]; | ||
| 314 | a[hi--] = t; | ||
| 315 | } | ||
| 316 | } | ||
| 317 | |||
| 318 | /** | ||
| 319 | * Returns the minimum acceptable run length for an array of the specified | ||
| 320 | * length. Natural runs shorter than this will be extended with | ||
| 321 | * {@link #binarySort}. | ||
| 322 | * | ||
| 323 | * Roughly speaking, the computation is: | ||
| 324 | * | ||
| 325 | * If n < MIN_MERGE, return n (it's too small to bother with fancy stuff). | ||
| 326 | * Else if n is an exact power of 2, return MIN_MERGE/2. | ||
| 327 | * Else return an int k, MIN_MERGE/2 <= k <= MIN_MERGE, such that n/k | ||
| 328 | * is close to, but strictly less than, an exact power of 2. | ||
| 329 | * | ||
| 330 | * For the rationale, see listsort.txt. | ||
| 331 | * | ||
| 332 | * @param n the length of the array to be sorted | ||
| 333 | * @return the length of the minimum run to be merged | ||
| 334 | */ | ||
| 335 | private static int minRunLength(int n) { | ||
| 336 | assert n >= 0; | ||
| 337 | int r = 0; // Becomes 1 if any 1 bits are shifted off | ||
| 338 | while (n >= MIN_MERGE) { | ||
| 339 | r |= (n & 1); | ||
| 340 | n >>= 1; | ||
| 341 | } | ||
| 342 | return n + r; | ||
| 343 | } | ||
| 344 | |||
| 345 | /** | ||
| 346 | * Pushes the specified run onto the pending-run stack. | ||
| 347 | * | ||
| 348 | * @param runBase index of the first element in the run | ||
| 349 | * @param runLen the number of elements in the run | ||
| 350 | */ | ||
| 351 | private void pushRun(int runBase, int runLen) { | ||
| 352 | this.runBase[stackSize] = runBase; | ||
| 353 | this.runLen[stackSize] = runLen; | ||
| 354 | stackSize++; | ||
| 355 | } | ||
| 356 | |||
| 357 | /** | ||
| 358 | * Examines the stack of runs waiting to be merged and merges adjacent runs | ||
| 359 | * until the stack invariants are reestablished: | ||
| 360 | * | ||
| 361 | * 1. runLen[i - 3] > runLen[i - 2] + runLen[i - 1] | ||
| 362 | * 2. runLen[i - 2] > runLen[i - 1] | ||
| 363 | * | ||
| 364 | * This method is called each time a new run is pushed onto the stack, | ||
| 365 | * so the invariants are guaranteed to hold for i < stackSize upon | ||
| 366 | * entry to the method. | ||
| 367 | */ | ||
| 368 | private void mergeCollapse() { | ||
| 369 | while (stackSize > 1) { | ||
| 370 | int n = stackSize - 2; | ||
| 371 | if (n > 0 && runLen[n-1] <= runLen[n] + runLen[n+1]) { | ||
| 372 | if (runLen[n - 1] < runLen[n + 1]) | ||
| 373 | n--; | ||
| 374 | mergeAt(n); | ||
| 375 | } else if (runLen[n] <= runLen[n + 1]) { | ||
| 376 | mergeAt(n); | ||
| 377 | } else { | ||
| 378 | break; // Invariant is established | ||
| 379 | } | ||
| 380 | } | ||
| 381 | } | ||
| 382 | |||
| 383 | /** | ||
| 384 | * Merges all runs on the stack until only one remains. This method is | ||
| 385 | * called once, to complete the sort. | ||
| 386 | */ | ||
| 387 | private void mergeForceCollapse() { | ||
| 388 | while (stackSize > 1) { | ||
| 389 | int n = stackSize - 2; | ||
| 390 | if (n > 0 && runLen[n - 1] < runLen[n + 1]) | ||
| 391 | n--; | ||
| 392 | mergeAt(n); | ||
| 393 | } | ||
| 394 | } | ||
| 395 | |||
| 396 | /** | ||
| 397 | * Merges the two runs at stack indices i and i+1. Run i must be | ||
| 398 | * the penultimate or antepenultimate run on the stack. In other words, | ||
| 399 | * i must be equal to stackSize-2 or stackSize-3. | ||
| 400 | * | ||
| 401 | * @param i stack index of the first of the two runs to merge | ||
| 402 | */ | ||
| 403 | @SuppressWarnings("unchecked") | ||
| 404 | private void mergeAt(int i) { | ||
| 405 | assert stackSize >= 2; | ||
| 406 | assert i >= 0; | ||
| 407 | assert i == stackSize - 2 || i == stackSize - 3; | ||
| 408 | |||
| 409 | int base1 = runBase[i]; | ||
| 410 | int len1 = runLen[i]; | ||
| 411 | int base2 = runBase[i + 1]; | ||
| 412 | int len2 = runLen[i + 1]; | ||
| 413 | assert len1 > 0 && len2 > 0; | ||
| 414 | assert base1 + len1 == base2; | ||
| 415 | |||
| 416 | /* | ||
| 417 | * Record the length of the combined runs; if i is the 3rd-last | ||
| 418 | * run now, also slide over the last run (which isn't involved | ||
| 419 | * in this merge). The current run (i+1) goes away in any case. | ||
| 420 | */ | ||
| 421 | runLen[i] = len1 + len2; | ||
| 422 | if (i == stackSize - 3) { | ||
| 423 | runBase[i + 1] = runBase[i + 2]; | ||
| 424 | runLen[i + 1] = runLen[i + 2]; | ||
| 425 | } | ||
| 426 | stackSize--; | ||
| 427 | |||
| 428 | /* | ||
| 429 | * Find where the first element of run2 goes in run1. Prior elements | ||
| 430 | * in run1 can be ignored (because they're already in place). | ||
| 431 | */ | ||
| 432 | int k = gallopRight((Comparable<Object>) a[base2], a, base1, len1, 0); | ||
| 433 | assert k >= 0; | ||
| 434 | base1 += k; | ||
| 435 | len1 -= k; | ||
| 436 | if (len1 == 0) | ||
| 437 | return; | ||
| 438 | |||
| 439 | /* | ||
| 440 | * Find where the last element of run1 goes in run2. Subsequent elements | ||
| 441 | * in run2 can be ignored (because they're already in place). | ||
| 442 | */ | ||
| 443 | len2 = gallopLeft((Comparable<Object>) a[base1 + len1 - 1], a, | ||
| 444 | base2, len2, len2 - 1); | ||
| 445 | assert len2 >= 0; | ||
| 446 | if (len2 == 0) | ||
| 447 | return; | ||
| 448 | |||
| 449 | // Merge remaining runs, using tmp array with min(len1, len2) elements | ||
| 450 | if (len1 <= len2) | ||
| 451 | mergeLo(base1, len1, base2, len2); | ||
| 452 | else | ||
| 453 | mergeHi(base1, len1, base2, len2); | ||
| 454 | } | ||
| 455 | |||
| 456 | /** | ||
| 457 | * Locates the position at which to insert the specified key into the | ||
| 458 | * specified sorted range; if the range contains an element equal to key, | ||
| 459 | * returns the index of the leftmost equal element. | ||
| 460 | * | ||
| 461 | * @param key the key whose insertion point to search for | ||
| 462 | * @param a the array in which to search | ||
| 463 | * @param base the index of the first element in the range | ||
| 464 | * @param len the length of the range; must be > 0 | ||
| 465 | * @param hint the index at which to begin the search, 0 <= hint < n. | ||
| 466 | * The closer hint is to the result, the faster this method will run. | ||
| 467 | * @return the int k, 0 <= k <= n such that a[b + k - 1] < key <= a[b + k], | ||
| 468 | * pretending that a[b - 1] is minus infinity and a[b + n] is infinity. | ||
| 469 | * In other words, key belongs at index b + k; or in other words, | ||
| 470 | * the first k elements of a should precede key, and the last n - k | ||
| 471 | * should follow it. | ||
| 472 | */ | ||
| 473 | private static int gallopLeft(Comparable<Object> key, Object[] a, | ||
| 474 | int base, int len, int hint) { | ||
| 475 | assert len > 0 && hint >= 0 && hint < len; | ||
| 476 | |||
| 477 | int lastOfs = 0; | ||
| 478 | int ofs = 1; | ||
| 479 | if (key.compareTo(a[base + hint]) > 0) { | ||
| 480 | // Gallop right until a[base+hint+lastOfs] < key <= a[base+hint+ofs] | ||
| 481 | int maxOfs = len - hint; | ||
| 482 | while (ofs < maxOfs && key.compareTo(a[base + hint + ofs]) > 0) { | ||
| 483 | lastOfs = ofs; | ||
| 484 | ofs = (ofs << 1) + 1; | ||
| 485 | if (ofs <= 0) // int overflow | ||
| 486 | ofs = maxOfs; | ||
| 487 | } | ||
| 488 | if (ofs > maxOfs) | ||
| 489 | ofs = maxOfs; | ||
| 490 | |||
| 491 | // Make offsets relative to base | ||
| 492 | lastOfs += hint; | ||
| 493 | ofs += hint; | ||
| 494 | } else { // key <= a[base + hint] | ||
| 495 | // Gallop left until a[base+hint-ofs] < key <= a[base+hint-lastOfs] | ||
| 496 | final int maxOfs = hint + 1; | ||
| 497 | while (ofs < maxOfs && key.compareTo(a[base + hint - ofs]) <= 0) { | ||
| 498 | lastOfs = ofs; | ||
| 499 | ofs = (ofs << 1) + 1; | ||
| 500 | if (ofs <= 0) // int overflow | ||
| 501 | ofs = maxOfs; | ||
| 502 | } | ||
| 503 | if (ofs > maxOfs) | ||
| 504 | ofs = maxOfs; | ||
| 505 | |||
| 506 | // Make offsets relative to base | ||
| 507 | int tmp = lastOfs; | ||
| 508 | lastOfs = hint - ofs; | ||
| 509 | ofs = hint - tmp; | ||
| 510 | } | ||
| 511 | assert -1 <= lastOfs && lastOfs < ofs && ofs <= len; | ||
| 512 | |||
| 513 | /* | ||
| 514 | * Now a[base+lastOfs] < key <= a[base+ofs], so key belongs somewhere | ||
| 515 | * to the right of lastOfs but no farther right than ofs. Do a binary | ||
| 516 | * search, with invariant a[base + lastOfs - 1] < key <= a[base + ofs]. | ||
| 517 | */ | ||
| 518 | lastOfs++; | ||
| 519 | while (lastOfs < ofs) { | ||
| 520 | int m = lastOfs + ((ofs - lastOfs) >>> 1); | ||
| 521 | |||
| 522 | if (key.compareTo(a[base + m]) > 0) | ||
| 523 | lastOfs = m + 1; // a[base + m] < key | ||
| 524 | else | ||
| 525 | ofs = m; // key <= a[base + m] | ||
| 526 | } | ||
| 527 | assert lastOfs == ofs; // so a[base + ofs - 1] < key <= a[base + ofs] | ||
| 528 | return ofs; | ||
| 529 | } | ||
| 530 | |||
| 531 | /** | ||
| 532 | * Like gallopLeft, except that if the range contains an element equal to | ||
| 533 | * key, gallopRight returns the index after the rightmost equal element. | ||
| 534 | * | ||
| 535 | * @param key the key whose insertion point to search for | ||
| 536 | * @param a the array in which to search | ||
| 537 | * @param base the index of the first element in the range | ||
| 538 | * @param len the length of the range; must be > 0 | ||
| 539 | * @param hint the index at which to begin the search, 0 <= hint < n. | ||
| 540 | * The closer hint is to the result, the faster this method will run. | ||
| 541 | * @return the int k, 0 <= k <= n such that a[b + k - 1] <= key < a[b + k] | ||
| 542 | */ | ||
| 543 | private static int gallopRight(Comparable<Object> key, Object[] a, | ||
| 544 | int base, int len, int hint) { | ||
| 545 | assert len > 0 && hint >= 0 && hint < len; | ||
| 546 | |||
| 547 | int ofs = 1; | ||
| 548 | int lastOfs = 0; | ||
| 549 | if (key.compareTo(a[base + hint]) < 0) { | ||
| 550 | // Gallop left until a[b+hint - ofs] <= key < a[b+hint - lastOfs] | ||
| 551 | int maxOfs = hint + 1; | ||
| 552 | while (ofs < maxOfs && key.compareTo(a[base + hint - ofs]) < 0) { | ||
| 553 | lastOfs = ofs; | ||
| 554 | ofs = (ofs << 1) + 1; | ||
| 555 | if (ofs <= 0) // int overflow | ||
| 556 | ofs = maxOfs; | ||
| 557 | } | ||
| 558 | if (ofs > maxOfs) | ||
| 559 | ofs = maxOfs; | ||
| 560 | |||
| 561 | // Make offsets relative to b | ||
| 562 | int tmp = lastOfs; | ||
| 563 | lastOfs = hint - ofs; | ||
| 564 | ofs = hint - tmp; | ||
| 565 | } else { // a[b + hint] <= key | ||
| 566 | // Gallop right until a[b+hint + lastOfs] <= key < a[b+hint + ofs] | ||
| 567 | int maxOfs = len - hint; | ||
| 568 | while (ofs < maxOfs && key.compareTo(a[base + hint + ofs]) >= 0) { | ||
| 569 | lastOfs = ofs; | ||
| 570 | ofs = (ofs << 1) + 1; | ||
| 571 | if (ofs <= 0) // int overflow | ||
| 572 | ofs = maxOfs; | ||
| 573 | } | ||
| 574 | if (ofs > maxOfs) | ||
| 575 | ofs = maxOfs; | ||
| 576 | |||
| 577 | // Make offsets relative to b | ||
| 578 | lastOfs += hint; | ||
| 579 | ofs += hint; | ||
| 580 | } | ||
| 581 | assert -1 <= lastOfs && lastOfs < ofs && ofs <= len; | ||
| 582 | |||
| 583 | /* | ||
| 584 | * Now a[b + lastOfs] <= key < a[b + ofs], so key belongs somewhere to | ||
| 585 | * the right of lastOfs but no farther right than ofs. Do a binary | ||
| 586 | * search, with invariant a[b + lastOfs - 1] <= key < a[b + ofs]. | ||
| 587 | */ | ||
| 588 | lastOfs++; | ||
| 589 | while (lastOfs < ofs) { | ||
| 590 | int m = lastOfs + ((ofs - lastOfs) >>> 1); | ||
| 591 | |||
| 592 | if (key.compareTo(a[base + m]) < 0) | ||
| 593 | ofs = m; // key < a[b + m] | ||
| 594 | else | ||
| 595 | lastOfs = m + 1; // a[b + m] <= key | ||
| 596 | } | ||
| 597 | assert lastOfs == ofs; // so a[b + ofs - 1] <= key < a[b + ofs] | ||
| 598 | return ofs; | ||
| 599 | } | ||
| 600 | |||
| 601 | /** | ||
| 602 | * Merges two adjacent runs in place, in a stable fashion. The first | ||
| 603 | * element of the first run must be greater than the first element of the | ||
| 604 | * second run (a[base1] > a[base2]), and the last element of the first run | ||
| 605 | * (a[base1 + len1-1]) must be greater than all elements of the second run. | ||
| 606 | * | ||
| 607 | * For performance, this method should be called only when len1 <= len2; | ||
| 608 | * its twin, mergeHi should be called if len1 >= len2. (Either method | ||
| 609 | * may be called if len1 == len2.) | ||
| 610 | * | ||
| 611 | * @param base1 index of first element in first run to be merged | ||
| 612 | * @param len1 length of first run to be merged (must be > 0) | ||
| 613 | * @param base2 index of first element in second run to be merged | ||
| 614 | * (must be aBase + aLen) | ||
| 615 | * @param len2 length of second run to be merged (must be > 0) | ||
| 616 | */ | ||
| 617 | @SuppressWarnings("unchecked") | ||
| 618 | private void mergeLo(int base1, int len1, int base2, int len2) { | ||
| 619 | assert len1 > 0 && len2 > 0 && base1 + len1 == base2; | ||
| 620 | |||
| 621 | // Copy first run into temp array | ||
| 622 | Object[] a = this.a; // For performance | ||
| 623 | Object[] tmp = ensureCapacity(len1); | ||
| 624 | System.arraycopy(a, base1, tmp, 0, len1); | ||
| 625 | |||
| 626 | int cursor1 = 0; // Indexes into tmp array | ||
| 627 | int cursor2 = base2; // Indexes int a | ||
| 628 | int dest = base1; // Indexes int a | ||
| 629 | |||
| 630 | // Move first element of second run and deal with degenerate cases | ||
| 631 | a[dest++] = a[cursor2++]; | ||
| 632 | if (--len2 == 0) { | ||
| 633 | System.arraycopy(tmp, cursor1, a, dest, len1); | ||
| 634 | return; | ||
| 635 | } | ||
| 636 | if (len1 == 1) { | ||
| 637 | System.arraycopy(a, cursor2, a, dest, len2); | ||
| 638 | a[dest + len2] = tmp[cursor1]; // Last elt of run 1 to end of merge | ||
| 639 | return; | ||
| 640 | } | ||
| 641 | |||
| 642 | int minGallop = this.minGallop; // Use local variable for performance | ||
| 643 | outer: | ||
| 644 | while (true) { | ||
| 645 | int count1 = 0; // Number of times in a row that first run won | ||
| 646 | int count2 = 0; // Number of times in a row that second run won | ||
| 647 | |||
| 648 | /* | ||
| 649 | * Do the straightforward thing until (if ever) one run starts | ||
| 650 | * winning consistently. | ||
| 651 | */ | ||
| 652 | do { | ||
| 653 | assert len1 > 1 && len2 > 0; | ||
| 654 | if (((Comparable) a[cursor2]).compareTo(tmp[cursor1]) < 0) { | ||
| 655 | a[dest++] = a[cursor2++]; | ||
| 656 | count2++; | ||
| 657 | count1 = 0; | ||
| 658 | if (--len2 == 0) | ||
| 659 | break outer; | ||
| 660 | } else { | ||
| 661 | a[dest++] = tmp[cursor1++]; | ||
| 662 | count1++; | ||
| 663 | count2 = 0; | ||
| 664 | if (--len1 == 1) | ||
| 665 | break outer; | ||
| 666 | } | ||
| 667 | } while ((count1 | count2) < minGallop); | ||
| 668 | |||
| 669 | /* | ||
| 670 | * One run is winning so consistently that galloping may be a | ||
| 671 | * huge win. So try that, and continue galloping until (if ever) | ||
| 672 | * neither run appears to be winning consistently anymore. | ||
| 673 | */ | ||
| 674 | do { | ||
| 675 | assert len1 > 1 && len2 > 0; | ||
| 676 | count1 = gallopRight((Comparable) a[cursor2], tmp, cursor1, len1, 0); | ||
| 677 | if (count1 != 0) { | ||
| 678 | System.arraycopy(tmp, cursor1, a, dest, count1); | ||
| 679 | dest += count1; | ||
| 680 | cursor1 += count1; | ||
| 681 | len1 -= count1; | ||
| 682 | if (len1 <= 1) // len1 == 1 || len1 == 0 | ||
| 683 | break outer; | ||
| 684 | } | ||
| 685 | a[dest++] = a[cursor2++]; | ||
| 686 | if (--len2 == 0) | ||
| 687 | break outer; | ||
| 688 | |||
| 689 | count2 = gallopLeft((Comparable) tmp[cursor1], a, cursor2, len2, 0); | ||
| 690 | if (count2 != 0) { | ||
| 691 | System.arraycopy(a, cursor2, a, dest, count2); | ||
| 692 | dest += count2; | ||
| 693 | cursor2 += count2; | ||
| 694 | len2 -= count2; | ||
| 695 | if (len2 == 0) | ||
| 696 | break outer; | ||
| 697 | } | ||
| 698 | a[dest++] = tmp[cursor1++]; | ||
| 699 | if (--len1 == 1) | ||
| 700 | break outer; | ||
| 701 | minGallop--; | ||
| 702 | } while (count1 >= MIN_GALLOP | count2 >= MIN_GALLOP); | ||
| 703 | if (minGallop < 0) | ||
| 704 | minGallop = 0; | ||
| 705 | minGallop += 2; // Penalize for leaving gallop mode | ||
| 706 | } // End of "outer" loop | ||
| 707 | this.minGallop = minGallop < 1 ? 1 : minGallop; // Write back to field | ||
| 708 | |||
| 709 | if (len1 == 1) { | ||
| 710 | assert len2 > 0; | ||
| 711 | System.arraycopy(a, cursor2, a, dest, len2); | ||
| 712 | a[dest + len2] = tmp[cursor1]; // Last elt of run 1 to end of merge | ||
| 713 | } else if (len1 == 0) { | ||
| 714 | throw new IllegalArgumentException( | ||
| 715 | "Comparison method violates its general contract!"); | ||
| 716 | } else { | ||
| 717 | assert len2 == 0; | ||
| 718 | assert len1 > 1; | ||
| 719 | System.arraycopy(tmp, cursor1, a, dest, len1); | ||
| 720 | } | ||
| 721 | } | ||
| 722 | |||
| 723 | /** | ||
| 724 | * Like mergeLo, except that this method should be called only if | ||
| 725 | * len1 >= len2; mergeLo should be called if len1 <= len2. (Either method | ||
| 726 | * may be called if len1 == len2.) | ||
| 727 | * | ||
| 728 | * @param base1 index of first element in first run to be merged | ||
| 729 | * @param len1 length of first run to be merged (must be > 0) | ||
| 730 | * @param base2 index of first element in second run to be merged | ||
| 731 | * (must be aBase + aLen) | ||
| 732 | * @param len2 length of second run to be merged (must be > 0) | ||
| 733 | */ | ||
| 734 | @SuppressWarnings("unchecked") | ||
| 735 | private void mergeHi(int base1, int len1, int base2, int len2) { | ||
| 736 | assert len1 > 0 && len2 > 0 && base1 + len1 == base2; | ||
| 737 | |||
| 738 | // Copy second run into temp array | ||
| 739 | Object[] a = this.a; // For performance | ||
| 740 | Object[] tmp = ensureCapacity(len2); | ||
| 741 | System.arraycopy(a, base2, tmp, 0, len2); | ||
| 742 | |||
| 743 | int cursor1 = base1 + len1 - 1; // Indexes into a | ||
| 744 | int cursor2 = len2 - 1; // Indexes into tmp array | ||
| 745 | int dest = base2 + len2 - 1; // Indexes into a | ||
| 746 | |||
| 747 | // Move last element of first run and deal with degenerate cases | ||
| 748 | a[dest--] = a[cursor1--]; | ||
| 749 | if (--len1 == 0) { | ||
| 750 | System.arraycopy(tmp, 0, a, dest - (len2 - 1), len2); | ||
| 751 | return; | ||
| 752 | } | ||
| 753 | if (len2 == 1) { | ||
| 754 | dest -= len1; | ||
| 755 | cursor1 -= len1; | ||
| 756 | System.arraycopy(a, cursor1 + 1, a, dest + 1, len1); | ||
| 757 | a[dest] = tmp[cursor2]; | ||
| 758 | return; | ||
| 759 | } | ||
| 760 | |||
| 761 | int minGallop = this.minGallop; // Use local variable for performance | ||
| 762 | outer: | ||
| 763 | while (true) { | ||
| 764 | int count1 = 0; // Number of times in a row that first run won | ||
| 765 | int count2 = 0; // Number of times in a row that second run won | ||
| 766 | |||
| 767 | /* | ||
| 768 | * Do the straightforward thing until (if ever) one run | ||
| 769 | * appears to win consistently. | ||
| 770 | */ | ||
| 771 | do { | ||
| 772 | assert len1 > 0 && len2 > 1; | ||
| 773 | if (((Comparable) tmp[cursor2]).compareTo(a[cursor1]) < 0) { | ||
| 774 | a[dest--] = a[cursor1--]; | ||
| 775 | count1++; | ||
| 776 | count2 = 0; | ||
| 777 | if (--len1 == 0) | ||
| 778 | break outer; | ||
| 779 | } else { | ||
| 780 | a[dest--] = tmp[cursor2--]; | ||
| 781 | count2++; | ||
| 782 | count1 = 0; | ||
| 783 | if (--len2 == 1) | ||
| 784 | break outer; | ||
| 785 | } | ||
| 786 | } while ((count1 | count2) < minGallop); | ||
| 787 | |||
| 788 | /* | ||
| 789 | * One run is winning so consistently that galloping may be a | ||
| 790 | * huge win. So try that, and continue galloping until (if ever) | ||
| 791 | * neither run appears to be winning consistently anymore. | ||
| 792 | */ | ||
| 793 | do { | ||
| 794 | assert len1 > 0 && len2 > 1; | ||
| 795 | count1 = len1 - gallopRight((Comparable) tmp[cursor2], a, base1, len1, len1 - 1); | ||
| 796 | if (count1 != 0) { | ||
| 797 | dest -= count1; | ||
| 798 | cursor1 -= count1; | ||
| 799 | len1 -= count1; | ||
| 800 | System.arraycopy(a, cursor1 + 1, a, dest + 1, count1); | ||
| 801 | if (len1 == 0) | ||
| 802 | break outer; | ||
| 803 | } | ||
| 804 | a[dest--] = tmp[cursor2--]; | ||
| 805 | if (--len2 == 1) | ||
| 806 | break outer; | ||
| 807 | |||
| 808 | count2 = len2 - gallopLeft((Comparable) a[cursor1], tmp, 0, len2, len2 - 1); | ||
| 809 | if (count2 != 0) { | ||
| 810 | dest -= count2; | ||
| 811 | cursor2 -= count2; | ||
| 812 | len2 -= count2; | ||
| 813 | System.arraycopy(tmp, cursor2 + 1, a, dest + 1, count2); | ||
| 814 | if (len2 <= 1) | ||
| 815 | break outer; // len2 == 1 || len2 == 0 | ||
| 816 | } | ||
| 817 | a[dest--] = a[cursor1--]; | ||
| 818 | if (--len1 == 0) | ||
| 819 | break outer; | ||
| 820 | minGallop--; | ||
| 821 | } while (count1 >= MIN_GALLOP | count2 >= MIN_GALLOP); | ||
| 822 | if (minGallop < 0) | ||
| 823 | minGallop = 0; | ||
| 824 | minGallop += 2; // Penalize for leaving gallop mode | ||
| 825 | } // End of "outer" loop | ||
| 826 | this.minGallop = minGallop < 1 ? 1 : minGallop; // Write back to field | ||
| 827 | |||
| 828 | if (len2 == 1) { | ||
| 829 | assert len1 > 0; | ||
| 830 | dest -= len1; | ||
| 831 | cursor1 -= len1; | ||
| 832 | System.arraycopy(a, cursor1 + 1, a, dest + 1, len1); | ||
| 833 | a[dest] = tmp[cursor2]; // Move first elt of run2 to front of merge | ||
| 834 | } else if (len2 == 0) { | ||
| 835 | throw new IllegalArgumentException( | ||
| 836 | "Comparison method violates its general contract!"); | ||
| 837 | } else { | ||
| 838 | assert len1 == 0; | ||
| 839 | assert len2 > 0; | ||
| 840 | System.arraycopy(tmp, 0, a, dest - (len2 - 1), len2); | ||
| 841 | } | ||
| 842 | } | ||
| 843 | |||
| 844 | /** | ||
| 845 | * Ensures that the external array tmp has at least the specified | ||
| 846 | * number of elements, increasing its size if necessary. The size | ||
| 847 | * increases exponentially to ensure amortized linear time complexity. | ||
| 848 | * | ||
| 849 | * @param minCapacity the minimum required capacity of the tmp array | ||
| 850 | * @return tmp, whether or not it grew | ||
| 851 | */ | ||
| 852 | private Object[] ensureCapacity(int minCapacity) { | ||
| 853 | if (tmp.length < minCapacity) { | ||
| 854 | // Compute smallest power of 2 > minCapacity | ||
| 855 | int newSize = minCapacity; | ||
| 856 | newSize |= newSize >> 1; | ||
| 857 | newSize |= newSize >> 2; | ||
| 858 | newSize |= newSize >> 4; | ||
| 859 | newSize |= newSize >> 8; | ||
| 860 | newSize |= newSize >> 16; | ||
| 861 | newSize++; | ||
| 862 | |||
| 863 | if (newSize < 0) // Not bloody likely! | ||
| 864 | newSize = minCapacity; | ||
| 865 | else | ||
| 866 | newSize = Math.min(newSize, a.length >>> 1); | ||
| 867 | |||
| 868 | @SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"}) | ||
| 869 | Object[] newArray = new Object[newSize]; | ||
| 870 | tmp = newArray; | ||
| 871 | } | ||
| 872 | return tmp; | ||
| 873 | } | ||
| 874 | |||
| 875 | /** | ||
| 876 | * Checks that fromIndex and toIndex are in range, and throws an | ||
| 877 | * appropriate exception if they aren't. | ||
| 878 | * | ||
| 879 | * @param arrayLen the length of the array | ||
| 880 | * @param fromIndex the index of the first element of the range | ||
| 881 | * @param toIndex the index after the last element of the range | ||
| 882 | * @throws IllegalArgumentException if fromIndex > toIndex | ||
| 883 | * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 | ||
| 884 | * or toIndex > arrayLen | ||
| 885 | */ | ||
| 886 | private static void rangeCheck(int arrayLen, int fromIndex, int toIndex) { | ||
| 887 | if (fromIndex > toIndex) | ||
| 888 | throw new IllegalArgumentException("fromIndex(" + fromIndex + | ||
| 889 | ") > toIndex(" + toIndex+")"); | ||
| 890 | if (fromIndex < 0) | ||
| 891 | throw new ArrayIndexOutOfBoundsException(fromIndex); | ||
| 892 | if (toIndex > arrayLen) | ||
| 893 | throw new ArrayIndexOutOfBoundsException(toIndex); | ||
| 894 | } | ||
| 895 | } | ||
Binary file not shown.
| @@ -0,0 +1,168 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package java.util; | ||
| 27 | |||
| 28 | /** | ||
| 29 | * A comparison function, which imposes a <i>total ordering</i> on some | ||
| 30 | * collection of objects. Comparators can be passed to a sort method (such | ||
| 31 | * as {@link Collections#sort(List,Comparator) Collections.sort} or {@link | ||
| 32 | * Arrays#sort(Object[],Comparator) Arrays.sort}) to allow precise control | ||
| 33 | * over the sort order. Comparators can also be used to control the order of | ||
| 34 | * certain data structures (such as {@link SortedSet sorted sets} or {@link | ||
| 35 | * SortedMap sorted maps}), or to provide an ordering for collections of | ||
| 36 | * objects that don't have a {@link Comparable natural ordering}.<p> | ||
| 37 | * | ||
| 38 | * The ordering imposed by a comparator <tt>c</tt> on a set of elements | ||
| 39 | * <tt>S</tt> is said to be <i>consistent with equals</i> if and only if | ||
| 40 | * <tt>c.compare(e1, e2)==0</tt> has the same boolean value as | ||
| 41 | * <tt>e1.equals(e2)</tt> for every <tt>e1</tt> and <tt>e2</tt> in | ||
| 42 | * <tt>S</tt>.<p> | ||
| 43 | * | ||
| 44 | * Caution should be exercised when using a comparator capable of imposing an | ||
| 45 | * ordering inconsistent with equals to order a sorted set (or sorted map). | ||
| 46 | * Suppose a sorted set (or sorted map) with an explicit comparator <tt>c</tt> | ||
| 47 | * is used with elements (or keys) drawn from a set <tt>S</tt>. If the | ||
| 48 | * ordering imposed by <tt>c</tt> on <tt>S</tt> is inconsistent with equals, | ||
| 49 | * the sorted set (or sorted map) will behave "strangely." In particular the | ||
| 50 | * sorted set (or sorted map) will violate the general contract for set (or | ||
| 51 | * map), which is defined in terms of <tt>equals</tt>.<p> | ||
| 52 | * | ||
| 53 | * For example, suppose one adds two elements {@code a} and {@code b} such that | ||
| 54 | * {@code (a.equals(b) && c.compare(a, b) != 0)} | ||
| 55 | * to an empty {@code TreeSet} with comparator {@code c}. | ||
| 56 | * The second {@code add} operation will return | ||
| 57 | * true (and the size of the tree set will increase) because {@code a} and | ||
| 58 | * {@code b} are not equivalent from the tree set's perspective, even though | ||
| 59 | * this is contrary to the specification of the | ||
| 60 | * {@link Set#add Set.add} method.<p> | ||
| 61 | * | ||
| 62 | * Note: It is generally a good idea for comparators to also implement | ||
| 63 | * <tt>java.io.Serializable</tt>, as they may be used as ordering methods in | ||
| 64 | * serializable data structures (like {@link TreeSet}, {@link TreeMap}). In | ||
| 65 | * order for the data structure to serialize successfully, the comparator (if | ||
| 66 | * provided) must implement <tt>Serializable</tt>.<p> | ||
| 67 | * | ||
| 68 | * For the mathematically inclined, the <i>relation</i> that defines the | ||
| 69 | * <i>imposed ordering</i> that a given comparator <tt>c</tt> imposes on a | ||
| 70 | * given set of objects <tt>S</tt> is:<pre> | ||
| 71 | * {(x, y) such that c.compare(x, y) <= 0}. | ||
| 72 | * </pre> The <i>quotient</i> for this total order is:<pre> | ||
| 73 | * {(x, y) such that c.compare(x, y) == 0}. | ||
| 74 | * </pre> | ||
| 75 | * | ||
| 76 | * It follows immediately from the contract for <tt>compare</tt> that the | ||
| 77 | * quotient is an <i>equivalence relation</i> on <tt>S</tt>, and that the | ||
| 78 | * imposed ordering is a <i>total order</i> on <tt>S</tt>. When we say that | ||
| 79 | * the ordering imposed by <tt>c</tt> on <tt>S</tt> is <i>consistent with | ||
| 80 | * equals</i>, we mean that the quotient for the ordering is the equivalence | ||
| 81 | * relation defined by the objects' {@link Object#equals(Object) | ||
| 82 | * equals(Object)} method(s):<pre> | ||
| 83 | * {(x, y) such that x.equals(y)}. </pre> | ||
| 84 | * | ||
| 85 | * <p>Unlike {@code Comparable}, a comparator may optionally permit | ||
| 86 | * comparison of null arguments, while maintaining the requirements for | ||
| 87 | * an equivalence relation. | ||
| 88 | * | ||
| 89 | * <p>This interface is a member of the | ||
| 90 | * <a href="{@docRoot}/../technotes/guides/collections/index.html"> | ||
| 91 | * Java Collections Framework</a>. | ||
| 92 | * | ||
| 93 | * @param <T> the type of objects that may be compared by this comparator | ||
| 94 | * | ||
| 95 | * @author Josh Bloch | ||
| 96 | * @author Neal Gafter | ||
| 97 | * @see Comparable | ||
| 98 | * @see java.io.Serializable | ||
| 99 | * @since 1.2 | ||
| 100 | */ | ||
| 101 | |||
| 102 | public interface Comparator<T> { | ||
| 103 | /** | ||
| 104 | * Compares its two arguments for order. Returns a negative integer, | ||
| 105 | * zero, or a positive integer as the first argument is less than, equal | ||
| 106 | * to, or greater than the second.<p> | ||
| 107 | * | ||
| 108 | * In the foregoing description, the notation | ||
| 109 | * <tt>sgn(</tt><i>expression</i><tt>)</tt> designates the mathematical | ||
| 110 | * <i>signum</i> function, which is defined to return one of <tt>-1</tt>, | ||
| 111 | * <tt>0</tt>, or <tt>1</tt> according to whether the value of | ||
| 112 | * <i>expression</i> is negative, zero or positive.<p> | ||
| 113 | * | ||
| 114 | * The implementor must ensure that <tt>sgn(compare(x, y)) == | ||
| 115 | * -sgn(compare(y, x))</tt> for all <tt>x</tt> and <tt>y</tt>. (This | ||
| 116 | * implies that <tt>compare(x, y)</tt> must throw an exception if and only | ||
| 117 | * if <tt>compare(y, x)</tt> throws an exception.)<p> | ||
| 118 | * | ||
| 119 | * The implementor must also ensure that the relation is transitive: | ||
| 120 | * <tt>((compare(x, y)>0) && (compare(y, z)>0))</tt> implies | ||
| 121 | * <tt>compare(x, z)>0</tt>.<p> | ||
| 122 | * | ||
| 123 | * Finally, the implementor must ensure that <tt>compare(x, y)==0</tt> | ||
| 124 | * implies that <tt>sgn(compare(x, z))==sgn(compare(y, z))</tt> for all | ||
| 125 | * <tt>z</tt>.<p> | ||
| 126 | * | ||
| 127 | * It is generally the case, but <i>not</i> strictly required that | ||
| 128 | * <tt>(compare(x, y)==0) == (x.equals(y))</tt>. Generally speaking, | ||
| 129 | * any comparator that violates this condition should clearly indicate | ||
| 130 | * this fact. The recommended language is "Note: this comparator | ||
| 131 | * imposes orderings that are inconsistent with equals." | ||
| 132 | * | ||
| 133 | * @param o1 the first object to be compared. | ||
| 134 | * @param o2 the second object to be compared. | ||
| 135 | * @return a negative integer, zero, or a positive integer as the | ||
| 136 | * first argument is less than, equal to, or greater than the | ||
| 137 | * second. | ||
| 138 | * @throws NullPointerException if an argument is null and this | ||
| 139 | * comparator does not permit null arguments | ||
| 140 | * @throws ClassCastException if the arguments' types prevent them from | ||
| 141 | * being compared by this comparator. | ||
| 142 | */ | ||
| 143 | int compare(T o1, T o2); | ||
| 144 | |||
| 145 | /** | ||
| 146 | * Indicates whether some other object is "equal to" this | ||
| 147 | * comparator. This method must obey the general contract of | ||
| 148 | * {@link Object#equals(Object)}. Additionally, this method can return | ||
| 149 | * <tt>true</tt> <i>only</i> if the specified object is also a comparator | ||
| 150 | * and it imposes the same ordering as this comparator. Thus, | ||
| 151 | * <code>comp1.equals(comp2)</code> implies that <tt>sgn(comp1.compare(o1, | ||
| 152 | * o2))==sgn(comp2.compare(o1, o2))</tt> for every object reference | ||
| 153 | * <tt>o1</tt> and <tt>o2</tt>.<p> | ||
| 154 | * | ||
| 155 | * Note that it is <i>always</i> safe <i>not</i> to override | ||
| 156 | * <tt>Object.equals(Object)</tt>. However, overriding this method may, | ||
| 157 | * in some cases, improve performance by allowing programs to determine | ||
| 158 | * that two distinct comparators impose the same order. | ||
| 159 | * | ||
| 160 | * @param obj the reference object with which to compare. | ||
| 161 | * @return <code>true</code> only if the specified object is also | ||
| 162 | * a comparator and it imposes the same ordering as this | ||
| 163 | * comparator. | ||
| 164 | * @see Object#equals(Object) | ||
| 165 | * @see Object#hashCode() | ||
| 166 | */ | ||
| 167 | boolean equals(Object obj); | ||
| 168 | } | ||
Binary file not shown.
| @@ -0,0 +1,123 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package java.util; | ||
| 27 | |||
| 28 | /** | ||
| 29 | * This exception may be thrown by methods that have detected concurrent | ||
| 30 | * modification of an object when such modification is not permissible. | ||
| 31 | * <p> | ||
| 32 | * For example, it is not generally permissible for one thread to modify a Collection | ||
| 33 | * while another thread is iterating over it. In general, the results of the | ||
| 34 | * iteration are undefined under these circumstances. Some Iterator | ||
| 35 | * implementations (including those of all the general purpose collection implementations | ||
| 36 | * provided by the JRE) may choose to throw this exception if this behavior is | ||
| 37 | * detected. Iterators that do this are known as <i>fail-fast</i> iterators, | ||
| 38 | * as they fail quickly and cleanly, rather that risking arbitrary, | ||
| 39 | * non-deterministic behavior at an undetermined time in the future. | ||
| 40 | * <p> | ||
| 41 | * Note that this exception does not always indicate that an object has | ||
| 42 | * been concurrently modified by a <i>different</i> thread. If a single | ||
| 43 | * thread issues a sequence of method invocations that violates the | ||
| 44 | * contract of an object, the object may throw this exception. For | ||
| 45 | * example, if a thread modifies a collection directly while it is | ||
| 46 | * iterating over the collection with a fail-fast iterator, the iterator | ||
| 47 | * will throw this exception. | ||
| 48 | * | ||
| 49 | * <p>Note that fail-fast behavior cannot be guaranteed as it is, generally | ||
| 50 | * speaking, impossible to make any hard guarantees in the presence of | ||
| 51 | * unsynchronized concurrent modification. Fail-fast operations | ||
| 52 | * throw {@code ConcurrentModificationException} on a best-effort basis. | ||
| 53 | * Therefore, it would be wrong to write a program that depended on this | ||
| 54 | * exception for its correctness: <i>{@code ConcurrentModificationException} | ||
| 55 | * should be used only to detect bugs.</i> | ||
| 56 | * | ||
| 57 | * @author Josh Bloch | ||
| 58 | * @see Collection | ||
| 59 | * @see Iterator | ||
| 60 | * @see ListIterator | ||
| 61 | * @see Vector | ||
| 62 | * @see LinkedList | ||
| 63 | * @see HashSet | ||
| 64 | * @see Hashtable | ||
| 65 | * @see TreeMap | ||
| 66 | * @see AbstractList | ||
| 67 | * @since 1.2 | ||
| 68 | */ | ||
| 69 | public class ConcurrentModificationException extends RuntimeException { | ||
| 70 | private static final long serialVersionUID = -3666751008965953603L; | ||
| 71 | |||
| 72 | /** | ||
| 73 | * Constructs a ConcurrentModificationException with no | ||
| 74 | * detail message. | ||
| 75 | */ | ||
| 76 | public ConcurrentModificationException() { | ||
| 77 | } | ||
| 78 | |||
| 79 | /** | ||
| 80 | * Constructs a {@code ConcurrentModificationException} with the | ||
| 81 | * specified detail message. | ||
| 82 | * | ||
| 83 | * @param message the detail message pertaining to this exception. | ||
| 84 | */ | ||
| 85 | public ConcurrentModificationException(String message) { | ||
| 86 | super(message); | ||
| 87 | } | ||
| 88 | |||
| 89 | /** | ||
| 90 | * Constructs a new exception with the specified cause and a detail | ||
| 91 | * message of {@code (cause==null ? null : cause.toString())} (which | ||
| 92 | * typically contains the class and detail message of {@code cause}. | ||
| 93 | * | ||
| 94 | * @param cause the cause (which is saved for later retrieval by the | ||
| 95 | * {@link Throwable#getCause()} method). (A {@code null} value is | ||
| 96 | * permitted, and indicates that the cause is nonexistent or | ||
| 97 | * unknown.) | ||
| 98 | * @since 1.7 | ||
| 99 | */ | ||
| 100 | public ConcurrentModificationException(Throwable cause) { | ||
| 101 | super(cause); | ||
| 102 | } | ||
| 103 | |||
| 104 | /** | ||
| 105 | * Constructs a new exception with the specified detail message and | ||
| 106 | * cause. | ||
| 107 | * | ||
| 108 | * <p>Note that the detail message associated with <code>cause</code> is | ||
| 109 | * <i>not</i> automatically incorporated in this exception's detail | ||
| 110 | * message. | ||
| 111 | * | ||
| 112 | * @param message the detail message (which is saved for later retrieval | ||
| 113 | * by the {@link Throwable#getMessage()} method). | ||
| 114 | * @param cause the cause (which is saved for later retrieval by the | ||
| 115 | * {@link Throwable#getCause()} method). (A {@code null} value | ||
| 116 | * is permitted, and indicates that the cause is nonexistent or | ||
| 117 | * unknown.) | ||
| 118 | * @since 1.7 | ||
| 119 | */ | ||
| 120 | public ConcurrentModificationException(String message, Throwable cause) { | ||
| 121 | super(message, cause); | ||
| 122 | } | ||
| 123 | } | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,741 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package java.util; | ||
| 27 | |||
| 28 | import java.io.BufferedInputStream; | ||
| 29 | import java.io.DataInputStream; | ||
| 30 | import java.io.File; | ||
| 31 | import java.io.FileInputStream; | ||
| 32 | import java.io.FileReader; | ||
| 33 | import java.io.IOException; | ||
| 34 | import java.io.Serializable; | ||
| 35 | import java.security.AccessController; | ||
| 36 | import java.security.PrivilegedAction; | ||
| 37 | import java.util.logging.Level; | ||
| 38 | import java.util.regex.Pattern; | ||
| 39 | import java.util.regex.Matcher; | ||
| 40 | import java.util.spi.CurrencyNameProvider; | ||
| 41 | import java.util.spi.LocaleServiceProvider; | ||
| 42 | import sun.util.LocaleServiceProviderPool; | ||
| 43 | import sun.util.logging.PlatformLogger; | ||
| 44 | import sun.util.resources.LocaleData; | ||
| 45 | import sun.util.resources.OpenListResourceBundle; | ||
| 46 | |||
| 47 | |||
| 48 | /** | ||
| 49 | * Represents a currency. Currencies are identified by their ISO 4217 currency | ||
| 50 | * codes. Visit the <a href="http://www.iso.org/iso/en/prods-services/popstds/currencycodes.html"> | ||
| 51 | * ISO web site</a> for more information, including a table of | ||
| 52 | * currency codes. | ||
| 53 | * <p> | ||
| 54 | * The class is designed so that there's never more than one | ||
| 55 | * <code>Currency</code> instance for any given currency. Therefore, there's | ||
| 56 | * no public constructor. You obtain a <code>Currency</code> instance using | ||
| 57 | * the <code>getInstance</code> methods. | ||
| 58 | * <p> | ||
| 59 | * Users can supersede the Java runtime currency data by creating a properties | ||
| 60 | * file named <code><JAVA_HOME>/lib/currency.properties</code>. The contents | ||
| 61 | * of the properties file are key/value pairs of the ISO 3166 country codes | ||
| 62 | * and the ISO 4217 currency data respectively. The value part consists of | ||
| 63 | * three ISO 4217 values of a currency, i.e., an alphabetic code, a numeric | ||
| 64 | * code, and a minor unit. Those three ISO 4217 values are separated by commas. | ||
| 65 | * The lines which start with '#'s are considered comment lines. For example, | ||
| 66 | * <p> | ||
| 67 | * <code> | ||
| 68 | * #Sample currency properties<br> | ||
| 69 | * JP=JPZ,999,0 | ||
| 70 | * </code> | ||
| 71 | * <p> | ||
| 72 | * will supersede the currency data for Japan. | ||
| 73 | * | ||
| 74 | * @since 1.4 | ||
| 75 | */ | ||
| 76 | public final class Currency implements Serializable { | ||
| 77 | |||
| 78 | private static final long serialVersionUID = -158308464356906721L; | ||
| 79 | |||
| 80 | /** | ||
| 81 | * ISO 4217 currency code for this currency. | ||
| 82 | * | ||
| 83 | * @serial | ||
| 84 | */ | ||
| 85 | private final String currencyCode; | ||
| 86 | |||
| 87 | /** | ||
| 88 | * Default fraction digits for this currency. | ||
| 89 | * Set from currency data tables. | ||
| 90 | */ | ||
| 91 | transient private final int defaultFractionDigits; | ||
| 92 | |||
| 93 | /** | ||
| 94 | * ISO 4217 numeric code for this currency. | ||
| 95 | * Set from currency data tables. | ||
| 96 | */ | ||
| 97 | transient private final int numericCode; | ||
| 98 | |||
| 99 | |||
| 100 | // class data: instance map | ||
| 101 | |||
| 102 | private static HashMap<String, Currency> instances = new HashMap<String, Currency>(7); | ||
| 103 | private static HashSet<Currency> available; | ||
| 104 | |||
| 105 | |||
| 106 | // Class data: currency data obtained from currency.data file. | ||
| 107 | // Purpose: | ||
| 108 | // - determine valid country codes | ||
| 109 | // - determine valid currency codes | ||
| 110 | // - map country codes to currency codes | ||
| 111 | // - obtain default fraction digits for currency codes | ||
| 112 | // | ||
| 113 | // sc = special case; dfd = default fraction digits | ||
| 114 | // Simple countries are those where the country code is a prefix of the | ||
| 115 | // currency code, and there are no known plans to change the currency. | ||
| 116 | // | ||
| 117 | // table formats: | ||
| 118 | // - mainTable: | ||
| 119 | // - maps country code to 32-bit int | ||
| 120 | // - 26*26 entries, corresponding to [A-Z]*[A-Z] | ||
| 121 | // - \u007F -> not valid country | ||
| 122 | // - bits 18-31: unused | ||
| 123 | // - bits 8-17: numeric code (0 to 1023) | ||
| 124 | // - bit 7: 1 - special case, bits 0-4 indicate which one | ||
| 125 | // 0 - simple country, bits 0-4 indicate final char of currency code | ||
| 126 | // - bits 5-6: fraction digits for simple countries, 0 for special cases | ||
| 127 | // - bits 0-4: final char for currency code for simple country, or ID of special case | ||
| 128 | // - special case IDs: | ||
| 129 | // - 0: country has no currency | ||
| 130 | // - other: index into sc* arrays + 1 | ||
| 131 | // - scCutOverTimes: cut-over time in millis as returned by | ||
| 132 | // System.currentTimeMillis for special case countries that are changing | ||
| 133 | // currencies; Long.MAX_VALUE for countries that are not changing currencies | ||
| 134 | // - scOldCurrencies: old currencies for special case countries | ||
| 135 | // - scNewCurrencies: new currencies for special case countries that are | ||
| 136 | // changing currencies; null for others | ||
| 137 | // - scOldCurrenciesDFD: default fraction digits for old currencies | ||
| 138 | // - scNewCurrenciesDFD: default fraction digits for new currencies, 0 for | ||
| 139 | // countries that are not changing currencies | ||
| 140 | // - otherCurrencies: concatenation of all currency codes that are not the | ||
| 141 | // main currency of a simple country, separated by "-" | ||
| 142 | // - otherCurrenciesDFD: decimal format digits for currencies in otherCurrencies, same order | ||
| 143 | |||
| 144 | static int formatVersion; | ||
| 145 | static int dataVersion; | ||
| 146 | static int[] mainTable; | ||
| 147 | static long[] scCutOverTimes; | ||
| 148 | static String[] scOldCurrencies; | ||
| 149 | static String[] scNewCurrencies; | ||
| 150 | static int[] scOldCurrenciesDFD; | ||
| 151 | static int[] scNewCurrenciesDFD; | ||
| 152 | static int[] scOldCurrenciesNumericCode; | ||
| 153 | static int[] scNewCurrenciesNumericCode; | ||
| 154 | static String otherCurrencies; | ||
| 155 | static int[] otherCurrenciesDFD; | ||
| 156 | static int[] otherCurrenciesNumericCode; | ||
| 157 | |||
| 158 | // handy constants - must match definitions in GenerateCurrencyData | ||
| 159 | // magic number | ||
| 160 | private static final int MAGIC_NUMBER = 0x43757244; | ||
| 161 | // number of characters from A to Z | ||
| 162 | private static final int A_TO_Z = ('Z' - 'A') + 1; | ||
| 163 | // entry for invalid country codes | ||
| 164 | private static final int INVALID_COUNTRY_ENTRY = 0x007F; | ||
| 165 | // entry for countries without currency | ||
| 166 | private static final int COUNTRY_WITHOUT_CURRENCY_ENTRY = 0x0080; | ||
| 167 | // mask for simple case country entries | ||
| 168 | private static final int SIMPLE_CASE_COUNTRY_MASK = 0x0000; | ||
| 169 | // mask for simple case country entry final character | ||
| 170 | private static final int SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK = 0x001F; | ||
| 171 | // mask for simple case country entry default currency digits | ||
| 172 | private static final int SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK = 0x0060; | ||
| 173 | // shift count for simple case country entry default currency digits | ||
| 174 | private static final int SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT = 5; | ||
| 175 | // mask for special case country entries | ||
| 176 | private static final int SPECIAL_CASE_COUNTRY_MASK = 0x0080; | ||
| 177 | // mask for special case country index | ||
| 178 | private static final int SPECIAL_CASE_COUNTRY_INDEX_MASK = 0x001F; | ||
| 179 | // delta from entry index component in main table to index into special case tables | ||
| 180 | private static final int SPECIAL_CASE_COUNTRY_INDEX_DELTA = 1; | ||
| 181 | // mask for distinguishing simple and special case countries | ||
| 182 | private static final int COUNTRY_TYPE_MASK = SIMPLE_CASE_COUNTRY_MASK | SPECIAL_CASE_COUNTRY_MASK; | ||
| 183 | // mask for the numeric code of the currency | ||
| 184 | private static final int NUMERIC_CODE_MASK = 0x0003FF00; | ||
| 185 | // shift count for the numeric code of the currency | ||
| 186 | private static final int NUMERIC_CODE_SHIFT = 8; | ||
| 187 | |||
| 188 | // Currency data format version | ||
| 189 | private static final int VALID_FORMAT_VERSION = 1; | ||
| 190 | |||
| 191 | static { | ||
| 192 | AccessController.doPrivileged(new PrivilegedAction() { | ||
| 193 | public Object run() { | ||
| 194 | String homeDir = System.getProperty("java.home"); | ||
| 195 | try { | ||
| 196 | String dataFile = homeDir + File.separator + | ||
| 197 | "lib" + File.separator + "currency.data"; | ||
| 198 | DataInputStream dis = new DataInputStream( | ||
| 199 | new BufferedInputStream( | ||
| 200 | new FileInputStream(dataFile))); | ||
| 201 | if (dis.readInt() != MAGIC_NUMBER) { | ||
| 202 | throw new InternalError("Currency data is possibly corrupted"); | ||
| 203 | } | ||
| 204 | formatVersion = dis.readInt(); | ||
| 205 | if (formatVersion != VALID_FORMAT_VERSION) { | ||
| 206 | throw new InternalError("Currency data format is incorrect"); | ||
| 207 | } | ||
| 208 | dataVersion = dis.readInt(); | ||
| 209 | mainTable = readIntArray(dis, A_TO_Z * A_TO_Z); | ||
| 210 | int scCount = dis.readInt(); | ||
| 211 | scCutOverTimes = readLongArray(dis, scCount); | ||
| 212 | scOldCurrencies = readStringArray(dis, scCount); | ||
| 213 | scNewCurrencies = readStringArray(dis, scCount); | ||
| 214 | scOldCurrenciesDFD = readIntArray(dis, scCount); | ||
| 215 | scNewCurrenciesDFD = readIntArray(dis, scCount); | ||
| 216 | scOldCurrenciesNumericCode = readIntArray(dis, scCount); | ||
| 217 | scNewCurrenciesNumericCode = readIntArray(dis, scCount); | ||
| 218 | int ocCount = dis.readInt(); | ||
| 219 | otherCurrencies = dis.readUTF(); | ||
| 220 | otherCurrenciesDFD = readIntArray(dis, ocCount); | ||
| 221 | otherCurrenciesNumericCode = readIntArray(dis, ocCount); | ||
| 222 | dis.close(); | ||
| 223 | } catch (IOException e) { | ||
| 224 | InternalError ie = new InternalError(); | ||
| 225 | ie.initCause(e); | ||
| 226 | throw ie; | ||
| 227 | } | ||
| 228 | |||
| 229 | // look for the properties file for overrides | ||
| 230 | try { | ||
| 231 | File propFile = new File(homeDir + File.separator + | ||
| 232 | "lib" + File.separator + | ||
| 233 | "currency.properties"); | ||
| 234 | if (propFile.exists()) { | ||
| 235 | Properties props = new Properties(); | ||
| 236 | try (FileReader fr = new FileReader(propFile)) { | ||
| 237 | props.load(fr); | ||
| 238 | } | ||
| 239 | Set<String> keys = props.stringPropertyNames(); | ||
| 240 | Pattern propertiesPattern = | ||
| 241 | Pattern.compile("([A-Z]{3})\\s*,\\s*(\\d{3})\\s*,\\s*([0-3])"); | ||
| 242 | for (String key : keys) { | ||
| 243 | replaceCurrencyData(propertiesPattern, | ||
| 244 | key.toUpperCase(Locale.ROOT), | ||
| 245 | props.getProperty(key).toUpperCase(Locale.ROOT)); | ||
| 246 | } | ||
| 247 | } | ||
| 248 | } catch (IOException e) { | ||
| 249 | info("currency.properties is ignored because of an IOException", e); | ||
| 250 | } | ||
| 251 | return null; | ||
| 252 | } | ||
| 253 | }); | ||
| 254 | } | ||
| 255 | |||
| 256 | /** | ||
| 257 | * Constants for retrieving localized names from the name providers. | ||
| 258 | */ | ||
| 259 | private static final int SYMBOL = 0; | ||
| 260 | private static final int DISPLAYNAME = 1; | ||
| 261 | |||
| 262 | |||
| 263 | /** | ||
| 264 | * Constructs a <code>Currency</code> instance. The constructor is private | ||
| 265 | * so that we can insure that there's never more than one instance for a | ||
| 266 | * given currency. | ||
| 267 | */ | ||
| 268 | private Currency(String currencyCode, int defaultFractionDigits, int numericCode) { | ||
| 269 | this.currencyCode = currencyCode; | ||
| 270 | this.defaultFractionDigits = defaultFractionDigits; | ||
| 271 | this.numericCode = numericCode; | ||
| 272 | } | ||
| 273 | |||
| 274 | /** | ||
| 275 | * Returns the <code>Currency</code> instance for the given currency code. | ||
| 276 | * | ||
| 277 | * @param currencyCode the ISO 4217 code of the currency | ||
| 278 | * @return the <code>Currency</code> instance for the given currency code | ||
| 279 | * @exception NullPointerException if <code>currencyCode</code> is null | ||
| 280 | * @exception IllegalArgumentException if <code>currencyCode</code> is not | ||
| 281 | * a supported ISO 4217 code. | ||
| 282 | */ | ||
| 283 | public static Currency getInstance(String currencyCode) { | ||
| 284 | return getInstance(currencyCode, Integer.MIN_VALUE, 0); | ||
| 285 | } | ||
| 286 | |||
| 287 | private static Currency getInstance(String currencyCode, int defaultFractionDigits, | ||
| 288 | int numericCode) { | ||
| 289 | synchronized (instances) { | ||
| 290 | // Try to look up the currency code in the instances table. | ||
| 291 | // This does the null pointer check as a side effect. | ||
| 292 | // Also, if there already is an entry, the currencyCode must be valid. | ||
| 293 | Currency instance = instances.get(currencyCode); | ||
| 294 | if (instance != null) { | ||
| 295 | return instance; | ||
| 296 | } | ||
| 297 | |||
| 298 | if (defaultFractionDigits == Integer.MIN_VALUE) { | ||
| 299 | // Currency code not internally generated, need to verify first | ||
| 300 | // A currency code must have 3 characters and exist in the main table | ||
| 301 | // or in the list of other currencies. | ||
| 302 | if (currencyCode.length() != 3) { | ||
| 303 | throw new IllegalArgumentException(); | ||
| 304 | } | ||
| 305 | char char1 = currencyCode.charAt(0); | ||
| 306 | char char2 = currencyCode.charAt(1); | ||
| 307 | int tableEntry = getMainTableEntry(char1, char2); | ||
| 308 | if ((tableEntry & COUNTRY_TYPE_MASK) == SIMPLE_CASE_COUNTRY_MASK | ||
| 309 | && tableEntry != INVALID_COUNTRY_ENTRY | ||
| 310 | && currencyCode.charAt(2) - 'A' == (tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK)) { | ||
| 311 | defaultFractionDigits = (tableEntry & SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK) >> SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT; | ||
| 312 | numericCode = (tableEntry & NUMERIC_CODE_MASK) >> NUMERIC_CODE_SHIFT; | ||
| 313 | } else { | ||
| 314 | // Check for '-' separately so we don't get false hits in the table. | ||
| 315 | if (currencyCode.charAt(2) == '-') { | ||
| 316 | throw new IllegalArgumentException(); | ||
| 317 | } | ||
| 318 | int index = otherCurrencies.indexOf(currencyCode); | ||
| 319 | if (index == -1) { | ||
| 320 | throw new IllegalArgumentException(); | ||
| 321 | } | ||
| 322 | defaultFractionDigits = otherCurrenciesDFD[index / 4]; | ||
| 323 | numericCode = otherCurrenciesNumericCode[index / 4]; | ||
| 324 | } | ||
| 325 | } | ||
| 326 | |||
| 327 | instance = new Currency(currencyCode, defaultFractionDigits, numericCode); | ||
| 328 | instances.put(currencyCode, instance); | ||
| 329 | return instance; | ||
| 330 | } | ||
| 331 | } | ||
| 332 | |||
| 333 | /** | ||
| 334 | * Returns the <code>Currency</code> instance for the country of the | ||
| 335 | * given locale. The language and variant components of the locale | ||
| 336 | * are ignored. The result may vary over time, as countries change their | ||
| 337 | * currencies. For example, for the original member countries of the | ||
| 338 | * European Monetary Union, the method returns the old national currencies | ||
| 339 | * until December 31, 2001, and the Euro from January 1, 2002, local time | ||
| 340 | * of the respective countries. | ||
| 341 | * <p> | ||
| 342 | * The method returns <code>null</code> for territories that don't | ||
| 343 | * have a currency, such as Antarctica. | ||
| 344 | * | ||
| 345 | * @param locale the locale for whose country a <code>Currency</code> | ||
| 346 | * instance is needed | ||
| 347 | * @return the <code>Currency</code> instance for the country of the given | ||
| 348 | * locale, or null | ||
| 349 | * @exception NullPointerException if <code>locale</code> or its country | ||
| 350 | * code is null | ||
| 351 | * @exception IllegalArgumentException if the country of the given locale | ||
| 352 | * is not a supported ISO 3166 country code. | ||
| 353 | */ | ||
| 354 | public static Currency getInstance(Locale locale) { | ||
| 355 | String country = locale.getCountry(); | ||
| 356 | if (country == null) { | ||
| 357 | throw new NullPointerException(); | ||
| 358 | } | ||
| 359 | |||
| 360 | if (country.length() != 2) { | ||
| 361 | throw new IllegalArgumentException(); | ||
| 362 | } | ||
| 363 | |||
| 364 | char char1 = country.charAt(0); | ||
| 365 | char char2 = country.charAt(1); | ||
| 366 | int tableEntry = getMainTableEntry(char1, char2); | ||
| 367 | if ((tableEntry & COUNTRY_TYPE_MASK) == SIMPLE_CASE_COUNTRY_MASK | ||
| 368 | && tableEntry != INVALID_COUNTRY_ENTRY) { | ||
| 369 | char finalChar = (char) ((tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK) + 'A'); | ||
| 370 | int defaultFractionDigits = (tableEntry & SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK) >> SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT; | ||
| 371 | int numericCode = (tableEntry & NUMERIC_CODE_MASK) >> NUMERIC_CODE_SHIFT; | ||
| 372 | StringBuffer sb = new StringBuffer(country); | ||
| 373 | sb.append(finalChar); | ||
| 374 | return getInstance(sb.toString(), defaultFractionDigits, numericCode); | ||
| 375 | } else { | ||
| 376 | // special cases | ||
| 377 | if (tableEntry == INVALID_COUNTRY_ENTRY) { | ||
| 378 | throw new IllegalArgumentException(); | ||
| 379 | } | ||
| 380 | if (tableEntry == COUNTRY_WITHOUT_CURRENCY_ENTRY) { | ||
| 381 | return null; | ||
| 382 | } else { | ||
| 383 | int index = (tableEntry & SPECIAL_CASE_COUNTRY_INDEX_MASK) - SPECIAL_CASE_COUNTRY_INDEX_DELTA; | ||
| 384 | if (scCutOverTimes[index] == Long.MAX_VALUE || System.currentTimeMillis() < scCutOverTimes[index]) { | ||
| 385 | return getInstance(scOldCurrencies[index], scOldCurrenciesDFD[index], | ||
| 386 | scOldCurrenciesNumericCode[index]); | ||
| 387 | } else { | ||
| 388 | return getInstance(scNewCurrencies[index], scNewCurrenciesDFD[index], | ||
| 389 | scNewCurrenciesNumericCode[index]); | ||
| 390 | } | ||
| 391 | } | ||
| 392 | } | ||
| 393 | } | ||
| 394 | |||
| 395 | /** | ||
| 396 | * Gets the set of available currencies. The returned set of currencies | ||
| 397 | * contains all of the available currencies, which may include currencies | ||
| 398 | * that represent obsolete ISO 4217 codes. The set can be modified | ||
| 399 | * without affecting the available currencies in the runtime. | ||
| 400 | * | ||
| 401 | * @return the set of available currencies. If there is no currency | ||
| 402 | * available in the runtime, the returned set is empty. | ||
| 403 | * @since 1.7 | ||
| 404 | */ | ||
| 405 | public static Set<Currency> getAvailableCurrencies() { | ||
| 406 | synchronized(Currency.class) { | ||
| 407 | if (available == null) { | ||
| 408 | available = new HashSet<Currency>(256); | ||
| 409 | |||
| 410 | // Add simple currencies first | ||
| 411 | for (char c1 = 'A'; c1 <= 'Z'; c1 ++) { | ||
| 412 | for (char c2 = 'A'; c2 <= 'Z'; c2 ++) { | ||
| 413 | int tableEntry = getMainTableEntry(c1, c2); | ||
| 414 | if ((tableEntry & COUNTRY_TYPE_MASK) == SIMPLE_CASE_COUNTRY_MASK | ||
| 415 | && tableEntry != INVALID_COUNTRY_ENTRY) { | ||
| 416 | char finalChar = (char) ((tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK) + 'A'); | ||
| 417 | int defaultFractionDigits = (tableEntry & SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK) >> SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT; | ||
| 418 | int numericCode = (tableEntry & NUMERIC_CODE_MASK) >> NUMERIC_CODE_SHIFT; | ||
| 419 | StringBuilder sb = new StringBuilder(); | ||
| 420 | sb.append(c1); | ||
| 421 | sb.append(c2); | ||
| 422 | sb.append(finalChar); | ||
| 423 | available.add(getInstance(sb.toString(), defaultFractionDigits, numericCode)); | ||
| 424 | } | ||
| 425 | } | ||
| 426 | } | ||
| 427 | |||
| 428 | // Now add other currencies | ||
| 429 | StringTokenizer st = new StringTokenizer(otherCurrencies, "-"); | ||
| 430 | while (st.hasMoreElements()) { | ||
| 431 | available.add(getInstance((String)st.nextElement())); | ||
| 432 | } | ||
| 433 | } | ||
| 434 | } | ||
| 435 | |||
| 436 | return (Set<Currency>) available.clone(); | ||
| 437 | } | ||
| 438 | |||
| 439 | /** | ||
| 440 | * Gets the ISO 4217 currency code of this currency. | ||
| 441 | * | ||
| 442 | * @return the ISO 4217 currency code of this currency. | ||
| 443 | */ | ||
| 444 | public String getCurrencyCode() { | ||
| 445 | return currencyCode; | ||
| 446 | } | ||
| 447 | |||
| 448 | /** | ||
| 449 | * Gets the symbol of this currency for the default locale. | ||
| 450 | * For example, for the US Dollar, the symbol is "$" if the default | ||
| 451 | * locale is the US, while for other locales it may be "US$". If no | ||
| 452 | * symbol can be determined, the ISO 4217 currency code is returned. | ||
| 453 | * | ||
| 454 | * @return the symbol of this currency for the default locale | ||
| 455 | */ | ||
| 456 | public String getSymbol() { | ||
| 457 | return getSymbol(Locale.getDefault(Locale.Category.DISPLAY)); | ||
| 458 | } | ||
| 459 | |||
| 460 | /** | ||
| 461 | * Gets the symbol of this currency for the specified locale. | ||
| 462 | * For example, for the US Dollar, the symbol is "$" if the specified | ||
| 463 | * locale is the US, while for other locales it may be "US$". If no | ||
| 464 | * symbol can be determined, the ISO 4217 currency code is returned. | ||
| 465 | * | ||
| 466 | * @param locale the locale for which a display name for this currency is | ||
| 467 | * needed | ||
| 468 | * @return the symbol of this currency for the specified locale | ||
| 469 | * @exception NullPointerException if <code>locale</code> is null | ||
| 470 | */ | ||
| 471 | public String getSymbol(Locale locale) { | ||
| 472 | try { | ||
| 473 | // Check whether a provider can provide an implementation that's closer | ||
| 474 | // to the requested locale than what the Java runtime itself can provide. | ||
| 475 | LocaleServiceProviderPool pool = | ||
| 476 | LocaleServiceProviderPool.getPool(CurrencyNameProvider.class); | ||
| 477 | |||
| 478 | if (pool.hasProviders()) { | ||
| 479 | // Assuming that all the country locales include necessary currency | ||
| 480 | // symbols in the Java runtime's resources, so there is no need to | ||
| 481 | // examine whether Java runtime's currency resource bundle is missing | ||
| 482 | // names. Therefore, no resource bundle is provided for calling this | ||
| 483 | // method. | ||
| 484 | String symbol = pool.getLocalizedObject( | ||
| 485 | CurrencyNameGetter.INSTANCE, | ||
| 486 | locale, (OpenListResourceBundle)null, | ||
| 487 | currencyCode, SYMBOL); | ||
| 488 | if (symbol != null) { | ||
| 489 | return symbol; | ||
| 490 | } | ||
| 491 | } | ||
| 492 | |||
| 493 | ResourceBundle bundle = LocaleData.getCurrencyNames(locale); | ||
| 494 | return bundle.getString(currencyCode); | ||
| 495 | } catch (MissingResourceException e) { | ||
| 496 | // use currency code as symbol of last resort | ||
| 497 | return currencyCode; | ||
| 498 | } | ||
| 499 | } | ||
| 500 | |||
| 501 | /** | ||
| 502 | * Gets the default number of fraction digits used with this currency. | ||
| 503 | * For example, the default number of fraction digits for the Euro is 2, | ||
| 504 | * while for the Japanese Yen it's 0. | ||
| 505 | * In the case of pseudo-currencies, such as IMF Special Drawing Rights, | ||
| 506 | * -1 is returned. | ||
| 507 | * | ||
| 508 | * @return the default number of fraction digits used with this currency | ||
| 509 | */ | ||
| 510 | public int getDefaultFractionDigits() { | ||
| 511 | return defaultFractionDigits; | ||
| 512 | } | ||
| 513 | |||
| 514 | /** | ||
| 515 | * Returns the ISO 4217 numeric code of this currency. | ||
| 516 | * | ||
| 517 | * @return the ISO 4217 numeric code of this currency | ||
| 518 | * @since 1.7 | ||
| 519 | */ | ||
| 520 | public int getNumericCode() { | ||
| 521 | return numericCode; | ||
| 522 | } | ||
| 523 | |||
| 524 | /** | ||
| 525 | * Gets the name that is suitable for displaying this currency for | ||
| 526 | * the default locale. If there is no suitable display name found | ||
| 527 | * for the default locale, the ISO 4217 currency code is returned. | ||
| 528 | * | ||
| 529 | * @return the display name of this currency for the default locale | ||
| 530 | * @since 1.7 | ||
| 531 | */ | ||
| 532 | public String getDisplayName() { | ||
| 533 | return getDisplayName(Locale.getDefault(Locale.Category.DISPLAY)); | ||
| 534 | } | ||
| 535 | |||
| 536 | /** | ||
| 537 | * Gets the name that is suitable for displaying this currency for | ||
| 538 | * the specified locale. If there is no suitable display name found | ||
| 539 | * for the specified locale, the ISO 4217 currency code is returned. | ||
| 540 | * | ||
| 541 | * @param locale the locale for which a display name for this currency is | ||
| 542 | * needed | ||
| 543 | * @return the display name of this currency for the specified locale | ||
| 544 | * @exception NullPointerException if <code>locale</code> is null | ||
| 545 | * @since 1.7 | ||
| 546 | */ | ||
| 547 | public String getDisplayName(Locale locale) { | ||
| 548 | try { | ||
| 549 | OpenListResourceBundle bundle = LocaleData.getCurrencyNames(locale); | ||
| 550 | String result = null; | ||
| 551 | String bundleKey = currencyCode.toLowerCase(Locale.ROOT); | ||
| 552 | |||
| 553 | // Check whether a provider can provide an implementation that's closer | ||
| 554 | // to the requested locale than what the Java runtime itself can provide. | ||
| 555 | LocaleServiceProviderPool pool = | ||
| 556 | LocaleServiceProviderPool.getPool(CurrencyNameProvider.class); | ||
| 557 | if (pool.hasProviders()) { | ||
| 558 | result = pool.getLocalizedObject( | ||
| 559 | CurrencyNameGetter.INSTANCE, | ||
| 560 | locale, bundleKey, bundle, currencyCode, DISPLAYNAME); | ||
| 561 | } | ||
| 562 | |||
| 563 | if (result == null) { | ||
| 564 | result = bundle.getString(bundleKey); | ||
| 565 | } | ||
| 566 | |||
| 567 | if (result != null) { | ||
| 568 | return result; | ||
| 569 | } | ||
| 570 | } catch (MissingResourceException e) { | ||
| 571 | // fall through | ||
| 572 | } | ||
| 573 | |||
| 574 | // use currency code as symbol of last resort | ||
| 575 | return currencyCode; | ||
| 576 | } | ||
| 577 | |||
| 578 | /** | ||
| 579 | * Returns the ISO 4217 currency code of this currency. | ||
| 580 | * | ||
| 581 | * @return the ISO 4217 currency code of this currency | ||
| 582 | */ | ||
| 583 | public String toString() { | ||
| 584 | return currencyCode; | ||
| 585 | } | ||
| 586 | |||
| 587 | /** | ||
| 588 | * Resolves instances being deserialized to a single instance per currency. | ||
| 589 | */ | ||
| 590 | private Object readResolve() { | ||
| 591 | return getInstance(currencyCode); | ||
| 592 | } | ||
| 593 | |||
| 594 | /** | ||
| 595 | * Gets the main table entry for the country whose country code consists | ||
| 596 | * of char1 and char2. | ||
| 597 | */ | ||
| 598 | private static int getMainTableEntry(char char1, char char2) { | ||
| 599 | if (char1 < 'A' || char1 > 'Z' || char2 < 'A' || char2 > 'Z') { | ||
| 600 | throw new IllegalArgumentException(); | ||
| 601 | } | ||
| 602 | return mainTable[(char1 - 'A') * A_TO_Z + (char2 - 'A')]; | ||
| 603 | } | ||
| 604 | |||
| 605 | /** | ||
| 606 | * Sets the main table entry for the country whose country code consists | ||
| 607 | * of char1 and char2. | ||
| 608 | */ | ||
| 609 | private static void setMainTableEntry(char char1, char char2, int entry) { | ||
| 610 | if (char1 < 'A' || char1 > 'Z' || char2 < 'A' || char2 > 'Z') { | ||
| 611 | throw new IllegalArgumentException(); | ||
| 612 | } | ||
| 613 | mainTable[(char1 - 'A') * A_TO_Z + (char2 - 'A')] = entry; | ||
| 614 | } | ||
| 615 | |||
| 616 | /** | ||
| 617 | * Obtains a localized currency names from a CurrencyNameProvider | ||
| 618 | * implementation. | ||
| 619 | */ | ||
| 620 | private static class CurrencyNameGetter | ||
| 621 | implements LocaleServiceProviderPool.LocalizedObjectGetter<CurrencyNameProvider, | ||
| 622 | String> { | ||
| 623 | private static final CurrencyNameGetter INSTANCE = new CurrencyNameGetter(); | ||
| 624 | |||
| 625 | public String getObject(CurrencyNameProvider currencyNameProvider, | ||
| 626 | Locale locale, | ||
| 627 | String key, | ||
| 628 | Object... params) { | ||
| 629 | assert params.length == 1; | ||
| 630 | int type = (Integer)params[0]; | ||
| 631 | |||
| 632 | switch(type) { | ||
| 633 | case SYMBOL: | ||
| 634 | return currencyNameProvider.getSymbol(key, locale); | ||
| 635 | case DISPLAYNAME: | ||
| 636 | return currencyNameProvider.getDisplayName(key, locale); | ||
| 637 | default: | ||
| 638 | assert false; // shouldn't happen | ||
| 639 | } | ||
| 640 | |||
| 641 | return null; | ||
| 642 | } | ||
| 643 | } | ||
| 644 | |||
| 645 | private static int[] readIntArray(DataInputStream dis, int count) throws IOException { | ||
| 646 | int[] ret = new int[count]; | ||
| 647 | for (int i = 0; i < count; i++) { | ||
| 648 | ret[i] = dis.readInt(); | ||
| 649 | } | ||
| 650 | |||
| 651 | return ret; | ||
| 652 | } | ||
| 653 | |||
| 654 | private static long[] readLongArray(DataInputStream dis, int count) throws IOException { | ||
| 655 | long[] ret = new long[count]; | ||
| 656 | for (int i = 0; i < count; i++) { | ||
| 657 | ret[i] = dis.readLong(); | ||
| 658 | } | ||
| 659 | |||
| 660 | return ret; | ||
| 661 | } | ||
| 662 | |||
| 663 | private static String[] readStringArray(DataInputStream dis, int count) throws IOException { | ||
| 664 | String[] ret = new String[count]; | ||
| 665 | for (int i = 0; i < count; i++) { | ||
| 666 | ret[i] = dis.readUTF(); | ||
| 667 | } | ||
| 668 | |||
| 669 | return ret; | ||
| 670 | } | ||
| 671 | |||
| 672 | /** | ||
| 673 | * Replaces currency data found in the currencydata.properties file | ||
| 674 | * | ||
| 675 | * @param pattern regex pattern for the properties | ||
| 676 | * @param ctry country code | ||
| 677 | * @param data currency data. This is a comma separated string that | ||
| 678 | * consists of "three-letter alphabet code", "three-digit numeric code", | ||
| 679 | * and "one-digit (0,1,2, or 3) default fraction digit". | ||
| 680 | * For example, "JPZ,392,0". | ||
| 681 | * @throws | ||
| 682 | */ | ||
| 683 | private static void replaceCurrencyData(Pattern pattern, String ctry, String curdata) { | ||
| 684 | |||
| 685 | if (ctry.length() != 2) { | ||
| 686 | // ignore invalid country code | ||
| 687 | String message = new StringBuilder() | ||
| 688 | .append("The entry in currency.properties for ") | ||
| 689 | .append(ctry).append(" is ignored because of the invalid country code.") | ||
| 690 | .toString(); | ||
| 691 | info(message, null); | ||
| 692 | return; | ||
| 693 | } | ||
| 694 | |||
| 695 | Matcher m = pattern.matcher(curdata); | ||
| 696 | if (!m.find()) { | ||
| 697 | // format is not recognized. ignore the data | ||
| 698 | String message = new StringBuilder() | ||
| 699 | .append("The entry in currency.properties for ") | ||
| 700 | .append(ctry) | ||
| 701 | .append(" is ignored because the value format is not recognized.") | ||
| 702 | .toString(); | ||
| 703 | info(message, null); | ||
| 704 | return; | ||
| 705 | } | ||
| 706 | |||
| 707 | String code = m.group(1); | ||
| 708 | int numeric = Integer.parseInt(m.group(2)); | ||
| 709 | int fraction = Integer.parseInt(m.group(3)); | ||
| 710 | int entry = numeric << NUMERIC_CODE_SHIFT; | ||
| 711 | |||
| 712 | int index; | ||
| 713 | for (index = 0; index < scOldCurrencies.length; index++) { | ||
| 714 | if (scOldCurrencies[index].equals(code)) { | ||
| 715 | break; | ||
| 716 | } | ||
| 717 | } | ||
| 718 | |||
| 719 | if (index == scOldCurrencies.length) { | ||
| 720 | // simple case | ||
| 721 | entry |= (fraction << SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT) | | ||
| 722 | (code.charAt(2) - 'A'); | ||
| 723 | } else { | ||
| 724 | // special case | ||
| 725 | entry |= SPECIAL_CASE_COUNTRY_MASK | | ||
| 726 | (index + SPECIAL_CASE_COUNTRY_INDEX_DELTA); | ||
| 727 | } | ||
| 728 | setMainTableEntry(ctry.charAt(0), ctry.charAt(1), entry); | ||
| 729 | } | ||
| 730 | |||
| 731 | private static void info(String message, Throwable t) { | ||
| 732 | PlatformLogger logger = PlatformLogger.getLogger("java.util.Currency"); | ||
| 733 | if (logger.isLoggable(PlatformLogger.INFO)) { | ||
| 734 | if (t != null) { | ||
| 735 | logger.info(message, t); | ||
| 736 | } else { | ||
| 737 | logger.info(message); | ||
| 738 | } | ||
| 739 | } | ||
| 740 | } | ||
| 741 | } | ||
| @@ -0,0 +1,586 @@ | |||
| 1 | # | ||
| 2 | # Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | # | ||
| 5 | # This code is free software; you can redistribute it and/or modify it | ||
| 6 | # under the terms of the GNU General Public License version 2 only, as | ||
| 7 | # published by the Free Software Foundation. Oracle designates this | ||
| 8 | # particular file as subject to the "Classpath" exception as provided | ||
| 9 | # by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | # | ||
| 11 | # This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | # version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | # accompanied this code). | ||
| 16 | # | ||
| 17 | # You should have received a copy of the GNU General Public License version | ||
| 18 | # 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | # | ||
| 21 | # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | # or visit www.oracle.com if you need additional information or have any | ||
| 23 | # questions. | ||
| 24 | # | ||
| 25 | |||
| 26 | formatVersion=1 | ||
| 27 | |||
| 28 | # Version of the currency code information in this class. | ||
| 29 | # It is a serial number that accompanies with each amendment, such as | ||
| 30 | # 'MAxxx.doc' | ||
| 31 | |||
| 32 | dataVersion=140 | ||
| 33 | |||
| 34 | # List of all valid ISO 4217 currency codes. | ||
| 35 | # To ensure compatibility, do not remove codes. | ||
| 36 | |||
| 37 | all=ADP020-AED784-AFA004-AFN971-ALL008-AMD051-ANG532-AOA973-ARS032-ATS040-AUD036-\ | ||
| 38 | AWG533-AYM945-AZM031-AZN944-BAM977-BBD052-BDT050-BEF056-BGL100-BGN975-BHD048-BIF108-\ | ||
| 39 | BMD060-BND096-BOB068-BOV984-BRL986-BSD044-BTN064-BWP072-BYB112-BYR974-\ | ||
| 40 | BZD084-CAD124-CDF976-CHF756-CLF990-CLP152-CNY156-COP170-CRC188-CSD891-CUP192-\ | ||
| 41 | CVE132-CYP196-CZK203-DEM276-DJF262-DKK208-DOP214-DZD012-EEK233-EGP818-\ | ||
| 42 | ERN232-ESP724-ETB230-EUR978-FIM246-FJD242-FKP238-FRF250-GBP826-GEL981-\ | ||
| 43 | GHC288-GHS936-GIP292-GMD270-GNF324-GRD300-GTQ320-GWP624-GYD328-HKD344-HNL340-\ | ||
| 44 | HRK191-HTG332-HUF348-IDR360-IEP372-ILS376-INR356-IQD368-IRR364-ISK352-\ | ||
| 45 | ITL380-JMD388-JOD400-JPY392-KES404-KGS417-KHR116-KMF174-KPW408-KRW410-\ | ||
| 46 | KWD414-KYD136-KZT398-LAK418-LBP422-LKR144-LRD430-LSL426-LTL440-LUF442-\ | ||
| 47 | LVL428-LYD434-MAD504-MDL498-MGA969-MGF450-MKD807-MMK104-MNT496-MOP446-MRO478-\ | ||
| 48 | MTL470-MUR480-MVR462-MWK454-MXN484-MXV979-MYR458-MZM508-MZN943-NAD516-NGN566-\ | ||
| 49 | NIO558-NLG528-NOK578-NPR524-NZD554-OMR512-PAB590-PEN604-PGK598-PHP608-\ | ||
| 50 | PKR586-PLN985-PTE620-PYG600-QAR634-ROL946-RON946-RSD941-RUB643-RUR810-RWF646-SAR682-\ | ||
| 51 | SBD090-SCR690-SDD736-SDG938-SEK752-SGD702-SHP654-SIT705-SKK703-SLL694-SOS706-\ | ||
| 52 | SRD968-SRG740-STD678-SVC222-SYP760-SZL748-THB764-TJS972-TMM795-TND788-TOP776-\ | ||
| 53 | TPE626-TRL792-TRY949-TTD780-TWD901-TZS834-UAH980-UGX800-USD840-USN997-USS998-\ | ||
| 54 | UYU858-UZS860-VEB862-VEF937-VND704-VUV548-WST882-XAF950-XAG961-XAU959-XBA955-\ | ||
| 55 | XBB956-XBC957-XBD958-XCD951-XDR960-XFO000-XFU000-XOF952-XPD964-XPF953-\ | ||
| 56 | XPT962-XTS963-XXX999-YER886-YUM891-ZAR710-ZMK894-ZWD716-ZWN942 | ||
| 57 | |||
| 58 | |||
| 59 | # Mappings from ISO 3166 country codes to ISO 4217 currency codes. | ||
| 60 | # | ||
| 61 | # Three forms are used: | ||
| 62 | # Form 1: <country code>=<currency code> | ||
| 63 | # Form 2: <country code>=<currency code 1>;<time stamp>;<currency code 2> | ||
| 64 | # Form 3: <country code>= | ||
| 65 | # Form 1 is used if no future change in currency is known. | ||
| 66 | # Form 2 indicates that before the specified time currency 1 is used, from | ||
| 67 | # the specified time currency 2. The time is given in SimpleDateFormat's | ||
| 68 | # yyyy-MM-dd-HH-mm-ss format in the GMT time zone. | ||
| 69 | # Form 3 indicates the country doesn't have a currency (the entry is still | ||
| 70 | # needed to verify that the country code is valid). | ||
| 71 | # | ||
| 72 | # The table is based on the following web sites: | ||
| 73 | # http://www.din.de/gremien/nas/nabd/iso3166ma/codlstp1/db_en.html | ||
| 74 | # http://www.bsi-global.com/iso4217currency | ||
| 75 | # http://www.cia.gov/cia/publications/factbook/indexgeo.html | ||
| 76 | |||
| 77 | # AFGHANISTAN | ||
| 78 | AF=AFN | ||
| 79 | # \u00c5LAND ISLANDS | ||
| 80 | AX=EUR | ||
| 81 | # ALBANIA | ||
| 82 | AL=ALL | ||
| 83 | # ALGERIA | ||
| 84 | DZ=DZD | ||
| 85 | # AMERICAN SAMOA | ||
| 86 | AS=USD | ||
| 87 | # ANDORRA | ||
| 88 | AD=EUR | ||
| 89 | # ANGOLA | ||
| 90 | AO=AOA | ||
| 91 | # ANGUILLA | ||
| 92 | AI=XCD | ||
| 93 | # ANTARCTICA | ||
| 94 | AQ= | ||
| 95 | # ANTIGUA AND BARBUDA | ||
| 96 | AG=XCD | ||
| 97 | # ARGENTINA | ||
| 98 | AR=ARS | ||
| 99 | # ARMENIA | ||
| 100 | AM=AMD | ||
| 101 | # ARUBA | ||
| 102 | AW=AWG | ||
| 103 | # AUSTRALIA | ||
| 104 | AU=AUD | ||
| 105 | # AUSTRIA | ||
| 106 | AT=EUR | ||
| 107 | # AZERBAIJAN | ||
| 108 | AZ=AZM;2005-12-31-20-00-00;AZN | ||
| 109 | # BAHAMAS | ||
| 110 | BS=BSD | ||
| 111 | # BAHRAIN | ||
| 112 | BH=BHD | ||
| 113 | # BANGLADESH | ||
| 114 | BD=BDT | ||
| 115 | # BARBADOS | ||
| 116 | BB=BBD | ||
| 117 | # BELARUS | ||
| 118 | BY=BYR | ||
| 119 | # BELGIUM | ||
| 120 | BE=EUR | ||
| 121 | # BELIZE | ||
| 122 | BZ=BZD | ||
| 123 | # BENIN | ||
| 124 | BJ=XOF | ||
| 125 | # BERMUDA | ||
| 126 | BM=BMD | ||
| 127 | # BHUTAN | ||
| 128 | BT=BTN | ||
| 129 | # BOLIVIA | ||
| 130 | BO=BOB | ||
| 131 | # BOSNIA AND HERZEGOVINA | ||
| 132 | BA=BAM | ||
| 133 | # BOTSWANA | ||
| 134 | BW=BWP | ||
| 135 | # BOUVET ISLAND | ||
| 136 | BV=NOK | ||
| 137 | # BRAZIL | ||
| 138 | BR=BRL | ||
| 139 | # BRITISH INDIAN OCEAN TERRITORY | ||
| 140 | IO=USD | ||
| 141 | # BRUNEI DARUSSALAM | ||
| 142 | BN=BND | ||
| 143 | # BULGARIA | ||
| 144 | BG=BGN | ||
| 145 | # BURKINA FASO | ||
| 146 | BF=XOF | ||
| 147 | # BURUNDI | ||
| 148 | BI=BIF | ||
| 149 | # CAMBODIA | ||
| 150 | KH=KHR | ||
| 151 | # CAMEROON | ||
| 152 | CM=XAF | ||
| 153 | # CANADA | ||
| 154 | CA=CAD | ||
| 155 | # CAPE VERDE | ||
| 156 | CV=CVE | ||
| 157 | # CAYMAN ISLANDS | ||
| 158 | KY=KYD | ||
| 159 | # CENTRAL AFRICAN REPUBLIC | ||
| 160 | CF=XAF | ||
| 161 | # CHAD | ||
| 162 | TD=XAF | ||
| 163 | # CHILE | ||
| 164 | CL=CLP | ||
| 165 | # CHINA | ||
| 166 | CN=CNY | ||
| 167 | # CHRISTMAS ISLAND | ||
| 168 | CX=AUD | ||
| 169 | # COCOS (KEELING) ISLANDS | ||
| 170 | CC=AUD | ||
| 171 | # COLOMBIA | ||
| 172 | CO=COP | ||
| 173 | # COMOROS | ||
| 174 | KM=KMF | ||
| 175 | # CONGO | ||
| 176 | CG=XAF | ||
| 177 | # CONGO, THE DEMOCRATIC REPUBLIC OF THE | ||
| 178 | CD=CDF | ||
| 179 | # COOK ISLANDS | ||
| 180 | CK=NZD | ||
| 181 | # COSTA RICA | ||
| 182 | CR=CRC | ||
| 183 | # COTE D'IVOIRE | ||
| 184 | CI=XOF | ||
| 185 | # CROATIA | ||
| 186 | HR=HRK | ||
| 187 | # CUBA | ||
| 188 | CU=CUP | ||
| 189 | # CYPRUS | ||
| 190 | CY=EUR | ||
| 191 | # CZECH REPUBLIC | ||
| 192 | CZ=CZK | ||
| 193 | # DENMARK | ||
| 194 | DK=DKK | ||
| 195 | # DJIBOUTI | ||
| 196 | DJ=DJF | ||
| 197 | # DOMINICA | ||
| 198 | DM=XCD | ||
| 199 | # DOMINICAN REPUBLIC | ||
| 200 | DO=DOP | ||
| 201 | # ECUADOR | ||
| 202 | EC=USD | ||
| 203 | # EGYPT | ||
| 204 | EG=EGP | ||
| 205 | # EL SALVADOR | ||
| 206 | # USD is also legal currency as of 2001/01/01 | ||
| 207 | SV=SVC | ||
| 208 | # EQUATORIAL GUINEA | ||
| 209 | GQ=XAF | ||
| 210 | # ERITREA | ||
| 211 | ER=ERN | ||
| 212 | # ESTONIA | ||
| 213 | EE=EEK | ||
| 214 | # ETHIOPIA | ||
| 215 | ET=ETB | ||
| 216 | # FALKLAND ISLANDS (MALVINAS) | ||
| 217 | FK=FKP | ||
| 218 | # FAROE ISLANDS | ||
| 219 | FO=DKK | ||
| 220 | # FIJI | ||
| 221 | FJ=FJD | ||
| 222 | # FINLAND | ||
| 223 | FI=EUR | ||
| 224 | # FRANCE | ||
| 225 | FR=EUR | ||
| 226 | # FRENCH GUIANA | ||
| 227 | GF=EUR | ||
| 228 | # FRENCH POLYNESIA | ||
| 229 | PF=XPF | ||
| 230 | # FRENCH SOUTHERN TERRITORIES | ||
| 231 | TF=EUR | ||
| 232 | # GABON | ||
| 233 | GA=XAF | ||
| 234 | # GAMBIA | ||
| 235 | GM=GMD | ||
| 236 | # GEORGIA | ||
| 237 | GE=GEL | ||
| 238 | # GERMANY | ||
| 239 | DE=EUR | ||
| 240 | # GHANA | ||
| 241 | GH=GHS | ||
| 242 | # GIBRALTAR | ||
| 243 | GI=GIP | ||
| 244 | # GREECE | ||
| 245 | GR=EUR | ||
| 246 | # GREENLAND | ||
| 247 | GL=DKK | ||
| 248 | # GRENADA | ||
| 249 | GD=XCD | ||
| 250 | # GUADELOUPE | ||
| 251 | GP=EUR | ||
| 252 | # GUAM | ||
| 253 | GU=USD | ||
| 254 | # GUATEMALA | ||
| 255 | GT=GTQ | ||
| 256 | # GUERNSEY | ||
| 257 | GG=GBP | ||
| 258 | # GUINEA | ||
| 259 | GN=GNF | ||
| 260 | # GUINEA-BISSAU | ||
| 261 | GW=XOF | ||
| 262 | # GUYANA | ||
| 263 | GY=GYD | ||
| 264 | # HAITI | ||
| 265 | HT=HTG | ||
| 266 | # HEARD ISLAND AND MCDONALD ISLANDS | ||
| 267 | HM=AUD | ||
| 268 | # HOLY SEE (VATICAN CITY STATE) | ||
| 269 | VA=EUR | ||
| 270 | # HONDURAS | ||
| 271 | HN=HNL | ||
| 272 | # HONG KONG | ||
| 273 | HK=HKD | ||
| 274 | # HUNGARY | ||
| 275 | HU=HUF | ||
| 276 | # ICELAND | ||
| 277 | IS=ISK | ||
| 278 | # INDIA | ||
| 279 | IN=INR | ||
| 280 | # INDONESIA | ||
| 281 | ID=IDR | ||
| 282 | # IRAN, ISLAMIC REPUBLIC OF | ||
| 283 | IR=IRR | ||
| 284 | # IRAQ | ||
| 285 | IQ=IQD | ||
| 286 | # IRELAND | ||
| 287 | IE=EUR | ||
| 288 | # ISLE OF MAN | ||
| 289 | IM=GBP | ||
| 290 | # ISRAEL | ||
| 291 | IL=ILS | ||
| 292 | # ITALY | ||
| 293 | IT=EUR | ||
| 294 | # JAMAICA | ||
| 295 | JM=JMD | ||
| 296 | # JAPAN | ||
| 297 | JP=JPY | ||
| 298 | # JERSEY | ||
| 299 | JE=GBP | ||
| 300 | # JORDAN | ||
| 301 | JO=JOD | ||
| 302 | # KAZAKSTAN | ||
| 303 | KZ=KZT | ||
| 304 | # KENYA | ||
| 305 | KE=KES | ||
| 306 | # KIRIBATI | ||
| 307 | KI=AUD | ||
| 308 | # KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF | ||
| 309 | KP=KPW | ||
| 310 | # KOREA, REPUBLIC OF | ||
| 311 | KR=KRW | ||
| 312 | # KUWAIT | ||
| 313 | KW=KWD | ||
| 314 | # KYRGYZSTAN | ||
| 315 | KG=KGS | ||
| 316 | # LAO PEOPLE'S DEMOCRATIC REPUBLIC | ||
| 317 | LA=LAK | ||
| 318 | # LATVIA | ||
| 319 | LV=LVL | ||
| 320 | # LEBANON | ||
| 321 | LB=LBP | ||
| 322 | # LESOTHO | ||
| 323 | LS=LSL | ||
| 324 | # LIBERIA | ||
| 325 | LR=LRD | ||
| 326 | # LIBYAN ARAB JAMAHIRIYA | ||
| 327 | LY=LYD | ||
| 328 | # LIECHTENSTEIN | ||
| 329 | LI=CHF | ||
| 330 | # LITHUANIA | ||
| 331 | LT=LTL | ||
| 332 | # LUXEMBOURG | ||
| 333 | LU=EUR | ||
| 334 | # MACAU | ||
| 335 | MO=MOP | ||
| 336 | # MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF | ||
| 337 | MK=MKD | ||
| 338 | # MADAGASCAR | ||
| 339 | MG=MGA | ||
| 340 | # MALAWI | ||
| 341 | MW=MWK | ||
| 342 | # MALAYSIA | ||
| 343 | MY=MYR | ||
| 344 | # MALDIVES | ||
| 345 | MV=MVR | ||
| 346 | # MALI | ||
| 347 | ML=XOF | ||
| 348 | # MALTA | ||
| 349 | MT=EUR | ||
| 350 | # MARSHALL ISLANDS | ||
| 351 | MH=USD | ||
| 352 | # MARTINIQUE | ||
| 353 | MQ=EUR | ||
| 354 | # MAURITANIA | ||
| 355 | MR=MRO | ||
| 356 | # MAURITIUS | ||
| 357 | MU=MUR | ||
| 358 | # MAYOTTE | ||
| 359 | YT=EUR | ||
| 360 | # MEXICO | ||
| 361 | MX=MXN | ||
| 362 | # MICRONESIA, FEDERATED STATES OF | ||
| 363 | FM=USD | ||
| 364 | # MOLDOVA, REPUBLIC OF | ||
| 365 | MD=MDL | ||
| 366 | # MONACO | ||
| 367 | MC=EUR | ||
| 368 | # MONGOLIA | ||
| 369 | MN=MNT | ||
| 370 | # MONTENEGRO | ||
| 371 | ME=EUR | ||
| 372 | # MONTSERRAT | ||
| 373 | MS=XCD | ||
| 374 | # MOROCCO | ||
| 375 | MA=MAD | ||
| 376 | # MOZAMBIQUE | ||
| 377 | MZ=MZM;2006-06-30-22-00-00;MZN | ||
| 378 | # MYANMAR | ||
| 379 | MM=MMK | ||
| 380 | # NAMIBIA | ||
| 381 | NA=NAD | ||
| 382 | # NAURU | ||
| 383 | NR=AUD | ||
| 384 | # NEPAL | ||
| 385 | NP=NPR | ||
| 386 | # NETHERLANDS | ||
| 387 | NL=EUR | ||
| 388 | # NETHERLANDS ANTILLES | ||
| 389 | AN=ANG | ||
| 390 | # NEW CALEDONIA | ||
| 391 | NC=XPF | ||
| 392 | # NEW ZEALAND | ||
| 393 | NZ=NZD | ||
| 394 | # NICARAGUA | ||
| 395 | NI=NIO | ||
| 396 | # NIGER | ||
| 397 | NE=XOF | ||
| 398 | # NIGERIA | ||
| 399 | NG=NGN | ||
| 400 | # NIUE | ||
| 401 | NU=NZD | ||
| 402 | # NORFOLK ISLAND | ||
| 403 | NF=AUD | ||
| 404 | # NORTHERN MARIANA ISLANDS | ||
| 405 | MP=USD | ||
| 406 | # NORWAY | ||
| 407 | NO=NOK | ||
| 408 | # OMAN | ||
| 409 | OM=OMR | ||
| 410 | # PAKISTAN | ||
| 411 | PK=PKR | ||
| 412 | # PALAU | ||
| 413 | PW=USD | ||
| 414 | # PALESTINIAN TERRITORY, OCCUPIED | ||
| 415 | PS=ILS | ||
| 416 | # PANAMA | ||
| 417 | PA=PAB | ||
| 418 | # PAPUA NEW GUINEA | ||
| 419 | PG=PGK | ||
| 420 | # PARAGUAY | ||
| 421 | PY=PYG | ||
| 422 | # PERU | ||
| 423 | PE=PEN | ||
| 424 | # PHILIPPINES | ||
| 425 | PH=PHP | ||
| 426 | # PITCAIRN | ||
| 427 | PN=NZD | ||
| 428 | # POLAND | ||
| 429 | PL=PLN | ||
| 430 | # PORTUGAL | ||
| 431 | PT=EUR | ||
| 432 | # PUERTO RICO | ||
| 433 | PR=USD | ||
| 434 | # QATAR | ||
| 435 | QA=QAR | ||
| 436 | # REUNION | ||
| 437 | RE=EUR | ||
| 438 | # ROMANIA | ||
| 439 | RO=ROL;2005-06-30-21-00-00;RON | ||
| 440 | # RUSSIAN FEDERATION | ||
| 441 | RU=RUB | ||
| 442 | # RWANDA | ||
| 443 | RW=RWF | ||
| 444 | # SAINT BARTHELEMY | ||
| 445 | BL=EUR | ||
| 446 | # SAINT HELENA | ||
| 447 | SH=SHP | ||
| 448 | # SAINT KITTS AND NEVIS | ||
| 449 | KN=XCD | ||
| 450 | # SAINT LUCIA | ||
| 451 | LC=XCD | ||
| 452 | # SAINT MARTIN | ||
| 453 | MF=EUR | ||
| 454 | # SAINT PIERRE AND MIQUELON | ||
| 455 | PM=EUR | ||
| 456 | # SAINT VINCENT AND THE GRENADINES | ||
| 457 | VC=XCD | ||
| 458 | # SAMOA | ||
| 459 | WS=WST | ||
| 460 | # SAN MARINO | ||
| 461 | SM=EUR | ||
| 462 | # SAO TOME AND PRINCIPE | ||
| 463 | ST=STD | ||
| 464 | # SAUDI ARABIA | ||
| 465 | SA=SAR | ||
| 466 | # SENEGAL | ||
| 467 | SN=XOF | ||
| 468 | # SERBIA | ||
| 469 | RS=RSD | ||
| 470 | # SERBIA AND MONTENEGRO | ||
| 471 | CS=CSD | ||
| 472 | # SEYCHELLES | ||
| 473 | SC=SCR | ||
| 474 | # SIERRA LEONE | ||
| 475 | SL=SLL | ||
| 476 | # SINGAPORE | ||
| 477 | SG=SGD | ||
| 478 | # SLOVAKIA | ||
| 479 | SK=SKK | ||
| 480 | # SLOVENIA | ||
| 481 | SI=EUR | ||
| 482 | # SOLOMON ISLANDS | ||
| 483 | SB=SBD | ||
| 484 | # SOMALIA | ||
| 485 | SO=SOS | ||
| 486 | # SOUTH AFRICA | ||
| 487 | ZA=ZAR | ||
| 488 | # SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS | ||
| 489 | GS=GBP | ||
| 490 | # SPAIN | ||
| 491 | ES=EUR | ||
| 492 | # SRI LANKA | ||
| 493 | LK=LKR | ||
| 494 | # SUDAN | ||
| 495 | SD=SDG | ||
| 496 | # SURINAME | ||
| 497 | SR=SRD | ||
| 498 | # SVALBARD AND JAN MAYEN | ||
| 499 | SJ=NOK | ||
| 500 | # SWAZILAND | ||
| 501 | SZ=SZL | ||
| 502 | # SWEDEN | ||
| 503 | SE=SEK | ||
| 504 | # SWITZERLAND | ||
| 505 | CH=CHF | ||
| 506 | # SYRIAN ARAB REPUBLIC | ||
| 507 | SY=SYP | ||
| 508 | # TAIWAN | ||
| 509 | TW=TWD | ||
| 510 | # TAJIKISTAN | ||
| 511 | TJ=TJS | ||
| 512 | # TANZANIA, UNITED REPUBLIC OF | ||
| 513 | TZ=TZS | ||
| 514 | # THAILAND | ||
| 515 | TH=THB | ||
| 516 | # TIMOR-LESTE | ||
| 517 | TL=USD | ||
| 518 | # TOGO | ||
| 519 | TG=XOF | ||
| 520 | # TOKELAU | ||
| 521 | TK=NZD | ||
| 522 | # TONGA | ||
| 523 | TO=TOP | ||
| 524 | # TRINIDAD AND TOBAGO | ||
| 525 | TT=TTD | ||
| 526 | # TUNISIA | ||
| 527 | TN=TND | ||
| 528 | # TURKEY | ||
| 529 | TR=TRL;2004-12-31-22-00-00;TRY | ||
| 530 | # TURKMENISTAN | ||
| 531 | TM=TMM | ||
| 532 | # TURKS AND CAICOS ISLANDS | ||
| 533 | TC=USD | ||
| 534 | # TUVALU | ||
| 535 | TV=AUD | ||
| 536 | # UGANDA | ||
| 537 | UG=UGX | ||
| 538 | # UKRAINE | ||
| 539 | UA=UAH | ||
| 540 | # UNITED ARAB EMIRATES | ||
| 541 | AE=AED | ||
| 542 | # UNITED KINGDOM | ||
| 543 | GB=GBP | ||
| 544 | # UNITED STATES | ||
| 545 | US=USD | ||
| 546 | # UNITED STATES MINOR OUTLYING ISLANDS | ||
| 547 | UM=USD | ||
| 548 | # URUGUAY | ||
| 549 | UY=UYU | ||
| 550 | # UZBEKISTAN | ||
| 551 | UZ=UZS | ||
| 552 | # VANUATU | ||
| 553 | VU=VUV | ||
| 554 | # VENEZUELA | ||
| 555 | VE=VEB;2008-01-01-04-00-00;VEF | ||
| 556 | # VIET NAM | ||
| 557 | VN=VND | ||
| 558 | # VIRGIN ISLANDS, BRITISH | ||
| 559 | VG=USD | ||
| 560 | # VIRGIN ISLANDS, U.S. | ||
| 561 | VI=USD | ||
| 562 | # WALLIS AND FUTUNA | ||
| 563 | WF=XPF | ||
| 564 | # WESTERN SAHARA | ||
| 565 | EH=MAD | ||
| 566 | # YEMEN | ||
| 567 | YE=YER | ||
| 568 | # ZAMBIA | ||
| 569 | ZM=ZMK | ||
| 570 | # ZIMBABWE | ||
| 571 | ZW=ZWD | ||
| 572 | |||
| 573 | |||
| 574 | # List of currencies with 0, 1, OR 3 decimals for minor units, or where there | ||
| 575 | # are no minor units defined. All others use 2 decimals. | ||
| 576 | |||
| 577 | minor0=\ | ||
| 578 | ADP-BEF-BIF-BYB-BYR-CLF-CLP-DJF-ESP-GNF-\ | ||
| 579 | GRD-ISK-ITL-JPY-KMF-KRW-LUF-MGF-PYG-PTE-RWF-\ | ||
| 580 | TPE-TRL-VUV-XAF-XOF-XPF | ||
| 581 | minor1= | ||
| 582 | minor3=\ | ||
| 583 | BHD-IQD-JOD-KWD-LYD-OMR-TND | ||
| 584 | minorUndefined=\ | ||
| 585 | XAG-XAU-XBA-XBB-XBC-XBD-XDR-XFO-XFU-XPD-\ | ||
| 586 | XPT-XTS-XXX | ||
Binary file not shown.
| @@ -0,0 +1,1331 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package java.util; | ||
| 27 | |||
| 28 | import java.text.DateFormat; | ||
| 29 | import java.io.IOException; | ||
| 30 | import java.io.ObjectOutputStream; | ||
| 31 | import java.io.ObjectInputStream; | ||
| 32 | import java.lang.ref.SoftReference; | ||
| 33 | import sun.util.calendar.BaseCalendar; | ||
| 34 | import sun.util.calendar.CalendarDate; | ||
| 35 | import sun.util.calendar.CalendarSystem; | ||
| 36 | import sun.util.calendar.CalendarUtils; | ||
| 37 | import sun.util.calendar.Era; | ||
| 38 | import sun.util.calendar.Gregorian; | ||
| 39 | import sun.util.calendar.ZoneInfo; | ||
| 40 | |||
| 41 | /** | ||
| 42 | * The class <code>Date</code> represents a specific instant | ||
| 43 | * in time, with millisecond precision. | ||
| 44 | * <p> | ||
| 45 | * Prior to JDK 1.1, the class <code>Date</code> had two additional | ||
| 46 | * functions. It allowed the interpretation of dates as year, month, day, hour, | ||
| 47 | * minute, and second values. It also allowed the formatting and parsing | ||
| 48 | * of date strings. Unfortunately, the API for these functions was not | ||
| 49 | * amenable to internationalization. As of JDK 1.1, the | ||
| 50 | * <code>Calendar</code> class should be used to convert between dates and time | ||
| 51 | * fields and the <code>DateFormat</code> class should be used to format and | ||
| 52 | * parse date strings. | ||
| 53 | * The corresponding methods in <code>Date</code> are deprecated. | ||
| 54 | * <p> | ||
| 55 | * Although the <code>Date</code> class is intended to reflect | ||
| 56 | * coordinated universal time (UTC), it may not do so exactly, | ||
| 57 | * depending on the host environment of the Java Virtual Machine. | ||
| 58 | * Nearly all modern operating systems assume that 1 day = | ||
| 59 | * 24 × 60 × 60 = 86400 seconds | ||
| 60 | * in all cases. In UTC, however, about once every year or two there | ||
| 61 | * is an extra second, called a "leap second." The leap | ||
| 62 | * second is always added as the last second of the day, and always | ||
| 63 | * on December 31 or June 30. For example, the last minute of the | ||
| 64 | * year 1995 was 61 seconds long, thanks to an added leap second. | ||
| 65 | * Most computer clocks are not accurate enough to be able to reflect | ||
| 66 | * the leap-second distinction. | ||
| 67 | * <p> | ||
| 68 | * Some computer standards are defined in terms of Greenwich mean | ||
| 69 | * time (GMT), which is equivalent to universal time (UT). GMT is | ||
| 70 | * the "civil" name for the standard; UT is the | ||
| 71 | * "scientific" name for the same standard. The | ||
| 72 | * distinction between UTC and UT is that UTC is based on an atomic | ||
| 73 | * clock and UT is based on astronomical observations, which for all | ||
| 74 | * practical purposes is an invisibly fine hair to split. Because the | ||
| 75 | * earth's rotation is not uniform (it slows down and speeds up | ||
| 76 | * in complicated ways), UT does not always flow uniformly. Leap | ||
| 77 | * seconds are introduced as needed into UTC so as to keep UTC within | ||
| 78 | * 0.9 seconds of UT1, which is a version of UT with certain | ||
| 79 | * corrections applied. There are other time and date systems as | ||
| 80 | * well; for example, the time scale used by the satellite-based | ||
| 81 | * global positioning system (GPS) is synchronized to UTC but is | ||
| 82 | * <i>not</i> adjusted for leap seconds. An interesting source of | ||
| 83 | * further information is the U.S. Naval Observatory, particularly | ||
| 84 | * the Directorate of Time at: | ||
| 85 | * <blockquote><pre> | ||
| 86 | * <a href=http://tycho.usno.navy.mil>http://tycho.usno.navy.mil</a> | ||
| 87 | * </pre></blockquote> | ||
| 88 | * <p> | ||
| 89 | * and their definitions of "Systems of Time" at: | ||
| 90 | * <blockquote><pre> | ||
| 91 | * <a href=http://tycho.usno.navy.mil/systime.html>http://tycho.usno.navy.mil/systime.html</a> | ||
| 92 | * </pre></blockquote> | ||
| 93 | * <p> | ||
| 94 | * In all methods of class <code>Date</code> that accept or return | ||
| 95 | * year, month, date, hours, minutes, and seconds values, the | ||
| 96 | * following representations are used: | ||
| 97 | * <ul> | ||
| 98 | * <li>A year <i>y</i> is represented by the integer | ||
| 99 | * <i>y</i> <code>- 1900</code>. | ||
| 100 | * <li>A month is represented by an integer from 0 to 11; 0 is January, | ||
| 101 | * 1 is February, and so forth; thus 11 is December. | ||
| 102 | * <li>A date (day of month) is represented by an integer from 1 to 31 | ||
| 103 | * in the usual manner. | ||
| 104 | * <li>An hour is represented by an integer from 0 to 23. Thus, the hour | ||
| 105 | * from midnight to 1 a.m. is hour 0, and the hour from noon to 1 | ||
| 106 | * p.m. is hour 12. | ||
| 107 | * <li>A minute is represented by an integer from 0 to 59 in the usual manner. | ||
| 108 | * <li>A second is represented by an integer from 0 to 61; the values 60 and | ||
| 109 | * 61 occur only for leap seconds and even then only in Java | ||
| 110 | * implementations that actually track leap seconds correctly. Because | ||
| 111 | * of the manner in which leap seconds are currently introduced, it is | ||
| 112 | * extremely unlikely that two leap seconds will occur in the same | ||
| 113 | * minute, but this specification follows the date and time conventions | ||
| 114 | * for ISO C. | ||
| 115 | * </ul> | ||
| 116 | * <p> | ||
| 117 | * In all cases, arguments given to methods for these purposes need | ||
| 118 | * not fall within the indicated ranges; for example, a date may be | ||
| 119 | * specified as January 32 and is interpreted as meaning February 1. | ||
| 120 | * | ||
| 121 | * @author James Gosling | ||
| 122 | * @author Arthur van Hoff | ||
| 123 | * @author Alan Liu | ||
| 124 | * @see java.text.DateFormat | ||
| 125 | * @see java.util.Calendar | ||
| 126 | * @see java.util.TimeZone | ||
| 127 | * @since JDK1.0 | ||
| 128 | */ | ||
| 129 | public class Date | ||
| 130 | implements java.io.Serializable, Cloneable, Comparable<Date> | ||
| 131 | { | ||
| 132 | private static final BaseCalendar gcal = | ||
| 133 | CalendarSystem.getGregorianCalendar(); | ||
| 134 | private static BaseCalendar jcal; | ||
| 135 | |||
| 136 | private transient long fastTime; | ||
| 137 | |||
| 138 | /* | ||
| 139 | * If cdate is null, then fastTime indicates the time in millis. | ||
| 140 | * If cdate.isNormalized() is true, then fastTime and cdate are in | ||
| 141 | * synch. Otherwise, fastTime is ignored, and cdate indicates the | ||
| 142 | * time. | ||
| 143 | */ | ||
| 144 | private transient BaseCalendar.Date cdate; | ||
| 145 | |||
| 146 | // Initialized just before the value is used. See parse(). | ||
| 147 | private static int defaultCenturyStart; | ||
| 148 | |||
| 149 | /* use serialVersionUID from modified java.util.Date for | ||
| 150 | * interoperability with JDK1.1. The Date was modified to write | ||
| 151 | * and read only the UTC time. | ||
| 152 | */ | ||
| 153 | private static final long serialVersionUID = 7523967970034938905L; | ||
| 154 | |||
| 155 | /** | ||
| 156 | * Allocates a <code>Date</code> object and initializes it so that | ||
| 157 | * it represents the time at which it was allocated, measured to the | ||
| 158 | * nearest millisecond. | ||
| 159 | * | ||
| 160 | * @see java.lang.System#currentTimeMillis() | ||
| 161 | */ | ||
| 162 | public Date() { | ||
| 163 | this(System.currentTimeMillis()); | ||
| 164 | } | ||
| 165 | |||
| 166 | /** | ||
| 167 | * Allocates a <code>Date</code> object and initializes it to | ||
| 168 | * represent the specified number of milliseconds since the | ||
| 169 | * standard base time known as "the epoch", namely January 1, | ||
| 170 | * 1970, 00:00:00 GMT. | ||
| 171 | * | ||
| 172 | * @param date the milliseconds since January 1, 1970, 00:00:00 GMT. | ||
| 173 | * @see java.lang.System#currentTimeMillis() | ||
| 174 | */ | ||
| 175 | public Date(long date) { | ||
| 176 | fastTime = date; | ||
| 177 | } | ||
| 178 | |||
| 179 | /** | ||
| 180 | * Allocates a <code>Date</code> object and initializes it so that | ||
| 181 | * it represents midnight, local time, at the beginning of the day | ||
| 182 | * specified by the <code>year</code>, <code>month</code>, and | ||
| 183 | * <code>date</code> arguments. | ||
| 184 | * | ||
| 185 | * @param year the year minus 1900. | ||
| 186 | * @param month the month between 0-11. | ||
| 187 | * @param date the day of the month between 1-31. | ||
| 188 | * @see java.util.Calendar | ||
| 189 | * @deprecated As of JDK version 1.1, | ||
| 190 | * replaced by <code>Calendar.set(year + 1900, month, date)</code> | ||
| 191 | * or <code>GregorianCalendar(year + 1900, month, date)</code>. | ||
| 192 | */ | ||
| 193 | @Deprecated | ||
| 194 | public Date(int year, int month, int date) { | ||
| 195 | this(year, month, date, 0, 0, 0); | ||
| 196 | } | ||
| 197 | |||
| 198 | /** | ||
| 199 | * Allocates a <code>Date</code> object and initializes it so that | ||
| 200 | * it represents the instant at the start of the minute specified by | ||
| 201 | * the <code>year</code>, <code>month</code>, <code>date</code>, | ||
| 202 | * <code>hrs</code>, and <code>min</code> arguments, in the local | ||
| 203 | * time zone. | ||
| 204 | * | ||
| 205 | * @param year the year minus 1900. | ||
| 206 | * @param month the month between 0-11. | ||
| 207 | * @param date the day of the month between 1-31. | ||
| 208 | * @param hrs the hours between 0-23. | ||
| 209 | * @param min the minutes between 0-59. | ||
| 210 | * @see java.util.Calendar | ||
| 211 | * @deprecated As of JDK version 1.1, | ||
| 212 | * replaced by <code>Calendar.set(year + 1900, month, date, | ||
| 213 | * hrs, min)</code> or <code>GregorianCalendar(year + 1900, | ||
| 214 | * month, date, hrs, min)</code>. | ||
| 215 | */ | ||
| 216 | @Deprecated | ||
| 217 | public Date(int year, int month, int date, int hrs, int min) { | ||
| 218 | this(year, month, date, hrs, min, 0); | ||
| 219 | } | ||
| 220 | |||
| 221 | /** | ||
| 222 | * Allocates a <code>Date</code> object and initializes it so that | ||
| 223 | * it represents the instant at the start of the second specified | ||
| 224 | * by the <code>year</code>, <code>month</code>, <code>date</code>, | ||
| 225 | * <code>hrs</code>, <code>min</code>, and <code>sec</code> arguments, | ||
| 226 | * in the local time zone. | ||
| 227 | * | ||
| 228 | * @param year the year minus 1900. | ||
| 229 | * @param month the month between 0-11. | ||
| 230 | * @param date the day of the month between 1-31. | ||
| 231 | * @param hrs the hours between 0-23. | ||
| 232 | * @param min the minutes between 0-59. | ||
| 233 | * @param sec the seconds between 0-59. | ||
| 234 | * @see java.util.Calendar | ||
| 235 | * @deprecated As of JDK version 1.1, | ||
| 236 | * replaced by <code>Calendar.set(year + 1900, month, date, | ||
| 237 | * hrs, min, sec)</code> or <code>GregorianCalendar(year + 1900, | ||
| 238 | * month, date, hrs, min, sec)</code>. | ||
| 239 | */ | ||
| 240 | @Deprecated | ||
| 241 | public Date(int year, int month, int date, int hrs, int min, int sec) { | ||
| 242 | int y = year + 1900; | ||
| 243 | // month is 0-based. So we have to normalize month to support Long.MAX_VALUE. | ||
| 244 | if (month >= 12) { | ||
| 245 | y += month / 12; | ||
| 246 | month %= 12; | ||
| 247 | } else if (month < 0) { | ||
| 248 | y += CalendarUtils.floorDivide(month, 12); | ||
| 249 | month = CalendarUtils.mod(month, 12); | ||
| 250 | } | ||
| 251 | BaseCalendar cal = getCalendarSystem(y); | ||
| 252 | cdate = (BaseCalendar.Date) cal.newCalendarDate(TimeZone.getDefaultRef()); | ||
| 253 | cdate.setNormalizedDate(y, month + 1, date).setTimeOfDay(hrs, min, sec, 0); | ||
| 254 | getTimeImpl(); | ||
| 255 | cdate = null; | ||
| 256 | } | ||
| 257 | |||
| 258 | /** | ||
| 259 | * Allocates a <code>Date</code> object and initializes it so that | ||
| 260 | * it represents the date and time indicated by the string | ||
| 261 | * <code>s</code>, which is interpreted as if by the | ||
| 262 | * {@link Date#parse} method. | ||
| 263 | * | ||
| 264 | * @param s a string representation of the date. | ||
| 265 | * @see java.text.DateFormat | ||
| 266 | * @see java.util.Date#parse(java.lang.String) | ||
| 267 | * @deprecated As of JDK version 1.1, | ||
| 268 | * replaced by <code>DateFormat.parse(String s)</code>. | ||
| 269 | */ | ||
| 270 | @Deprecated | ||
| 271 | public Date(String s) { | ||
| 272 | this(parse(s)); | ||
| 273 | } | ||
| 274 | |||
| 275 | /** | ||
| 276 | * Return a copy of this object. | ||
| 277 | */ | ||
| 278 | public Object clone() { | ||
| 279 | Date d = null; | ||
| 280 | try { | ||
| 281 | d = (Date)super.clone(); | ||
| 282 | if (cdate != null) { | ||
| 283 | d.cdate = (BaseCalendar.Date) cdate.clone(); | ||
| 284 | } | ||
| 285 | } catch (CloneNotSupportedException e) {} // Won't happen | ||
| 286 | return d; | ||
| 287 | } | ||
| 288 | |||
| 289 | /** | ||
| 290 | * Determines the date and time based on the arguments. The | ||
| 291 | * arguments are interpreted as a year, month, day of the month, | ||
| 292 | * hour of the day, minute within the hour, and second within the | ||
| 293 | * minute, exactly as for the <tt>Date</tt> constructor with six | ||
| 294 | * arguments, except that the arguments are interpreted relative | ||
| 295 | * to UTC rather than to the local time zone. The time indicated is | ||
| 296 | * returned represented as the distance, measured in milliseconds, | ||
| 297 | * of that time from the epoch (00:00:00 GMT on January 1, 1970). | ||
| 298 | * | ||
| 299 | * @param year the year minus 1900. | ||
| 300 | * @param month the month between 0-11. | ||
| 301 | * @param date the day of the month between 1-31. | ||
| 302 | * @param hrs the hours between 0-23. | ||
| 303 | * @param min the minutes between 0-59. | ||
| 304 | * @param sec the seconds between 0-59. | ||
| 305 | * @return the number of milliseconds since January 1, 1970, 00:00:00 GMT for | ||
| 306 | * the date and time specified by the arguments. | ||
| 307 | * @see java.util.Calendar | ||
| 308 | * @deprecated As of JDK version 1.1, | ||
| 309 | * replaced by <code>Calendar.set(year + 1900, month, date, | ||
| 310 | * hrs, min, sec)</code> or <code>GregorianCalendar(year + 1900, | ||
| 311 | * month, date, hrs, min, sec)</code>, using a UTC | ||
| 312 | * <code>TimeZone</code>, followed by <code>Calendar.getTime().getTime()</code>. | ||
| 313 | */ | ||
| 314 | @Deprecated | ||
| 315 | public static long UTC(int year, int month, int date, | ||
| 316 | int hrs, int min, int sec) { | ||
| 317 | int y = year + 1900; | ||
| 318 | // month is 0-based. So we have to normalize month to support Long.MAX_VALUE. | ||
| 319 | if (month >= 12) { | ||
| 320 | y += month / 12; | ||
| 321 | month %= 12; | ||
| 322 | } else if (month < 0) { | ||
| 323 | y += CalendarUtils.floorDivide(month, 12); | ||
| 324 | month = CalendarUtils.mod(month, 12); | ||
| 325 | } | ||
| 326 | int m = month + 1; | ||
| 327 | BaseCalendar cal = getCalendarSystem(y); | ||
| 328 | BaseCalendar.Date udate = (BaseCalendar.Date) cal.newCalendarDate(null); | ||
| 329 | udate.setNormalizedDate(y, m, date).setTimeOfDay(hrs, min, sec, 0); | ||
| 330 | |||
| 331 | // Use a Date instance to perform normalization. Its fastTime | ||
| 332 | // is the UTC value after the normalization. | ||
| 333 | Date d = new Date(0); | ||
| 334 | d.normalize(udate); | ||
| 335 | return d.fastTime; | ||
| 336 | } | ||
| 337 | |||
| 338 | /** | ||
| 339 | * Attempts to interpret the string <tt>s</tt> as a representation | ||
| 340 | * of a date and time. If the attempt is successful, the time | ||
| 341 | * indicated is returned represented as the distance, measured in | ||
| 342 | * milliseconds, of that time from the epoch (00:00:00 GMT on | ||
| 343 | * January 1, 1970). If the attempt fails, an | ||
| 344 | * <tt>IllegalArgumentException</tt> is thrown. | ||
| 345 | * <p> | ||
| 346 | * It accepts many syntaxes; in particular, it recognizes the IETF | ||
| 347 | * standard date syntax: "Sat, 12 Aug 1995 13:30:00 GMT". It also | ||
| 348 | * understands the continental U.S. time-zone abbreviations, but for | ||
| 349 | * general use, a time-zone offset should be used: "Sat, 12 Aug 1995 | ||
| 350 | * 13:30:00 GMT+0430" (4 hours, 30 minutes west of the Greenwich | ||
| 351 | * meridian). If no time zone is specified, the local time zone is | ||
| 352 | * assumed. GMT and UTC are considered equivalent. | ||
| 353 | * <p> | ||
| 354 | * The string <tt>s</tt> is processed from left to right, looking for | ||
| 355 | * data of interest. Any material in <tt>s</tt> that is within the | ||
| 356 | * ASCII parenthesis characters <tt>(</tt> and <tt>)</tt> is ignored. | ||
| 357 | * Parentheses may be nested. Otherwise, the only characters permitted | ||
| 358 | * within <tt>s</tt> are these ASCII characters: | ||
| 359 | * <blockquote><pre> | ||
| 360 | * abcdefghijklmnopqrstuvwxyz | ||
| 361 | * ABCDEFGHIJKLMNOPQRSTUVWXYZ | ||
| 362 | * 0123456789,+-:/</pre></blockquote> | ||
| 363 | * and whitespace characters.<p> | ||
| 364 | * A consecutive sequence of decimal digits is treated as a decimal | ||
| 365 | * number:<ul> | ||
| 366 | * <li>If a number is preceded by <tt>+</tt> or <tt>-</tt> and a year | ||
| 367 | * has already been recognized, then the number is a time-zone | ||
| 368 | * offset. If the number is less than 24, it is an offset measured | ||
| 369 | * in hours. Otherwise, it is regarded as an offset in minutes, | ||
| 370 | * expressed in 24-hour time format without punctuation. A | ||
| 371 | * preceding <tt>-</tt> means a westward offset. Time zone offsets | ||
| 372 | * are always relative to UTC (Greenwich). Thus, for example, | ||
| 373 | * <tt>-5</tt> occurring in the string would mean "five hours west | ||
| 374 | * of Greenwich" and <tt>+0430</tt> would mean "four hours and | ||
| 375 | * thirty minutes east of Greenwich." It is permitted for the | ||
| 376 | * string to specify <tt>GMT</tt>, <tt>UT</tt>, or <tt>UTC</tt> | ||
| 377 | * redundantly-for example, <tt>GMT-5</tt> or <tt>utc+0430</tt>. | ||
| 378 | * <li>The number is regarded as a year number if one of the | ||
| 379 | * following conditions is true: | ||
| 380 | * <ul> | ||
| 381 | * <li>The number is equal to or greater than 70 and followed by a | ||
| 382 | * space, comma, slash, or end of string | ||
| 383 | * <li>The number is less than 70, and both a month and a day of | ||
| 384 | * the month have already been recognized</li> | ||
| 385 | * </ul> | ||
| 386 | * If the recognized year number is less than 100, it is | ||
| 387 | * interpreted as an abbreviated year relative to a century of | ||
| 388 | * which dates are within 80 years before and 19 years after | ||
| 389 | * the time when the Date class is initialized. | ||
| 390 | * After adjusting the year number, 1900 is subtracted from | ||
| 391 | * it. For example, if the current year is 1999 then years in | ||
| 392 | * the range 19 to 99 are assumed to mean 1919 to 1999, while | ||
| 393 | * years from 0 to 18 are assumed to mean 2000 to 2018. Note | ||
| 394 | * that this is slightly different from the interpretation of | ||
| 395 | * years less than 100 that is used in {@link java.text.SimpleDateFormat}. | ||
| 396 | * <li>If the number is followed by a colon, it is regarded as an hour, | ||
| 397 | * unless an hour has already been recognized, in which case it is | ||
| 398 | * regarded as a minute. | ||
| 399 | * <li>If the number is followed by a slash, it is regarded as a month | ||
| 400 | * (it is decreased by 1 to produce a number in the range <tt>0</tt> | ||
| 401 | * to <tt>11</tt>), unless a month has already been recognized, in | ||
| 402 | * which case it is regarded as a day of the month. | ||
| 403 | * <li>If the number is followed by whitespace, a comma, a hyphen, or | ||
| 404 | * end of string, then if an hour has been recognized but not a | ||
| 405 | * minute, it is regarded as a minute; otherwise, if a minute has | ||
| 406 | * been recognized but not a second, it is regarded as a second; | ||
| 407 | * otherwise, it is regarded as a day of the month. </ul><p> | ||
| 408 | * A consecutive sequence of letters is regarded as a word and treated | ||
| 409 | * as follows:<ul> | ||
| 410 | * <li>A word that matches <tt>AM</tt>, ignoring case, is ignored (but | ||
| 411 | * the parse fails if an hour has not been recognized or is less | ||
| 412 | * than <tt>1</tt> or greater than <tt>12</tt>). | ||
| 413 | * <li>A word that matches <tt>PM</tt>, ignoring case, adds <tt>12</tt> | ||
| 414 | * to the hour (but the parse fails if an hour has not been | ||
| 415 | * recognized or is less than <tt>1</tt> or greater than <tt>12</tt>). | ||
| 416 | * <li>Any word that matches any prefix of <tt>SUNDAY, MONDAY, TUESDAY, | ||
| 417 | * WEDNESDAY, THURSDAY, FRIDAY</tt>, or <tt>SATURDAY</tt>, ignoring | ||
| 418 | * case, is ignored. For example, <tt>sat, Friday, TUE</tt>, and | ||
| 419 | * <tt>Thurs</tt> are ignored. | ||
| 420 | * <li>Otherwise, any word that matches any prefix of <tt>JANUARY, | ||
| 421 | * FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, | ||
| 422 | * OCTOBER, NOVEMBER</tt>, or <tt>DECEMBER</tt>, ignoring case, and | ||
| 423 | * considering them in the order given here, is recognized as | ||
| 424 | * specifying a month and is converted to a number (<tt>0</tt> to | ||
| 425 | * <tt>11</tt>). For example, <tt>aug, Sept, april</tt>, and | ||
| 426 | * <tt>NOV</tt> are recognized as months. So is <tt>Ma</tt>, which | ||
| 427 | * is recognized as <tt>MARCH</tt>, not <tt>MAY</tt>. | ||
| 428 | * <li>Any word that matches <tt>GMT, UT</tt>, or <tt>UTC</tt>, ignoring | ||
| 429 | * case, is treated as referring to UTC. | ||
| 430 | * <li>Any word that matches <tt>EST, CST, MST</tt>, or <tt>PST</tt>, | ||
| 431 | * ignoring case, is recognized as referring to the time zone in | ||
| 432 | * North America that is five, six, seven, or eight hours west of | ||
| 433 | * Greenwich, respectively. Any word that matches <tt>EDT, CDT, | ||
| 434 | * MDT</tt>, or <tt>PDT</tt>, ignoring case, is recognized as | ||
| 435 | * referring to the same time zone, respectively, during daylight | ||
| 436 | * saving time.</ul><p> | ||
| 437 | * Once the entire string s has been scanned, it is converted to a time | ||
| 438 | * result in one of two ways. If a time zone or time-zone offset has been | ||
| 439 | * recognized, then the year, month, day of month, hour, minute, and | ||
| 440 | * second are interpreted in UTC and then the time-zone offset is | ||
| 441 | * applied. Otherwise, the year, month, day of month, hour, minute, and | ||
| 442 | * second are interpreted in the local time zone. | ||
| 443 | * | ||
| 444 | * @param s a string to be parsed as a date. | ||
| 445 | * @return the number of milliseconds since January 1, 1970, 00:00:00 GMT | ||
| 446 | * represented by the string argument. | ||
| 447 | * @see java.text.DateFormat | ||
| 448 | * @deprecated As of JDK version 1.1, | ||
| 449 | * replaced by <code>DateFormat.parse(String s)</code>. | ||
| 450 | */ | ||
| 451 | @Deprecated | ||
| 452 | public static long parse(String s) { | ||
| 453 | int year = Integer.MIN_VALUE; | ||
| 454 | int mon = -1; | ||
| 455 | int mday = -1; | ||
| 456 | int hour = -1; | ||
| 457 | int min = -1; | ||
| 458 | int sec = -1; | ||
| 459 | int millis = -1; | ||
| 460 | int c = -1; | ||
| 461 | int i = 0; | ||
| 462 | int n = -1; | ||
| 463 | int wst = -1; | ||
| 464 | int tzoffset = -1; | ||
| 465 | int prevc = 0; | ||
| 466 | syntax: | ||
| 467 | { | ||
| 468 | if (s == null) | ||
| 469 | break syntax; | ||
| 470 | int limit = s.length(); | ||
| 471 | while (i < limit) { | ||
| 472 | c = s.charAt(i); | ||
| 473 | i++; | ||
| 474 | if (c <= ' ' || c == ',') | ||
| 475 | continue; | ||
| 476 | if (c == '(') { // skip comments | ||
| 477 | int depth = 1; | ||
| 478 | while (i < limit) { | ||
| 479 | c = s.charAt(i); | ||
| 480 | i++; | ||
| 481 | if (c == '(') depth++; | ||
| 482 | else if (c == ')') | ||
| 483 | if (--depth <= 0) | ||
| 484 | break; | ||
| 485 | } | ||
| 486 | continue; | ||
| 487 | } | ||
| 488 | if ('0' <= c && c <= '9') { | ||
| 489 | n = c - '0'; | ||
| 490 | while (i < limit && '0' <= (c = s.charAt(i)) && c <= '9') { | ||
| 491 | n = n * 10 + c - '0'; | ||
| 492 | i++; | ||
| 493 | } | ||
| 494 | if (prevc == '+' || prevc == '-' && year != Integer.MIN_VALUE) { | ||
| 495 | // timezone offset | ||
| 496 | if (n < 24) | ||
| 497 | n = n * 60; // EG. "GMT-3" | ||
| 498 | else | ||
| 499 | n = n % 100 + n / 100 * 60; // eg "GMT-0430" | ||
| 500 | if (prevc == '+') // plus means east of GMT | ||
| 501 | n = -n; | ||
| 502 | if (tzoffset != 0 && tzoffset != -1) | ||
| 503 | break syntax; | ||
| 504 | tzoffset = n; | ||
| 505 | } else if (n >= 70) | ||
| 506 | if (year != Integer.MIN_VALUE) | ||
| 507 | break syntax; | ||
| 508 | else if (c <= ' ' || c == ',' || c == '/' || i >= limit) | ||
| 509 | // year = n < 1900 ? n : n - 1900; | ||
| 510 | year = n; | ||
| 511 | else | ||
| 512 | break syntax; | ||
| 513 | else if (c == ':') | ||
| 514 | if (hour < 0) | ||
| 515 | hour = (byte) n; | ||
| 516 | else if (min < 0) | ||
| 517 | min = (byte) n; | ||
| 518 | else | ||
| 519 | break syntax; | ||
| 520 | else if (c == '/') | ||
| 521 | if (mon < 0) | ||
| 522 | mon = (byte) (n - 1); | ||
| 523 | else if (mday < 0) | ||
| 524 | mday = (byte) n; | ||
| 525 | else | ||
| 526 | break syntax; | ||
| 527 | else if (i < limit && c != ',' && c > ' ' && c != '-') | ||
| 528 | break syntax; | ||
| 529 | else if (hour >= 0 && min < 0) | ||
| 530 | min = (byte) n; | ||
| 531 | else if (min >= 0 && sec < 0) | ||
| 532 | sec = (byte) n; | ||
| 533 | else if (mday < 0) | ||
| 534 | mday = (byte) n; | ||
| 535 | // Handle two-digit years < 70 (70-99 handled above). | ||
| 536 | else if (year == Integer.MIN_VALUE && mon >= 0 && mday >= 0) | ||
| 537 | year = n; | ||
| 538 | else | ||
| 539 | break syntax; | ||
| 540 | prevc = 0; | ||
| 541 | } else if (c == '/' || c == ':' || c == '+' || c == '-') | ||
| 542 | prevc = c; | ||
| 543 | else { | ||
| 544 | int st = i - 1; | ||
| 545 | while (i < limit) { | ||
| 546 | c = s.charAt(i); | ||
| 547 | if (!('A' <= c && c <= 'Z' || 'a' <= c && c <= 'z')) | ||
| 548 | break; | ||
| 549 | i++; | ||
| 550 | } | ||
| 551 | if (i <= st + 1) | ||
| 552 | break syntax; | ||
| 553 | int k; | ||
| 554 | for (k = wtb.length; --k >= 0;) | ||
| 555 | if (wtb[k].regionMatches(true, 0, s, st, i - st)) { | ||
| 556 | int action = ttb[k]; | ||
| 557 | if (action != 0) { | ||
| 558 | if (action == 1) { // pm | ||
| 559 | if (hour > 12 || hour < 1) | ||
| 560 | break syntax; | ||
| 561 | else if (hour < 12) | ||
| 562 | hour += 12; | ||
| 563 | } else if (action == 14) { // am | ||
| 564 | if (hour > 12 || hour < 1) | ||
| 565 | break syntax; | ||
| 566 | else if (hour == 12) | ||
| 567 | hour = 0; | ||
| 568 | } else if (action <= 13) { // month! | ||
| 569 | if (mon < 0) | ||
| 570 | mon = (byte) (action - 2); | ||
| 571 | else | ||
| 572 | break syntax; | ||
| 573 | } else { | ||
| 574 | tzoffset = action - 10000; | ||
| 575 | } | ||
| 576 | } | ||
| 577 | break; | ||
| 578 | } | ||
| 579 | if (k < 0) | ||
| 580 | break syntax; | ||
| 581 | prevc = 0; | ||
| 582 | } | ||
| 583 | } | ||
| 584 | if (year == Integer.MIN_VALUE || mon < 0 || mday < 0) | ||
| 585 | break syntax; | ||
| 586 | // Parse 2-digit years within the correct default century. | ||
| 587 | if (year < 100) { | ||
| 588 | synchronized (Date.class) { | ||
| 589 | if (defaultCenturyStart == 0) { | ||
| 590 | defaultCenturyStart = gcal.getCalendarDate().getYear() - 80; | ||
| 591 | } | ||
| 592 | } | ||
| 593 | year += (defaultCenturyStart / 100) * 100; | ||
| 594 | if (year < defaultCenturyStart) year += 100; | ||
| 595 | } | ||
| 596 | if (sec < 0) | ||
| 597 | sec = 0; | ||
| 598 | if (min < 0) | ||
| 599 | min = 0; | ||
| 600 | if (hour < 0) | ||
| 601 | hour = 0; | ||
| 602 | BaseCalendar cal = getCalendarSystem(year); | ||
| 603 | if (tzoffset == -1) { // no time zone specified, have to use local | ||
| 604 | BaseCalendar.Date ldate = (BaseCalendar.Date) cal.newCalendarDate(TimeZone.getDefaultRef()); | ||
| 605 | ldate.setDate(year, mon + 1, mday); | ||
| 606 | ldate.setTimeOfDay(hour, min, sec, 0); | ||
| 607 | return cal.getTime(ldate); | ||
| 608 | } | ||
| 609 | BaseCalendar.Date udate = (BaseCalendar.Date) cal.newCalendarDate(null); // no time zone | ||
| 610 | udate.setDate(year, mon + 1, mday); | ||
| 611 | udate.setTimeOfDay(hour, min, sec, 0); | ||
| 612 | return cal.getTime(udate) + tzoffset * (60 * 1000); | ||
| 613 | } | ||
| 614 | // syntax error | ||
| 615 | throw new IllegalArgumentException(); | ||
| 616 | } | ||
| 617 | private final static String wtb[] = { | ||
| 618 | "am", "pm", | ||
| 619 | "monday", "tuesday", "wednesday", "thursday", "friday", | ||
| 620 | "saturday", "sunday", | ||
| 621 | "january", "february", "march", "april", "may", "june", | ||
| 622 | "july", "august", "september", "october", "november", "december", | ||
| 623 | "gmt", "ut", "utc", "est", "edt", "cst", "cdt", | ||
| 624 | "mst", "mdt", "pst", "pdt" | ||
| 625 | }; | ||
| 626 | private final static int ttb[] = { | ||
| 627 | 14, 1, 0, 0, 0, 0, 0, 0, 0, | ||
| 628 | 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, | ||
| 629 | 10000 + 0, 10000 + 0, 10000 + 0, // GMT/UT/UTC | ||
| 630 | 10000 + 5 * 60, 10000 + 4 * 60, // EST/EDT | ||
| 631 | 10000 + 6 * 60, 10000 + 5 * 60, // CST/CDT | ||
| 632 | 10000 + 7 * 60, 10000 + 6 * 60, // MST/MDT | ||
| 633 | 10000 + 8 * 60, 10000 + 7 * 60 // PST/PDT | ||
| 634 | }; | ||
| 635 | |||
| 636 | /** | ||
| 637 | * Returns a value that is the result of subtracting 1900 from the | ||
| 638 | * year that contains or begins with the instant in time represented | ||
| 639 | * by this <code>Date</code> object, as interpreted in the local | ||
| 640 | * time zone. | ||
| 641 | * | ||
| 642 | * @return the year represented by this date, minus 1900. | ||
| 643 | * @see java.util.Calendar | ||
| 644 | * @deprecated As of JDK version 1.1, | ||
| 645 | * replaced by <code>Calendar.get(Calendar.YEAR) - 1900</code>. | ||
| 646 | */ | ||
| 647 | @Deprecated | ||
| 648 | public int getYear() { | ||
| 649 | return normalize().getYear() - 1900; | ||
| 650 | } | ||
| 651 | |||
| 652 | /** | ||
| 653 | * Sets the year of this <tt>Date</tt> object to be the specified | ||
| 654 | * value plus 1900. This <code>Date</code> object is modified so | ||
| 655 | * that it represents a point in time within the specified year, | ||
| 656 | * with the month, date, hour, minute, and second the same as | ||
| 657 | * before, as interpreted in the local time zone. (Of course, if | ||
| 658 | * the date was February 29, for example, and the year is set to a | ||
| 659 | * non-leap year, then the new date will be treated as if it were | ||
| 660 | * on March 1.) | ||
| 661 | * | ||
| 662 | * @param year the year value. | ||
| 663 | * @see java.util.Calendar | ||
| 664 | * @deprecated As of JDK version 1.1, | ||
| 665 | * replaced by <code>Calendar.set(Calendar.YEAR, year + 1900)</code>. | ||
| 666 | */ | ||
| 667 | @Deprecated | ||
| 668 | public void setYear(int year) { | ||
| 669 | getCalendarDate().setNormalizedYear(year + 1900); | ||
| 670 | } | ||
661 more lines aren’t shown here.
Binary file not shown.
This diff is large: its 585 lines aren’t shown here.
Binary file not shown.
This diff is large: its 156 lines aren’t shown here.
Binary file not shown.
This diff is large: its 3019 lines aren’t shown here.
Binary file not shown.
This diff is large: its 69 lines aren’t shown here.
Binary file not shown.
This diff is large: its 47 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 800 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 444 lines aren’t shown here.
Binary file not shown.
This diff is large: its 80 lines aren’t shown here.
Binary file not shown.
This diff is large: its 34 lines aren’t shown here.
Binary file not shown.
This diff is large: its 76 lines aren’t shown here.
Binary file not shown.
This diff is large: its 79 lines aren’t shown here.
Binary file not shown.
This diff is large: its 85 lines aren’t shown here.
Binary file not shown.
This diff is large: its 165 lines aren’t shown here.
Binary file not shown.
This diff is large: its 76 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 4442 lines aren’t shown here.
Binary file not shown.
This diff is large: its 46 lines aren’t shown here.
Binary file not shown.
This diff is large: its 3180 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1052 lines aren’t shown here.
Binary file not shown.
This diff is large: its 313 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1116 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1244 lines aren’t shown here.
Binary file not shown.
This diff is large: its 70 lines aren’t shown here.
Binary file not shown.
This diff is large: its 85 lines aren’t shown here.
Binary file not shown.
This diff is large: its 43 lines aren’t shown here.
Binary file not shown.
This diff is large: its 68 lines aren’t shown here.
Binary file not shown.
This diff is large: its 64 lines aren’t shown here.
Binary file not shown.
This diff is large: its 63 lines aren’t shown here.
Binary file not shown.
This diff is large: its 91 lines aren’t shown here.
Binary file not shown.
This diff is large: its 60 lines aren’t shown here.
Binary file not shown.
This diff is large: its 91 lines aren’t shown here.
Binary file not shown.
This diff is large: its 88 lines aren’t shown here.
Binary file not shown.
This diff is large: its 2384 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 376 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 492 lines aren’t shown here.
Binary file not shown.
This diff is large: its 172 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1139 lines aren’t shown here.
Binary file not shown.
This diff is large: its 601 lines aren’t shown here.
Binary file not shown.
This diff is large: its 196 lines aren’t shown here.
Binary file not shown.
This diff is large: its 205 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 2561 lines aren’t shown here.
Binary file not shown.
This diff is large: its 479 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 479 lines aren’t shown here.
Binary file not shown.
This diff is large: its 71 lines aren’t shown here.
Binary file not shown.
This diff is large: its 69 lines aren’t shown here.
Binary file not shown.
This diff is large: its 125 lines aren’t shown here.
Binary file not shown.
This diff is large: its 425 lines aren’t shown here.
Binary file not shown.
This diff is large: its 320 lines aren’t shown here.
Binary file not shown.
This diff is large: its 61 lines aren’t shown here.
Binary file not shown.
This diff is large: its 230 lines aren’t shown here.
Binary file not shown.
This diff is large: its 214 lines aren’t shown here.
Binary file not shown.
This diff is large: its 48 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 776 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 1115 lines aren’t shown here.
Binary file not shown.
This diff is large: its 668 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 191 lines aren’t shown here.
Binary file not shown.
This diff is large: its 219 lines aren’t shown here.
Binary file not shown.
This diff is large: its 576 lines aren’t shown here.
Binary file not shown.
This diff is large: its 69 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 304 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 2912 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 2661 lines aren’t shown here.
Binary file not shown.
This diff is large: its 88 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 539 lines aren’t shown here.
Binary file not shown.
This diff is large: its 386 lines aren’t shown here.
Binary file not shown.
This diff is large: its 1707 lines aren’t shown here.
Binary file not shown.
This diff is large: its 285 lines aren’t shown here.
Binary file not shown.
This diff is large: its 223 lines aren’t shown here.
Binary file not shown.
This diff is large: its 142 lines aren’t shown here.
Binary file not shown.
This diff is large: its 432 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 929 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 865 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 721 lines aren’t shown here.
Binary file not shown.
This diff is large: its 159 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 72 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 2443 lines aren’t shown here.
Binary file not shown.
This diff is large: its 540 lines aren’t shown here.
Binary file not shown.
This diff is large: its 444 lines aren’t shown here.
Binary file not shown.
This diff is large: its 69 lines aren’t shown here.
Binary file not shown.
This diff is large: its 69 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1213 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 973 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 207 lines aren’t shown here.
Binary file not shown.
This diff is large: its 310 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 806 lines aren’t shown here.
Binary file not shown.
This diff is large: its 651 lines aren’t shown here.
Binary file not shown.
This diff is large: its 378 lines aren’t shown here.
Binary file not shown.
This diff is large: its 68 lines aren’t shown here.
Binary file not shown.
This diff is large: its 66 lines aren’t shown here.
Binary file not shown.
This diff is large: its 64 lines aren’t shown here.
Binary file not shown.
This diff is large: its 127 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1523 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1470 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 836 lines aren’t shown here.
Binary file not shown.
This diff is large: its 166 lines aren’t shown here.
Binary file not shown.
This diff is large: its 178 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 3120 lines aren’t shown here.
Binary file not shown.
This diff is large: its 492 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1341 lines aren’t shown here.
Binary file not shown.
This diff is large: its 393 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 321 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 484 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 547 lines aren’t shown here.
Binary file not shown.
This diff is large: its 63 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 688 lines aren’t shown here.
Binary file not shown.
This diff is large: its 95 lines aren’t shown here.
Binary file not shown.
This diff is large: its 142 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 206 lines aren’t shown here.
Binary file not shown.
This diff is large: its 371 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 707 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 2178 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1387 lines aren’t shown here.
Binary file not shown.
This diff is large: its 999 lines aren’t shown here.
Binary file not shown.
This diff is large: its 170 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 361 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1199 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 911 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1352 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 1153 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 979 lines aren’t shown here.
Binary file not shown.
This diff is large: its 182 lines aren’t shown here.
Binary file not shown.
This diff is large: its 98 lines aren’t shown here.
Binary file not shown.
This diff is large: its 92 lines aren’t shown here.
Binary file not shown.
This diff is large: its 63 lines aren’t shown here.
Binary file not shown.
This diff is large: its 55 lines aren’t shown here.
Binary file not shown.
This diff is large: its 59 lines aren’t shown here.
Binary file not shown.
This diff is large: its 188 lines aren’t shown here.
Binary file not shown.
This diff is large: its 49 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1278 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 714 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1197 lines aren’t shown here.
Binary file not shown.
This diff is large: its 71 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 227 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 2055 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 365 lines aren’t shown here.
Binary file not shown.
This diff is large: its 68 lines aren’t shown here.
Binary file not shown.
This diff is large: its 162 lines aren’t shown here.
Binary file not shown.
This diff is large: its 165 lines aren’t shown here.
Binary file not shown.
This diff is large: its 266 lines aren’t shown here.
Binary file not shown.
This diff is large: its 285 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 347 lines aren’t shown here.
Binary file not shown.
This diff is large: its 280 lines aren’t shown here.
Binary file not shown.
This diff is large: its 285 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 437 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 213 lines aren’t shown here.
Binary file not shown.
This diff is large: its 156 lines aren’t shown here.
Binary file not shown.
This diff is large: its 214 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 305 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 214 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 200 lines aren’t shown here.
Binary file not shown.
This diff is large: its 87 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 2110 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 2331 lines aren’t shown here.
Binary file not shown.
This diff is large: its 489 lines aren’t shown here.
Binary file not shown.
This diff is large: its 357 lines aren’t shown here.
Binary file not shown.
This diff is large: its 386 lines aren’t shown here.
Binary file not shown.
This diff is large: its 134 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 771 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1487 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 301 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 664 lines aren’t shown here.
Binary file not shown.
This diff is large: its 129 lines aren’t shown here.
Binary file not shown.
This diff is large: its 53 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 737 lines aren’t shown here.
Binary file not shown.
This diff is large: its 234 lines aren’t shown here.
Binary file not shown.
This diff is large: its 150 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 883 lines aren’t shown here.
Binary file not shown.
This diff is large: its 64 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 446 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 765 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
Binary file not shown.
This diff is large: its 118 lines aren’t shown here.
Binary file not shown.
This diff is large: its 100 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 629 lines aren’t shown here.
Binary file not shown.
This diff is large: its 51 lines aren’t shown here.
Binary file not shown.
This diff is large: its 148 lines aren’t shown here.
Binary file not shown.
This diff is large: its 305 lines aren’t shown here.
Binary file not shown.
This diff is large: its 379 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1226 lines aren’t shown here.
Binary file not shown.
This diff is large: its 567 lines aren’t shown here.
Binary file not shown.
This diff is large: its 1531 lines aren’t shown here.
Binary file not shown.
This diff is large: its 118 lines aren’t shown here.
Binary file not shown.
This diff is large: its 140 lines aren’t shown here.
Binary file not shown.
This diff is large: its 79 lines aren’t shown here.
Binary file not shown.
This diff is large: its 108 lines aren’t shown here.
Binary file not shown.
This diff is large: its 271 lines aren’t shown here.
Binary file not shown.
This diff is large: its 170 lines aren’t shown here.
Binary file not shown.
This diff is large: its 192 lines aren’t shown here.
Binary file not shown.
This diff is large: its 287 lines aren’t shown here.
Binary file not shown.
This diff is large: its 269 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 135 lines aren’t shown here.
This diff is large: its 118 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1614 lines aren’t shown here.
Binary file not shown.
This diff is large: its 59 lines aren’t shown here.
Binary file not shown.
This diff is large: its 262 lines aren’t shown here.
Binary file not shown.
This diff is large: its 78 lines aren’t shown here.
Binary file not shown.
This diff is large: its 105 lines aren’t shown here.
Binary file not shown.
This diff is large: its 55 lines aren’t shown here.
Binary file not shown.
This diff is large: its 126 lines aren’t shown here.
Binary file not shown.
This diff is large: its 47 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1257 lines aren’t shown here.
Binary file not shown.
This diff is large: its 58 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 422 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
Binary file not shown.
This diff is large: its 275 lines aren’t shown here.
Binary file not shown.
This diff is large: its 189 lines aren’t shown here.
Binary file not shown.
This diff is large: its 1257 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 5649 lines aren’t shown here.
Binary file not shown.
This diff is large: its 125 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 237 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
Binary file not shown.
This diff is large: its 120 lines aren’t shown here.
Binary file not shown.
This diff is large: its 145 lines aren’t shown here.
Binary file not shown.
This diff is large: its 139 lines aren’t shown here.
Binary file not shown.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
Binary file not shown.
This diff is large: its 96 lines aren’t shown here.
Binary file not shown.
This diff is large: its 94 lines aren’t shown here.
Binary file not shown.
This diff is large: its 117 lines aren’t shown here.
Binary file not shown.
This diff is large: its 85 lines aren’t shown here.
Binary file not shown.
This diff is large: its 61 lines aren’t shown here.
Binary file not shown.
This diff is large: its 53 lines aren’t shown here.
Binary file not shown.
This diff is large: its 551 lines aren’t shown here.
Binary file not shown.
This diff is large: its 295 lines aren’t shown here.
Binary file not shown.
This diff is large: its 285 lines aren’t shown here.
Binary file not shown.
This diff is large: its 290 lines aren’t shown here.
Binary file not shown.
This diff is large: its 224 lines aren’t shown here.
Binary file not shown.
This diff is large: its 403 lines aren’t shown here.
Binary file not shown.
This diff is large: its 289 lines aren’t shown here.
Binary file not shown.
This diff is large: its 277 lines aren’t shown here.
Binary file not shown.
This diff is large: its 47 lines aren’t shown here.
Binary file not shown.
This diff is large: its 160 lines aren’t shown here.
Binary file not shown.
This diff is large: its 99 lines aren’t shown here.
Binary file not shown.
This diff is large: its 85 lines aren’t shown here.
Binary file not shown.
This diff is large: its 328 lines aren’t shown here.
Binary file not shown.
This diff is large: its 45 lines aren’t shown here.
Binary file not shown.
This diff is large: its 61 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 763 lines aren’t shown here.
Binary file not shown.
This diff is large: its 457 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 621 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 99 lines aren’t shown here.