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