• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>'&#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
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