Coverage Summary for Class: Longs (com.google.common.primitives)

Class Method, % Line, %
Longs 3.4% (1/29) 0.8% (1/128)
Longs$AsciiDigits 0% (0/3) 0% (0/10)
Longs$LexicographicalComparator 0% (0/3) 0% (0/9)
Longs$LongArrayAsList 0% (0/15) 0% (0/52)
Longs$LongConverter 0% (0/6) 0% (0/6)
Total 1.8% (1/56) 0.5% (1/205)


1 /* 2  * Copyright (C) 2008 The Guava Authors 3  * 4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5  * in compliance with the License. You may obtain a copy of the License at 6  * 7  * http://www.apache.org/licenses/LICENSE-2.0 8  * 9  * Unless required by applicable law or agreed to in writing, software distributed under the License 10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11  * or implied. See the License for the specific language governing permissions and limitations under 12  * the License. 13  */ 14  15 package com.google.common.primitives; 16  17 import static com.google.common.base.Preconditions.checkArgument; 18 import static com.google.common.base.Preconditions.checkElementIndex; 19 import static com.google.common.base.Preconditions.checkNotNull; 20 import static com.google.common.base.Preconditions.checkPositionIndexes; 21  22 import com.google.common.annotations.Beta; 23 import com.google.common.annotations.GwtCompatible; 24 import com.google.common.base.Converter; 25 import java.io.Serializable; 26 import java.util.AbstractList; 27 import java.util.Arrays; 28 import java.util.Collection; 29 import java.util.Collections; 30 import java.util.Comparator; 31 import java.util.List; 32 import java.util.RandomAccess; 33 import java.util.Spliterator; 34 import java.util.Spliterators; 35 import javax.annotation.CheckForNull; 36  37 /** 38  * Static utility methods pertaining to {@code long} primitives, that are not already found in 39  * either {@link Long} or {@link Arrays}. 40  * 41  * <p>See the Guava User Guide article on <a 42  * href="https://github.com/google/guava/wiki/PrimitivesExplained">primitive utilities</a>. 43  * 44  * @author Kevin Bourrillion 45  * @since 1.0 46  */ 47 @GwtCompatible 48 @ElementTypesAreNonnullByDefault 49 public final class Longs { 50  private Longs() {} 51  52  /** 53  * The number of bytes required to represent a primitive {@code long} value. 54  * 55  * <p><b>Java 8 users:</b> use {@link Long#BYTES} instead. 56  */ 57  public static final int BYTES = Long.SIZE / Byte.SIZE; 58  59  /** 60  * The largest power of two that can be represented as a {@code long}. 61  * 62  * @since 10.0 63  */ 64  public static final long MAX_POWER_OF_TWO = 1L << (Long.SIZE - 2); 65  66  /** 67  * Returns a hash code for {@code value}; equal to the result of invoking {@code ((Long) 68  * value).hashCode()}. 69  * 70  * <p>This method always return the value specified by {@link Long#hashCode()} in java, which 71  * might be different from {@code ((Long) value).hashCode()} in GWT because {@link 72  * Long#hashCode()} in GWT does not obey the JRE contract. 73  * 74  * <p><b>Java 8 users:</b> use {@link Long#hashCode(long)} instead. 75  * 76  * @param value a primitive {@code long} value 77  * @return a hash code for the value 78  */ 79  public static int hashCode(long value) { 80  return (int) (value ^ (value >>> 32)); 81  } 82  83  /** 84  * Compares the two specified {@code long} values. The sign of the value returned is the same as 85  * that of {@code ((Long) a).compareTo(b)}. 86  * 87  * <p><b>Note for Java 7 and later:</b> this method should be treated as deprecated; use the 88  * equivalent {@link Long#compare} method instead. 89  * 90  * @param a the first {@code long} to compare 91  * @param b the second {@code long} to compare 92  * @return a negative value if {@code a} is less than {@code b}; a positive value if {@code a} is 93  * greater than {@code b}; or zero if they are equal 94  */ 95  public static int compare(long a, long b) { 96  return (a < b) ? -1 : ((a > b) ? 1 : 0); 97  } 98  99  /** 100  * Returns {@code true} if {@code target} is present as an element anywhere in {@code array}. 101  * 102  * @param array an array of {@code long} values, possibly empty 103  * @param target a primitive {@code long} value 104  * @return {@code true} if {@code array[i] == target} for some value of {@code i} 105  */ 106  public static boolean contains(long[] array, long target) { 107  for (long value : array) { 108  if (value == target) { 109  return true; 110  } 111  } 112  return false; 113  } 114  115  /** 116  * Returns the index of the first appearance of the value {@code target} in {@code array}. 117  * 118  * @param array an array of {@code long} values, possibly empty 119  * @param target a primitive {@code long} value 120  * @return the least index {@code i} for which {@code array[i] == target}, or {@code -1} if no 121  * such index exists. 122  */ 123  public static int indexOf(long[] array, long target) { 124  return indexOf(array, target, 0, array.length); 125  } 126  127  // TODO(kevinb): consider making this public 128  private static int indexOf(long[] array, long target, int start, int end) { 129  for (int i = start; i < end; i++) { 130  if (array[i] == target) { 131  return i; 132  } 133  } 134  return -1; 135  } 136  137  /** 138  * Returns the start position of the first occurrence of the specified {@code target} within 139  * {@code array}, or {@code -1} if there is no such occurrence. 140  * 141  * <p>More formally, returns the lowest index {@code i} such that {@code Arrays.copyOfRange(array, 142  * i, i + target.length)} contains exactly the same elements as {@code target}. 143  * 144  * @param array the array to search for the sequence {@code target} 145  * @param target the array to search for as a sub-sequence of {@code array} 146  */ 147  public static int indexOf(long[] array, long[] target) { 148  checkNotNull(array, "array"); 149  checkNotNull(target, "target"); 150  if (target.length == 0) { 151  return 0; 152  } 153  154  outer: 155  for (int i = 0; i < array.length - target.length + 1; i++) { 156  for (int j = 0; j < target.length; j++) { 157  if (array[i + j] != target[j]) { 158  continue outer; 159  } 160  } 161  return i; 162  } 163  return -1; 164  } 165  166  /** 167  * Returns the index of the last appearance of the value {@code target} in {@code array}. 168  * 169  * @param array an array of {@code long} values, possibly empty 170  * @param target a primitive {@code long} value 171  * @return the greatest index {@code i} for which {@code array[i] == target}, or {@code -1} if no 172  * such index exists. 173  */ 174  public static int lastIndexOf(long[] array, long target) { 175  return lastIndexOf(array, target, 0, array.length); 176  } 177  178  // TODO(kevinb): consider making this public 179  private static int lastIndexOf(long[] array, long target, int start, int end) { 180  for (int i = end - 1; i >= start; i--) { 181  if (array[i] == target) { 182  return i; 183  } 184  } 185  return -1; 186  } 187  188  /** 189  * Returns the least value present in {@code array}. 190  * 191  * @param array a <i>nonempty</i> array of {@code long} values 192  * @return the value present in {@code array} that is less than or equal to every other value in 193  * the array 194  * @throws IllegalArgumentException if {@code array} is empty 195  */ 196  public static long min(long... array) { 197  checkArgument(array.length > 0); 198  long min = array[0]; 199  for (int i = 1; i < array.length; i++) { 200  if (array[i] < min) { 201  min = array[i]; 202  } 203  } 204  return min; 205  } 206  207  /** 208  * Returns the greatest value present in {@code array}. 209  * 210  * @param array a <i>nonempty</i> array of {@code long} values 211  * @return the value present in {@code array} that is greater than or equal to every other value 212  * in the array 213  * @throws IllegalArgumentException if {@code array} is empty 214  */ 215  public static long max(long... array) { 216  checkArgument(array.length > 0); 217  long max = array[0]; 218  for (int i = 1; i < array.length; i++) { 219  if (array[i] > max) { 220  max = array[i]; 221  } 222  } 223  return max; 224  } 225  226  /** 227  * Returns the value nearest to {@code value} which is within the closed range {@code [min..max]}. 228  * 229  * <p>If {@code value} is within the range {@code [min..max]}, {@code value} is returned 230  * unchanged. If {@code value} is less than {@code min}, {@code min} is returned, and if {@code 231  * value} is greater than {@code max}, {@code max} is returned. 232  * 233  * @param value the {@code long} value to constrain 234  * @param min the lower bound (inclusive) of the range to constrain {@code value} to 235  * @param max the upper bound (inclusive) of the range to constrain {@code value} to 236  * @throws IllegalArgumentException if {@code min > max} 237  * @since 21.0 238  */ 239  @Beta 240  public static long constrainToRange(long value, long min, long max) { 241  checkArgument(min <= max, "min (%s) must be less than or equal to max (%s)", min, max); 242  return Math.min(Math.max(value, min), max); 243  } 244  245  /** 246  * Returns the values from each provided array combined into a single array. For example, {@code 247  * concat(new long[] {a, b}, new long[] {}, new long[] {c}} returns the array {@code {a, b, c}}. 248  * 249  * @param arrays zero or more {@code long} arrays 250  * @return a single array containing all the values from the source arrays, in order 251  */ 252  public static long[] concat(long[]... arrays) { 253  int length = 0; 254  for (long[] array : arrays) { 255  length += array.length; 256  } 257  long[] result = new long[length]; 258  int pos = 0; 259  for (long[] array : arrays) { 260  System.arraycopy(array, 0, result, pos, array.length); 261  pos += array.length; 262  } 263  return result; 264  } 265  266  /** 267  * Returns a big-endian representation of {@code value} in an 8-element byte array; equivalent to 268  * {@code ByteBuffer.allocate(8).putLong(value).array()}. For example, the input value {@code 269  * 0x1213141516171819L} would yield the byte array {@code {0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 270  * 0x18, 0x19}}. 271  * 272  * <p>If you need to convert and concatenate several values (possibly even of different types), 273  * use a shared {@link java.nio.ByteBuffer} instance, or use {@link 274  * com.google.common.io.ByteStreams#newDataOutput()} to get a growable buffer. 275  */ 276  public static byte[] toByteArray(long value) { 277  // Note that this code needs to stay compatible with GWT, which has known 278  // bugs when narrowing byte casts of long values occur. 279  byte[] result = new byte[8]; 280  for (int i = 7; i >= 0; i--) { 281  result[i] = (byte) (value & 0xffL); 282  value >>= 8; 283  } 284  return result; 285  } 286  287  /** 288  * Returns the {@code long} value whose big-endian representation is stored in the first 8 bytes 289  * of {@code bytes}; equivalent to {@code ByteBuffer.wrap(bytes).getLong()}. For example, the 290  * input byte array {@code {0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19}} would yield the 291  * {@code long} value {@code 0x1213141516171819L}. 292  * 293  * <p>Arguably, it's preferable to use {@link java.nio.ByteBuffer}; that library exposes much more 294  * flexibility at little cost in readability. 295  * 296  * @throws IllegalArgumentException if {@code bytes} has fewer than 8 elements 297  */ 298  public static long fromByteArray(byte[] bytes) { 299  checkArgument(bytes.length >= BYTES, "array too small: %s < %s", bytes.length, BYTES); 300  return fromBytes( 301  bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]); 302  } 303  304  /** 305  * Returns the {@code long} value whose byte representation is the given 8 bytes, in big-endian 306  * order; equivalent to {@code Longs.fromByteArray(new byte[] {b1, b2, b3, b4, b5, b6, b7, b8})}. 307  * 308  * @since 7.0 309  */ 310  public static long fromBytes( 311  byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8) { 312  return (b1 & 0xFFL) << 56 313  | (b2 & 0xFFL) << 48 314  | (b3 & 0xFFL) << 40 315  | (b4 & 0xFFL) << 32 316  | (b5 & 0xFFL) << 24 317  | (b6 & 0xFFL) << 16 318  | (b7 & 0xFFL) << 8 319  | (b8 & 0xFFL); 320  } 321  322  /* 323  * Moving asciiDigits into this static holder class lets ProGuard eliminate and inline the Longs 324  * class. 325  */ 326  static final class AsciiDigits { 327  private AsciiDigits() {} 328  329  private static final byte[] asciiDigits; 330  331  static { 332  byte[] result = new byte[128]; 333  Arrays.fill(result, (byte) -1); 334  for (int i = 0; i < 10; i++) { 335  result['0' + i] = (byte) i; 336  } 337  for (int i = 0; i < 26; i++) { 338  result['A' + i] = (byte) (10 + i); 339  result['a' + i] = (byte) (10 + i); 340  } 341  asciiDigits = result; 342  } 343  344  static int digit(char c) { 345  return (c < 128) ? asciiDigits[c] : -1; 346  } 347  } 348  349  /** 350  * Parses the specified string as a signed decimal long value. The ASCII character {@code '-'} ( 351  * <code>'&#92;u002D'</code>) is recognized as the minus sign. 352  * 353  * <p>Unlike {@link Long#parseLong(String)}, this method returns {@code null} instead of throwing 354  * an exception if parsing fails. Additionally, this method only accepts ASCII digits, and returns 355  * {@code null} if non-ASCII digits are present in the string. 356  * 357  * <p>Note that strings prefixed with ASCII {@code '+'} are rejected, even under JDK 7, despite 358  * the change to {@link Long#parseLong(String)} for that version. 359  * 360  * @param string the string representation of a long value 361  * @return the long value represented by {@code string}, or {@code null} if {@code string} has a 362  * length of zero or cannot be parsed as a long value 363  * @throws NullPointerException if {@code string} is {@code null} 364  * @since 14.0 365  */ 366  @Beta 367  @CheckForNull 368  public static Long tryParse(String string) { 369  return tryParse(string, 10); 370  } 371  372  /** 373  * Parses the specified string as a signed long value using the specified radix. The ASCII 374  * character {@code '-'} (<code>'&#92;u002D'</code>) is recognized as the minus sign. 375  * 376  * <p>Unlike {@link Long#parseLong(String, int)}, this method returns {@code null} instead of 377  * throwing an exception if parsing fails. Additionally, this method only accepts ASCII digits, 378  * and returns {@code null} if non-ASCII digits are present in the string. 379  * 380  * <p>Note that strings prefixed with ASCII {@code '+'} are rejected, even under JDK 7, despite 381  * the change to {@link Long#parseLong(String, int)} for that version. 382  * 383  * @param string the string representation of an long value 384  * @param radix the radix to use when parsing 385  * @return the long value represented by {@code string} using {@code radix}, or {@code null} if 386  * {@code string} has a length of zero or cannot be parsed as a long value 387  * @throws IllegalArgumentException if {@code radix < Character.MIN_RADIX} or {@code radix > 388  * Character.MAX_RADIX} 389  * @throws NullPointerException if {@code string} is {@code null} 390  * @since 19.0 391  */ 392  @Beta 393  @CheckForNull 394  public static Long tryParse(String string, int radix) { 395  if (checkNotNull(string).isEmpty()) { 396  return null; 397  } 398  if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) { 399  throw new IllegalArgumentException( 400  "radix must be between MIN_RADIX and MAX_RADIX but was " + radix); 401  } 402  boolean negative = string.charAt(0) == '-'; 403  int index = negative ? 1 : 0; 404  if (index == string.length()) { 405  return null; 406  } 407  int digit = AsciiDigits.digit(string.charAt(index++)); 408  if (digit < 0 || digit >= radix) { 409  return null; 410  } 411  long accum = -digit; 412  413  long cap = Long.MIN_VALUE / radix; 414  415  while (index < string.length()) { 416  digit = AsciiDigits.digit(string.charAt(index++)); 417  if (digit < 0 || digit >= radix || accum < cap) { 418  return null; 419  } 420  accum *= radix; 421  if (accum < Long.MIN_VALUE + digit) { 422  return null; 423  } 424  accum -= digit; 425  } 426  427  if (negative) { 428  return accum; 429  } else if (accum == Long.MIN_VALUE) { 430  return null; 431  } else { 432  return -accum; 433  } 434  } 435  436  private static final class LongConverter extends Converter<String, Long> implements Serializable { 437  static final LongConverter INSTANCE = new LongConverter(); 438  439  @Override 440  protected Long doForward(String value) { 441  return Long.decode(value); 442  } 443  444  @Override 445  protected String doBackward(Long value) { 446  return value.toString(); 447  } 448  449  @Override 450  public String toString() { 451  return "Longs.stringConverter()"; 452  } 453  454  private Object readResolve() { 455  return INSTANCE; 456  } 457  458  private static final long serialVersionUID = 1; 459  } 460  461  /** 462  * Returns a serializable converter object that converts between strings and longs using {@link 463  * Long#decode} and {@link Long#toString()}. The returned converter throws {@link 464  * NumberFormatException} if the input string is invalid. 465  * 466  * <p><b>Warning:</b> please see {@link Long#decode} to understand exactly how strings are parsed. 467  * For example, the string {@code "0123"} is treated as <i>octal</i> and converted to the value 468  * {@code 83L}. 469  * 470  * @since 16.0 471  */ 472  @Beta 473  public static Converter<String, Long> stringConverter() { 474  return LongConverter.INSTANCE; 475  } 476  477  /** 478  * Returns an array containing the same values as {@code array}, but guaranteed to be of a 479  * specified minimum length. If {@code array} already has a length of at least {@code minLength}, 480  * it is returned directly. Otherwise, a new array of size {@code minLength + padding} is 481  * returned, containing the values of {@code array}, and zeroes in the remaining places. 482  * 483  * @param array the source array 484  * @param minLength the minimum length the returned array must guarantee 485  * @param padding an extra amount to "grow" the array by if growth is necessary 486  * @throws IllegalArgumentException if {@code minLength} or {@code padding} is negative 487  * @return an array containing the values of {@code array}, with guaranteed minimum length {@code 488  * minLength} 489  */ 490  public static long[] ensureCapacity(long[] array, int minLength, int padding) { 491  checkArgument(minLength >= 0, "Invalid minLength: %s", minLength); 492  checkArgument(padding >= 0, "Invalid padding: %s", padding); 493  return (array.length < minLength) ? Arrays.copyOf(array, minLength + padding) : array; 494  } 495  496  /** 497  * Returns a string containing the supplied {@code long} values separated by {@code separator}. 498  * For example, {@code join("-", 1L, 2L, 3L)} returns the string {@code "1-2-3"}. 499  * 500  * @param separator the text that should appear between consecutive values in the resulting string 501  * (but not at the start or end) 502  * @param array an array of {@code long} values, possibly empty 503  */ 504  public static String join(String separator, long... array) { 505  checkNotNull(separator); 506  if (array.length == 0) { 507  return ""; 508  } 509  510  // For pre-sizing a builder, just get the right order of magnitude 511  StringBuilder builder = new StringBuilder(array.length * 10); 512  builder.append(array[0]); 513  for (int i = 1; i < array.length; i++) { 514  builder.append(separator).append(array[i]); 515  } 516  return builder.toString(); 517  } 518  519  /** 520  * Returns a comparator that compares two {@code long} arrays <a 521  * href="http://en.wikipedia.org/wiki/Lexicographical_order">lexicographically</a>. That is, it 522  * compares, using {@link #compare(long, long)}), the first pair of values that follow any common 523  * prefix, or when one array is a prefix of the other, treats the shorter array as the lesser. For 524  * example, {@code [] < [1L] < [1L, 2L] < [2L]}. 525  * 526  * <p>The returned comparator is inconsistent with {@link Object#equals(Object)} (since arrays 527  * support only identity equality), but it is consistent with {@link Arrays#equals(long[], 528  * long[])}. 529  * 530  * @since 2.0 531  */ 532  public static Comparator<long[]> lexicographicalComparator() { 533  return LexicographicalComparator.INSTANCE; 534  } 535  536  private enum LexicographicalComparator implements Comparator<long[]> { 537  INSTANCE; 538  539  @Override 540  public int compare(long[] left, long[] right) { 541  int minLength = Math.min(left.length, right.length); 542  for (int i = 0; i < minLength; i++) { 543  int result = Longs.compare(left[i], right[i]); 544  if (result != 0) { 545  return result; 546  } 547  } 548  return left.length - right.length; 549  } 550  551  @Override 552  public String toString() { 553  return "Longs.lexicographicalComparator()"; 554  } 555  } 556  557  /** 558  * Sorts the elements of {@code array} in descending order. 559  * 560  * @since 23.1 561  */ 562  public static void sortDescending(long[] array) { 563  checkNotNull(array); 564  sortDescending(array, 0, array.length); 565  } 566  567  /** 568  * Sorts the elements of {@code array} between {@code fromIndex} inclusive and {@code toIndex} 569  * exclusive in descending order. 570  * 571  * @since 23.1 572  */ 573  public static void sortDescending(long[] array, int fromIndex, int toIndex) { 574  checkNotNull(array); 575  checkPositionIndexes(fromIndex, toIndex, array.length); 576  Arrays.sort(array, fromIndex, toIndex); 577  reverse(array, fromIndex, toIndex); 578  } 579  580  /** 581  * Reverses the elements of {@code array}. This is equivalent to {@code 582  * Collections.reverse(Longs.asList(array))}, but is likely to be more efficient. 583  * 584  * @since 23.1 585  */ 586  public static void reverse(long[] array) { 587  checkNotNull(array); 588  reverse(array, 0, array.length); 589  } 590  591  /** 592  * Reverses the elements of {@code array} between {@code fromIndex} inclusive and {@code toIndex} 593  * exclusive. This is equivalent to {@code 594  * Collections.reverse(Longs.asList(array).subList(fromIndex, toIndex))}, but is likely to be more 595  * efficient. 596  * 597  * @throws IndexOutOfBoundsException if {@code fromIndex < 0}, {@code toIndex > array.length}, or 598  * {@code toIndex > fromIndex} 599  * @since 23.1 600  */ 601  public static void reverse(long[] array, int fromIndex, int toIndex) { 602  checkNotNull(array); 603  checkPositionIndexes(fromIndex, toIndex, array.length); 604  for (int i = fromIndex, j = toIndex - 1; i < j; i++, j--) { 605  long tmp = array[i]; 606  array[i] = array[j]; 607  array[j] = tmp; 608  } 609  } 610  611  /** 612  * Returns an array containing each value of {@code collection}, converted to a {@code long} value 613  * in the manner of {@link Number#longValue}. 614  * 615  * <p>Elements are copied from the argument collection as if by {@code collection.toArray()}. 616  * Calling this method is as thread-safe as calling that method. 617  * 618  * @param collection a collection of {@code Number} instances 619  * @return an array containing the same values as {@code collection}, in the same order, converted 620  * to primitives 621  * @throws NullPointerException if {@code collection} or any of its elements is null 622  * @since 1.0 (parameter was {@code Collection<Long>} before 12.0) 623  */ 624  public static long[] toArray(Collection<? extends Number> collection) { 625  if (collection instanceof LongArrayAsList) { 626  return ((LongArrayAsList) collection).toLongArray(); 627  } 628  629  Object[] boxedArray = collection.toArray(); 630  int len = boxedArray.length; 631  long[] array = new long[len]; 632  for (int i = 0; i < len; i++) { 633  // checkNotNull for GWT (do not optimize) 634  array[i] = ((Number) checkNotNull(boxedArray[i])).longValue(); 635  } 636  return array; 637  } 638  639  /** 640  * Returns a fixed-size list backed by the specified array, similar to {@link 641  * Arrays#asList(Object[])}. The list supports {@link List#set(int, Object)}, but any attempt to 642  * set a value to {@code null} will result in a {@link NullPointerException}. 643  * 644  * <p>The returned list maintains the values, but not the identities, of {@code Long} objects 645  * written to or read from it. For example, whether {@code list.get(0) == list.get(0)} is true for 646  * the returned list is unspecified. 647  * 648  * <p><b>Note:</b> when possible, you should represent your data as an {@link ImmutableLongArray} 649  * instead, which has an {@link ImmutableLongArray#asList asList} view. 650  * 651  * @param backingArray the array to back the list 652  * @return a list view of the array 653  */ 654  public static List<Long> asList(long... backingArray) { 655  if (backingArray.length == 0) { 656  return Collections.emptyList(); 657  } 658  return new LongArrayAsList(backingArray); 659  } 660  661  @GwtCompatible 662  private static class LongArrayAsList extends AbstractList<Long> 663  implements RandomAccess, Serializable { 664  final long[] array; 665  final int start; 666  final int end; 667  668  LongArrayAsList(long[] array) { 669  this(array, 0, array.length); 670  } 671  672  LongArrayAsList(long[] array, int start, int end) { 673  this.array = array; 674  this.start = start; 675  this.end = end; 676  } 677  678  @Override 679  public int size() { 680  return end - start; 681  } 682  683  @Override 684  public boolean isEmpty() { 685  return false; 686  } 687  688  @Override 689  public Long get(int index) { 690  checkElementIndex(index, size()); 691  return array[start + index]; 692  } 693  694  @Override 695  public Spliterator.OfLong spliterator() { 696  return Spliterators.spliterator(array, start, end, 0); 697  } 698  699  @Override 700  public boolean contains(@CheckForNull Object target) { 701  // Overridden to prevent a ton of boxing 702  return (target instanceof Long) && Longs.indexOf(array, (Long) target, start, end) != -1; 703  } 704  705  @Override 706  public int indexOf(@CheckForNull Object target) { 707  // Overridden to prevent a ton of boxing 708  if (target instanceof Long) { 709  int i = Longs.indexOf(array, (Long) target, start, end); 710  if (i >= 0) { 711  return i - start; 712  } 713  } 714  return -1; 715  } 716  717  @Override 718  public int lastIndexOf(@CheckForNull Object target) { 719  // Overridden to prevent a ton of boxing 720  if (target instanceof Long) { 721  int i = Longs.lastIndexOf(array, (Long) target, start, end); 722  if (i >= 0) { 723  return i - start; 724  } 725  } 726  return -1; 727  } 728  729  @Override 730  public Long set(int index, Long element) { 731  checkElementIndex(index, size()); 732  long oldValue = array[start + index]; 733  // checkNotNull for GWT (do not optimize) 734  array[start + index] = checkNotNull(element); 735  return oldValue; 736  } 737  738  @Override 739  public List<Long> subList(int fromIndex, int toIndex) { 740  int size = size(); 741  checkPositionIndexes(fromIndex, toIndex, size); 742  if (fromIndex == toIndex) { 743  return Collections.emptyList(); 744  } 745  return new LongArrayAsList(array, start + fromIndex, start + toIndex); 746  } 747  748  @Override 749  public boolean equals(@CheckForNull Object object) { 750  if (object == this) { 751  return true; 752  } 753  if (object instanceof LongArrayAsList) { 754  LongArrayAsList that = (LongArrayAsList) object; 755  int size = size(); 756  if (that.size() != size) { 757  return false; 758  } 759  for (int i = 0; i < size; i++) { 760  if (array[start + i] != that.array[that.start + i]) { 761  return false; 762  } 763  } 764  return true; 765  } 766  return super.equals(object); 767  } 768  769  @Override 770  public int hashCode() { 771  int result = 1; 772  for (int i = start; i < end; i++) { 773  result = 31 * result + Longs.hashCode(array[i]); 774  } 775  return result; 776  } 777  778  @Override 779  public String toString() { 780  StringBuilder builder = new StringBuilder(size() * 10); 781  builder.append('[').append(array[start]); 782  for (int i = start + 1; i < end; i++) { 783  builder.append(", ").append(array[i]); 784  } 785  return builder.append(']').toString(); 786  } 787  788  long[] toLongArray() { 789  return Arrays.copyOfRange(array, start, end); 790  } 791  792  private static final long serialVersionUID = 0; 793  } 794 }