• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 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.checkNotNull;
19 import static com.google.common.base.Preconditions.checkPositionIndexes;
20 
21 import com.google.common.annotations.GwtCompatible;
22 import java.util.Arrays;
23 import java.util.Comparator;
24 
25 /**
26  * Static utility methods pertaining to {@code byte} primitives that interpret values as signed. The
27  * corresponding methods that treat the values as unsigned are found in {@link UnsignedBytes}, and
28  * the methods for which signedness is not an issue are in {@link Bytes}.
29  *
30  * <p>See the Guava User Guide article on <a
31  * href="https://github.com/google/guava/wiki/PrimitivesExplained">primitive utilities</a>.
32  *
33  * @author Kevin Bourrillion
34  * @since 1.0
35  */
36 // TODO(kevinb): how to prevent warning on UnsignedBytes when building GWT
37 // javadoc?
38 @GwtCompatible
39 public final class SignedBytes {
SignedBytes()40   private SignedBytes() {}
41 
42   /**
43    * The largest power of two that can be represented as a signed {@code byte}.
44    *
45    * @since 10.0
46    */
47   public static final byte MAX_POWER_OF_TWO = 1 << 6;
48 
49   /**
50    * Returns the {@code byte} value that is equal to {@code value}, if possible.
51    *
52    * @param value any value in the range of the {@code byte} type
53    * @return the {@code byte} value that equals {@code value}
54    * @throws IllegalArgumentException if {@code value} is greater than {@link Byte#MAX_VALUE} or
55    *     less than {@link Byte#MIN_VALUE}
56    */
checkedCast(long value)57   public static byte checkedCast(long value) {
58     byte result = (byte) value;
59     checkArgument(result == value, "Out of range: %s", value);
60     return result;
61   }
62 
63   /**
64    * Returns the {@code byte} nearest in value to {@code value}.
65    *
66    * @param value any {@code long} value
67    * @return the same value cast to {@code byte} if it is in the range of the {@code byte} type,
68    *     {@link Byte#MAX_VALUE} if it is too large, or {@link Byte#MIN_VALUE} if it is too small
69    */
saturatedCast(long value)70   public static byte saturatedCast(long value) {
71     if (value > Byte.MAX_VALUE) {
72       return Byte.MAX_VALUE;
73     }
74     if (value < Byte.MIN_VALUE) {
75       return Byte.MIN_VALUE;
76     }
77     return (byte) value;
78   }
79 
80   /**
81    * Compares the two specified {@code byte} values. The sign of the value returned is the same as
82    * that of {@code ((Byte) a).compareTo(b)}.
83    *
84    * <p><b>Note:</b> this method behaves identically to the JDK 7 method {@link Byte#compare}.
85    *
86    * @param a the first {@code byte} to compare
87    * @param b the second {@code byte} to compare
88    * @return a negative value if {@code a} is less than {@code b}; a positive value if {@code a} is
89    *     greater than {@code b}; or zero if they are equal
90    */
91   // TODO(kevinb): if Ints.compare etc. are ever removed, *maybe* remove this
92   // one too, which would leave compare methods only on the Unsigned* classes.
compare(byte a, byte b)93   public static int compare(byte a, byte b) {
94     return a - b; // safe due to restricted range
95   }
96 
97   /**
98    * Returns the least value present in {@code array}.
99    *
100    * @param array a <i>nonempty</i> array of {@code byte} values
101    * @return the value present in {@code array} that is less than or equal to every other value in
102    *     the array
103    * @throws IllegalArgumentException if {@code array} is empty
104    */
min(byte... array)105   public static byte min(byte... array) {
106     checkArgument(array.length > 0);
107     byte min = array[0];
108     for (int i = 1; i < array.length; i++) {
109       if (array[i] < min) {
110         min = array[i];
111       }
112     }
113     return min;
114   }
115 
116   /**
117    * Returns the greatest value present in {@code array}.
118    *
119    * @param array a <i>nonempty</i> array of {@code byte} values
120    * @return the value present in {@code array} that is greater than or equal to every other value
121    *     in the array
122    * @throws IllegalArgumentException if {@code array} is empty
123    */
max(byte... array)124   public static byte max(byte... array) {
125     checkArgument(array.length > 0);
126     byte max = array[0];
127     for (int i = 1; i < array.length; i++) {
128       if (array[i] > max) {
129         max = array[i];
130       }
131     }
132     return max;
133   }
134 
135   /**
136    * Returns a string containing the supplied {@code byte} values separated by {@code separator}.
137    * For example, {@code join(":", 0x01, 0x02, -0x01)} returns the string {@code "1:2:-1"}.
138    *
139    * @param separator the text that should appear between consecutive values in the resulting string
140    *     (but not at the start or end)
141    * @param array an array of {@code byte} values, possibly empty
142    */
join(String separator, byte... array)143   public static String join(String separator, byte... array) {
144     checkNotNull(separator);
145     if (array.length == 0) {
146       return "";
147     }
148 
149     // For pre-sizing a builder, just get the right order of magnitude
150     StringBuilder builder = new StringBuilder(array.length * 5);
151     builder.append(array[0]);
152     for (int i = 1; i < array.length; i++) {
153       builder.append(separator).append(array[i]);
154     }
155     return builder.toString();
156   }
157 
158   /**
159    * Returns a comparator that compares two {@code byte} arrays <a
160    * href="http://en.wikipedia.org/wiki/Lexicographical_order">lexicographically</a>. That is, it
161    * compares, using {@link #compare(byte, byte)}), the first pair of values that follow any common
162    * prefix, or when one array is a prefix of the other, treats the shorter array as the lesser. For
163    * example, {@code [] < [0x01] < [0x01, 0x80] < [0x01, 0x7F] < [0x02]}. Values are treated as
164    * signed.
165    *
166    * <p>The returned comparator is inconsistent with {@link Object#equals(Object)} (since arrays
167    * support only identity equality), but it is consistent with {@link
168    * java.util.Arrays#equals(byte[], byte[])}.
169    *
170    * @since 2.0
171    */
lexicographicalComparator()172   public static Comparator<byte[]> lexicographicalComparator() {
173     return LexicographicalComparator.INSTANCE;
174   }
175 
176   private enum LexicographicalComparator implements Comparator<byte[]> {
177     INSTANCE;
178 
179     @Override
compare(byte[] left, byte[] right)180     public int compare(byte[] left, byte[] right) {
181       int minLength = Math.min(left.length, right.length);
182       for (int i = 0; i < minLength; i++) {
183         int result = SignedBytes.compare(left[i], right[i]);
184         if (result != 0) {
185           return result;
186         }
187       }
188       return left.length - right.length;
189     }
190 
191     @Override
toString()192     public String toString() {
193       return "SignedBytes.lexicographicalComparator()";
194     }
195   }
196 
197   /**
198    * Sorts the elements of {@code array} in descending order.
199    *
200    * @since 23.1
201    */
sortDescending(byte[] array)202   public static void sortDescending(byte[] array) {
203     checkNotNull(array);
204     sortDescending(array, 0, array.length);
205   }
206 
207   /**
208    * Sorts the elements of {@code array} between {@code fromIndex} inclusive and {@code toIndex}
209    * exclusive in descending order.
210    *
211    * @since 23.1
212    */
sortDescending(byte[] array, int fromIndex, int toIndex)213   public static void sortDescending(byte[] array, int fromIndex, int toIndex) {
214     checkNotNull(array);
215     checkPositionIndexes(fromIndex, toIndex, array.length);
216     Arrays.sort(array, fromIndex, toIndex);
217     Bytes.reverse(array, fromIndex, toIndex);
218   }
219 }
220