Home | History | Annotate | Download | only in primitives
      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 {
     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    */
     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    */
     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    */
    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    */
    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
    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    */
    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    */
    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
    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    */
    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    */
    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    */
    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    */
    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    */
    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    */
    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>'&#92;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
    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
    375     protected Long doForward(String value) {
    376       return Long.decode(value);
    377     }
    378 
    379     @Override
    380     protected String doBackward(Long value) {
    381       return value.toString();
    382     }
    383 
    384     @Override
    385     public String toString() {
    386       return "Longs.stringConverter()";
    387     }
    388 
    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
    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    */
    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
    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    */
    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    */
    478   public static Comparator<long[]> lexicographicalComparator() {
    479     return LexicographicalComparator.INSTANCE;
    480   }
    481 
    482   private enum LexicographicalComparator implements Comparator<long[]> {
    483     INSTANCE;
    484 
    485     @Override
    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    */
    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    */
    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 
    556     LongArrayAsList(long[] array) {
    557       this(array, 0, array.length);
    558     }
    559 
    560     LongArrayAsList(long[] array, int start, int end) {
    561       this.array = array;
    562       this.start = start;
    563       this.end = end;
    564     }
    565 
    566     @Override public int size() {
    567       return end - start;
    568     }
    569 
    570     @Override public boolean isEmpty() {
    571       return false;
    572     }
    573 
    574     @Override public Long get(int index) {
    575       checkElementIndex(index, size());
    576       return array[start + index];
    577     }
    578 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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