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