mirror of
https://github.com/Eaglercraft-Archive/Eaglercraftx-1.8.8-src.git
synced 2025-06-28 02:48:14 -05:00
Update #0 - First Release
This commit is contained in:
503
sources/main/java/com/google/common/primitives/Booleans.java
Normal file
503
sources/main/java/com/google/common/primitives/Booleans.java
Normal file
@ -0,0 +1,503 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.common.primitives;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkElementIndex;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkPositionIndexes;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.AbstractList;
|
||||
import java.util.Arrays;
|
||||
import java.util.BitSet;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.RandomAccess;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
|
||||
/**
|
||||
* Static utility methods pertaining to {@code boolean} primitives, that are not
|
||||
* already found in either {@link Boolean} or {@link Arrays}.
|
||||
*
|
||||
* <p>
|
||||
* See the Guava User Guide article on
|
||||
* <a href= "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained">
|
||||
* primitive utilities</a>.
|
||||
*
|
||||
* @author Kevin Bourrillion
|
||||
* @since 1.0
|
||||
*/
|
||||
@GwtCompatible
|
||||
public final class Booleans {
|
||||
private Booleans() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash code for {@code value}; equal to the result of invoking
|
||||
* {@code ((Boolean) value).hashCode()}.
|
||||
*
|
||||
* @param value a primitive {@code boolean} value
|
||||
* @return a hash code for the value
|
||||
*/
|
||||
public static int hashCode(boolean value) {
|
||||
return value ? 1231 : 1237;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the two specified {@code boolean} values in the standard way
|
||||
* ({@code false} is considered less than {@code true}). The sign of the value
|
||||
* returned is the same as that of {@code ((Boolean) a).compareTo(b)}.
|
||||
*
|
||||
* <p>
|
||||
* <b>Note:</b> projects using JDK 7 or later should use the equivalent
|
||||
* {@link Boolean#compare} method instead.
|
||||
*
|
||||
* @param a the first {@code boolean} to compare
|
||||
* @param b the second {@code boolean} to compare
|
||||
* @return a positive number if only {@code a} is {@code true}, a negative
|
||||
* number if only {@code b} is true, or zero if {@code a == b}
|
||||
*/
|
||||
public static int compare(boolean a, boolean b) {
|
||||
return (a == b) ? 0 : (a ? 1 : -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if {@code target} is present as an element anywhere in
|
||||
* {@code array}.
|
||||
*
|
||||
* <p>
|
||||
* <b>Note:</b> consider representing the array as a {@link BitSet} instead,
|
||||
* replacing {@code Booleans.contains(array, true)} with
|
||||
* {@code !bitSet.isEmpty()} and {@code Booleans.contains(array, false)} with
|
||||
* {@code bitSet.nextClearBit(0) == sizeOfBitSet}.
|
||||
*
|
||||
* @param array an array of {@code boolean} values, possibly empty
|
||||
* @param target a primitive {@code boolean} value
|
||||
* @return {@code true} if {@code array[i] == target} for some value of {@code
|
||||
* i}
|
||||
*/
|
||||
public static boolean contains(boolean[] array, boolean target) {
|
||||
for (boolean value : array) {
|
||||
if (value == target) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the first appearance of the value {@code target} in
|
||||
* {@code array}.
|
||||
*
|
||||
* <p>
|
||||
* <b>Note:</b> consider representing the array as a {@link BitSet} instead, and
|
||||
* using {@link BitSet#nextSetBit(int)} or {@link BitSet#nextClearBit(int)}.
|
||||
*
|
||||
* @param array an array of {@code boolean} values, possibly empty
|
||||
* @param target a primitive {@code boolean} value
|
||||
* @return the least index {@code i} for which {@code array[i] == target}, or
|
||||
* {@code -1} if no such index exists.
|
||||
*/
|
||||
public static int indexOf(boolean[] array, boolean target) {
|
||||
return indexOf(array, target, 0, array.length);
|
||||
}
|
||||
|
||||
// TODO(kevinb): consider making this public
|
||||
private static int indexOf(boolean[] array, boolean target, int start, int end) {
|
||||
for (int i = start; i < end; i++) {
|
||||
if (array[i] == target) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the start position of the first occurrence of the specified {@code
|
||||
* target} within {@code array}, or {@code -1} if there is no such occurrence.
|
||||
*
|
||||
* <p>
|
||||
* More formally, returns the lowest index {@code i} such that {@code
|
||||
* java.util.Arrays.copyOfRange(array, i, i + target.length)} contains exactly
|
||||
* the same elements as {@code target}.
|
||||
*
|
||||
* @param array the array to search for the sequence {@code target}
|
||||
* @param target the array to search for as a sub-sequence of {@code array}
|
||||
*/
|
||||
public static int indexOf(boolean[] array, boolean[] target) {
|
||||
checkNotNull(array, "array");
|
||||
checkNotNull(target, "target");
|
||||
if (target.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
outer: for (int i = 0; i < array.length - target.length + 1; i++) {
|
||||
for (int j = 0; j < target.length; j++) {
|
||||
if (array[i + j] != target[j]) {
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the last appearance of the value {@code target} in
|
||||
* {@code array}.
|
||||
*
|
||||
* @param array an array of {@code boolean} values, possibly empty
|
||||
* @param target a primitive {@code boolean} value
|
||||
* @return the greatest index {@code i} for which {@code array[i] == target}, or
|
||||
* {@code -1} if no such index exists.
|
||||
*/
|
||||
public static int lastIndexOf(boolean[] array, boolean target) {
|
||||
return lastIndexOf(array, target, 0, array.length);
|
||||
}
|
||||
|
||||
// TODO(kevinb): consider making this public
|
||||
private static int lastIndexOf(boolean[] array, boolean target, int start, int end) {
|
||||
for (int i = end - 1; i >= start; i--) {
|
||||
if (array[i] == target) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the values from each provided array combined into a single array. For
|
||||
* example, {@code concat(new boolean[] {a, b}, new boolean[] {}, new boolean[]
|
||||
* {c}} returns the array {@code {a, b, c}}.
|
||||
*
|
||||
* @param arrays zero or more {@code boolean} arrays
|
||||
* @return a single array containing all the values from the source arrays, in
|
||||
* order
|
||||
*/
|
||||
public static boolean[] concat(boolean[]... arrays) {
|
||||
int length = 0;
|
||||
for (boolean[] array : arrays) {
|
||||
length += array.length;
|
||||
}
|
||||
boolean[] result = new boolean[length];
|
||||
int pos = 0;
|
||||
for (boolean[] array : arrays) {
|
||||
System.arraycopy(array, 0, result, pos, array.length);
|
||||
pos += array.length;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing the same values as {@code array}, but guaranteed
|
||||
* to be of a specified minimum length. If {@code array} already has a length of
|
||||
* at least {@code minLength}, it is returned directly. Otherwise, a new array
|
||||
* of size {@code minLength + padding} is returned, containing the values of
|
||||
* {@code array}, and zeroes in the remaining places.
|
||||
*
|
||||
* @param array the source array
|
||||
* @param minLength the minimum length the returned array must guarantee
|
||||
* @param padding an extra amount to "grow" the array by if growth is
|
||||
* necessary
|
||||
* @throws IllegalArgumentException if {@code minLength} or {@code padding} is
|
||||
* negative
|
||||
* @return an array containing the values of {@code array}, with guaranteed
|
||||
* minimum length {@code minLength}
|
||||
*/
|
||||
public static boolean[] ensureCapacity(boolean[] array, int minLength, int padding) {
|
||||
checkArgument(minLength >= 0, "Invalid minLength: %s", minLength);
|
||||
checkArgument(padding >= 0, "Invalid padding: %s", padding);
|
||||
return (array.length < minLength) ? copyOf(array, minLength + padding) : array;
|
||||
}
|
||||
|
||||
// Arrays.copyOf() requires Java 6
|
||||
private static boolean[] copyOf(boolean[] original, int length) {
|
||||
boolean[] copy = new boolean[length];
|
||||
System.arraycopy(original, 0, copy, 0, Math.min(original.length, length));
|
||||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string containing the supplied {@code boolean} values separated by
|
||||
* {@code separator}. For example, {@code join("-", false, true, false)} returns
|
||||
* the string {@code "false-true-false"}.
|
||||
*
|
||||
* @param separator the text that should appear between consecutive values in
|
||||
* the resulting string (but not at the start or end)
|
||||
* @param array an array of {@code boolean} values, possibly empty
|
||||
*/
|
||||
public static String join(String separator, boolean... array) {
|
||||
checkNotNull(separator);
|
||||
if (array.length == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// For pre-sizing a builder, just get the right order of magnitude
|
||||
StringBuilder builder = new StringBuilder(array.length * 7);
|
||||
builder.append(array[0]);
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
builder.append(separator).append(array[i]);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a comparator that compares two {@code boolean} arrays
|
||||
* lexicographically. That is, it compares, using
|
||||
* {@link #compare(boolean, boolean)}), the first pair of values that follow any
|
||||
* common prefix, or when one array is a prefix of the other, treats the shorter
|
||||
* array as the lesser. For example,
|
||||
* {@code [] < [false] < [false, true] < [true]}.
|
||||
*
|
||||
* <p>
|
||||
* The returned comparator is inconsistent with {@link Object#equals(Object)}
|
||||
* (since arrays support only identity equality), but it is consistent with
|
||||
* {@link Arrays#equals(boolean[], boolean[])}.
|
||||
*
|
||||
* @see <a href="http://en.wikipedia.org/wiki/Lexicographical_order">
|
||||
* Lexicographical order article at Wikipedia</a>
|
||||
* @since 2.0
|
||||
*/
|
||||
public static Comparator<boolean[]> lexicographicalComparator() {
|
||||
return LexicographicalComparator.INSTANCE;
|
||||
}
|
||||
|
||||
private enum LexicographicalComparator implements Comparator<boolean[]> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public int compare(boolean[] left, boolean[] right) {
|
||||
int minLength = Math.min(left.length, right.length);
|
||||
for (int i = 0; i < minLength; i++) {
|
||||
int result = Booleans.compare(left[i], right[i]);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return left.length - right.length;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies a collection of {@code Boolean} instances into a new array of
|
||||
* primitive {@code boolean} values.
|
||||
*
|
||||
* <p>
|
||||
* Elements are copied from the argument collection as if by {@code
|
||||
* collection.toArray()}. Calling this method is as thread-safe as calling that
|
||||
* method.
|
||||
*
|
||||
* <p>
|
||||
* <b>Note:</b> consider representing the collection as a {@link BitSet}
|
||||
* instead.
|
||||
*
|
||||
* @param collection a collection of {@code Boolean} objects
|
||||
* @return an array containing the same values as {@code collection}, in the
|
||||
* same order, converted to primitives
|
||||
* @throws NullPointerException if {@code collection} or any of its elements is
|
||||
* null
|
||||
*/
|
||||
public static boolean[] toArray(Collection<Boolean> collection) {
|
||||
if (collection instanceof BooleanArrayAsList) {
|
||||
return ((BooleanArrayAsList) collection).toBooleanArray();
|
||||
}
|
||||
|
||||
Object[] boxedArray = collection.toArray();
|
||||
int len = boxedArray.length;
|
||||
boolean[] array = new boolean[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
// checkNotNull for GWT (do not optimize)
|
||||
array[i] = (Boolean) checkNotNull(boxedArray[i]);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a fixed-size list backed by the specified array, similar to
|
||||
* {@link Arrays#asList(Object[])}. The list supports
|
||||
* {@link List#set(int, Object)}, but any attempt to set a value to {@code null}
|
||||
* will result in a {@link NullPointerException}.
|
||||
*
|
||||
* <p>
|
||||
* The returned list maintains the values, but not the identities, of
|
||||
* {@code Boolean} objects written to or read from it. For example, whether
|
||||
* {@code list.get(0) == list.get(0)} is true for the returned list is
|
||||
* unspecified.
|
||||
*
|
||||
* @param backingArray the array to back the list
|
||||
* @return a list view of the array
|
||||
*/
|
||||
public static List<Boolean> asList(boolean... backingArray) {
|
||||
if (backingArray.length == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return new BooleanArrayAsList(backingArray);
|
||||
}
|
||||
|
||||
@GwtCompatible
|
||||
private static class BooleanArrayAsList extends AbstractList<Boolean> implements RandomAccess, Serializable {
|
||||
final boolean[] array;
|
||||
final int start;
|
||||
final int end;
|
||||
|
||||
BooleanArrayAsList(boolean[] array) {
|
||||
this(array, 0, array.length);
|
||||
}
|
||||
|
||||
BooleanArrayAsList(boolean[] array, int start, int end) {
|
||||
this.array = array;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return end - start;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean get(int index) {
|
||||
checkElementIndex(index, size());
|
||||
return array[start + index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
return (target instanceof Boolean) && Booleans.indexOf(array, (Boolean) target, start, end) != -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
if (target instanceof Boolean) {
|
||||
int i = Booleans.indexOf(array, (Boolean) target, start, end);
|
||||
if (i >= 0) {
|
||||
return i - start;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lastIndexOf(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
if (target instanceof Boolean) {
|
||||
int i = Booleans.lastIndexOf(array, (Boolean) target, start, end);
|
||||
if (i >= 0) {
|
||||
return i - start;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean set(int index, Boolean element) {
|
||||
checkElementIndex(index, size());
|
||||
boolean oldValue = array[start + index];
|
||||
// checkNotNull for GWT (do not optimize)
|
||||
array[start + index] = checkNotNull(element);
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Boolean> subList(int fromIndex, int toIndex) {
|
||||
int size = size();
|
||||
checkPositionIndexes(fromIndex, toIndex, size);
|
||||
if (fromIndex == toIndex) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return new BooleanArrayAsList(array, start + fromIndex, start + toIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object == this) {
|
||||
return true;
|
||||
}
|
||||
if (object instanceof BooleanArrayAsList) {
|
||||
BooleanArrayAsList that = (BooleanArrayAsList) object;
|
||||
int size = size();
|
||||
if (that.size() != size) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (array[start + i] != that.array[that.start + i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return super.equals(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
for (int i = start; i < end; i++) {
|
||||
result = 31 * result + Booleans.hashCode(array[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder(size() * 7);
|
||||
builder.append(array[start] ? "[true" : "[false");
|
||||
for (int i = start + 1; i < end; i++) {
|
||||
builder.append(array[i] ? ", true" : ", false");
|
||||
}
|
||||
return builder.append(']').toString();
|
||||
}
|
||||
|
||||
boolean[] toBooleanArray() {
|
||||
// Arrays.copyOfRange() is not available under GWT
|
||||
int size = size();
|
||||
boolean[] result = new boolean[size];
|
||||
System.arraycopy(array, start, result, 0, size);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of {@code values} that are {@code true}.
|
||||
*
|
||||
* @since 16.0
|
||||
*/
|
||||
@Beta
|
||||
public static int countTrue(boolean... values) {
|
||||
int count = 0;
|
||||
for (boolean value : values) {
|
||||
if (value) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
397
sources/main/java/com/google/common/primitives/Bytes.java
Normal file
397
sources/main/java/com/google/common/primitives/Bytes.java
Normal file
@ -0,0 +1,397 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.common.primitives;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkElementIndex;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkPositionIndexes;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.AbstractList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.RandomAccess;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
|
||||
/**
|
||||
* Static utility methods pertaining to {@code byte} primitives, that are not
|
||||
* already found in either {@link Byte} or {@link Arrays}, <i>and interpret
|
||||
* bytes as neither signed nor unsigned</i>. The methods which specifically
|
||||
* treat bytes as signed or unsigned are found in {@link SignedBytes} and
|
||||
* {@link UnsignedBytes}.
|
||||
*
|
||||
* <p>
|
||||
* See the Guava User Guide article on
|
||||
* <a href= "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained">
|
||||
* primitive utilities</a>.
|
||||
*
|
||||
* @author Kevin Bourrillion
|
||||
* @since 1.0
|
||||
*/
|
||||
// TODO(kevinb): how to prevent warning on UnsignedBytes when building GWT
|
||||
// javadoc?
|
||||
@GwtCompatible
|
||||
public final class Bytes {
|
||||
private Bytes() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash code for {@code value}; equal to the result of invoking
|
||||
* {@code ((Byte) value).hashCode()}.
|
||||
*
|
||||
* @param value a primitive {@code byte} value
|
||||
* @return a hash code for the value
|
||||
*/
|
||||
public static int hashCode(byte value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if {@code target} is present as an element anywhere in
|
||||
* {@code array}.
|
||||
*
|
||||
* @param array an array of {@code byte} values, possibly empty
|
||||
* @param target a primitive {@code byte} value
|
||||
* @return {@code true} if {@code array[i] == target} for some value of {@code
|
||||
* i}
|
||||
*/
|
||||
public static boolean contains(byte[] array, byte target) {
|
||||
for (byte value : array) {
|
||||
if (value == target) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the first appearance of the value {@code target} in
|
||||
* {@code array}.
|
||||
*
|
||||
* @param array an array of {@code byte} values, possibly empty
|
||||
* @param target a primitive {@code byte} value
|
||||
* @return the least index {@code i} for which {@code array[i] == target}, or
|
||||
* {@code -1} if no such index exists.
|
||||
*/
|
||||
public static int indexOf(byte[] array, byte target) {
|
||||
return indexOf(array, target, 0, array.length);
|
||||
}
|
||||
|
||||
// TODO(kevinb): consider making this public
|
||||
private static int indexOf(byte[] array, byte target, int start, int end) {
|
||||
for (int i = start; i < end; i++) {
|
||||
if (array[i] == target) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the start position of the first occurrence of the specified {@code
|
||||
* target} within {@code array}, or {@code -1} if there is no such occurrence.
|
||||
*
|
||||
* <p>
|
||||
* More formally, returns the lowest index {@code i} such that {@code
|
||||
* java.util.Arrays.copyOfRange(array, i, i + target.length)} contains exactly
|
||||
* the same elements as {@code target}.
|
||||
*
|
||||
* @param array the array to search for the sequence {@code target}
|
||||
* @param target the array to search for as a sub-sequence of {@code array}
|
||||
*/
|
||||
public static int indexOf(byte[] array, byte[] target) {
|
||||
checkNotNull(array, "array");
|
||||
checkNotNull(target, "target");
|
||||
if (target.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
outer: for (int i = 0; i < array.length - target.length + 1; i++) {
|
||||
for (int j = 0; j < target.length; j++) {
|
||||
if (array[i + j] != target[j]) {
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the last appearance of the value {@code target} in
|
||||
* {@code array}.
|
||||
*
|
||||
* @param array an array of {@code byte} values, possibly empty
|
||||
* @param target a primitive {@code byte} value
|
||||
* @return the greatest index {@code i} for which {@code array[i] == target}, or
|
||||
* {@code -1} if no such index exists.
|
||||
*/
|
||||
public static int lastIndexOf(byte[] array, byte target) {
|
||||
return lastIndexOf(array, target, 0, array.length);
|
||||
}
|
||||
|
||||
// TODO(kevinb): consider making this public
|
||||
private static int lastIndexOf(byte[] array, byte target, int start, int end) {
|
||||
for (int i = end - 1; i >= start; i--) {
|
||||
if (array[i] == target) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the values from each provided array combined into a single array. For
|
||||
* example, {@code concat(new byte[] {a, b}, new byte[] {}, new byte[] {c}}
|
||||
* returns the array {@code {a, b, c}}.
|
||||
*
|
||||
* @param arrays zero or more {@code byte} arrays
|
||||
* @return a single array containing all the values from the source arrays, in
|
||||
* order
|
||||
*/
|
||||
public static byte[] concat(byte[]... arrays) {
|
||||
int length = 0;
|
||||
for (byte[] array : arrays) {
|
||||
length += array.length;
|
||||
}
|
||||
byte[] result = new byte[length];
|
||||
int pos = 0;
|
||||
for (byte[] array : arrays) {
|
||||
System.arraycopy(array, 0, result, pos, array.length);
|
||||
pos += array.length;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing the same values as {@code array}, but guaranteed
|
||||
* to be of a specified minimum length. If {@code array} already has a length of
|
||||
* at least {@code minLength}, it is returned directly. Otherwise, a new array
|
||||
* of size {@code minLength + padding} is returned, containing the values of
|
||||
* {@code array}, and zeroes in the remaining places.
|
||||
*
|
||||
* @param array the source array
|
||||
* @param minLength the minimum length the returned array must guarantee
|
||||
* @param padding an extra amount to "grow" the array by if growth is
|
||||
* necessary
|
||||
* @throws IllegalArgumentException if {@code minLength} or {@code padding} is
|
||||
* negative
|
||||
* @return an array containing the values of {@code array}, with guaranteed
|
||||
* minimum length {@code minLength}
|
||||
*/
|
||||
public static byte[] ensureCapacity(byte[] array, int minLength, int padding) {
|
||||
checkArgument(minLength >= 0, "Invalid minLength: %s", minLength);
|
||||
checkArgument(padding >= 0, "Invalid padding: %s", padding);
|
||||
return (array.length < minLength) ? copyOf(array, minLength + padding) : array;
|
||||
}
|
||||
|
||||
// Arrays.copyOf() requires Java 6
|
||||
private static byte[] copyOf(byte[] original, int length) {
|
||||
byte[] copy = new byte[length];
|
||||
System.arraycopy(original, 0, copy, 0, Math.min(original.length, length));
|
||||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing each value of {@code collection}, converted to a
|
||||
* {@code byte} value in the manner of {@link Number#byteValue}.
|
||||
*
|
||||
* <p>
|
||||
* Elements are copied from the argument collection as if by {@code
|
||||
* collection.toArray()}. Calling this method is as thread-safe as calling that
|
||||
* method.
|
||||
*
|
||||
* @param collection a collection of {@code Number} instances
|
||||
* @return an array containing the same values as {@code collection}, in the
|
||||
* same order, converted to primitives
|
||||
* @throws NullPointerException if {@code collection} or any of its elements is
|
||||
* null
|
||||
* @since 1.0 (parameter was {@code Collection<Byte>} before 12.0)
|
||||
*/
|
||||
public static byte[] toArray(Collection<? extends Number> collection) {
|
||||
if (collection instanceof ByteArrayAsList) {
|
||||
return ((ByteArrayAsList) collection).toByteArray();
|
||||
}
|
||||
|
||||
Object[] boxedArray = collection.toArray();
|
||||
int len = boxedArray.length;
|
||||
byte[] array = new byte[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
// checkNotNull for GWT (do not optimize)
|
||||
array[i] = ((Number) checkNotNull(boxedArray[i])).byteValue();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a fixed-size list backed by the specified array, similar to
|
||||
* {@link Arrays#asList(Object[])}. The list supports
|
||||
* {@link List#set(int, Object)}, but any attempt to set a value to {@code null}
|
||||
* will result in a {@link NullPointerException}.
|
||||
*
|
||||
* <p>
|
||||
* The returned list maintains the values, but not the identities, of
|
||||
* {@code Byte} objects written to or read from it. For example, whether
|
||||
* {@code list.get(0) == list.get(0)} is true for the returned list is
|
||||
* unspecified.
|
||||
*
|
||||
* @param backingArray the array to back the list
|
||||
* @return a list view of the array
|
||||
*/
|
||||
public static List<Byte> asList(byte... backingArray) {
|
||||
if (backingArray.length == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return new ByteArrayAsList(backingArray);
|
||||
}
|
||||
|
||||
@GwtCompatible
|
||||
private static class ByteArrayAsList extends AbstractList<Byte> implements RandomAccess, Serializable {
|
||||
final byte[] array;
|
||||
final int start;
|
||||
final int end;
|
||||
|
||||
ByteArrayAsList(byte[] array) {
|
||||
this(array, 0, array.length);
|
||||
}
|
||||
|
||||
ByteArrayAsList(byte[] array, int start, int end) {
|
||||
this.array = array;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return end - start;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Byte get(int index) {
|
||||
checkElementIndex(index, size());
|
||||
return array[start + index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
return (target instanceof Byte) && Bytes.indexOf(array, (Byte) target, start, end) != -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
if (target instanceof Byte) {
|
||||
int i = Bytes.indexOf(array, (Byte) target, start, end);
|
||||
if (i >= 0) {
|
||||
return i - start;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lastIndexOf(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
if (target instanceof Byte) {
|
||||
int i = Bytes.lastIndexOf(array, (Byte) target, start, end);
|
||||
if (i >= 0) {
|
||||
return i - start;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Byte set(int index, Byte element) {
|
||||
checkElementIndex(index, size());
|
||||
byte oldValue = array[start + index];
|
||||
// checkNotNull for GWT (do not optimize)
|
||||
array[start + index] = checkNotNull(element);
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Byte> subList(int fromIndex, int toIndex) {
|
||||
int size = size();
|
||||
checkPositionIndexes(fromIndex, toIndex, size);
|
||||
if (fromIndex == toIndex) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return new ByteArrayAsList(array, start + fromIndex, start + toIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object == this) {
|
||||
return true;
|
||||
}
|
||||
if (object instanceof ByteArrayAsList) {
|
||||
ByteArrayAsList that = (ByteArrayAsList) object;
|
||||
int size = size();
|
||||
if (that.size() != size) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (array[start + i] != that.array[that.start + i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return super.equals(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
for (int i = start; i < end; i++) {
|
||||
result = 31 * result + Bytes.hashCode(array[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder(size() * 5);
|
||||
builder.append('[').append(array[start]);
|
||||
for (int i = start + 1; i < end; i++) {
|
||||
builder.append(", ").append(array[i]);
|
||||
}
|
||||
return builder.append(']').toString();
|
||||
}
|
||||
|
||||
byte[] toByteArray() {
|
||||
// Arrays.copyOfRange() is not available under GWT
|
||||
int size = size();
|
||||
byte[] result = new byte[size];
|
||||
System.arraycopy(array, start, result, 0, size);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0;
|
||||
}
|
||||
}
|
553
sources/main/java/com/google/common/primitives/Chars.java
Normal file
553
sources/main/java/com/google/common/primitives/Chars.java
Normal file
@ -0,0 +1,553 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.common.primitives;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkElementIndex;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkPositionIndexes;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.AbstractList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.RandomAccess;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
|
||||
/**
|
||||
* Static utility methods pertaining to {@code char} primitives, that are not
|
||||
* already found in either {@link Character} or {@link Arrays}.
|
||||
*
|
||||
* <p>
|
||||
* All the operations in this class treat {@code char} values strictly
|
||||
* numerically; they are neither Unicode-aware nor locale-dependent.
|
||||
*
|
||||
* <p>
|
||||
* See the Guava User Guide article on
|
||||
* <a href= "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained">
|
||||
* primitive utilities</a>.
|
||||
*
|
||||
* @author Kevin Bourrillion
|
||||
* @since 1.0
|
||||
*/
|
||||
@GwtCompatible(emulated = true)
|
||||
public final class Chars {
|
||||
private Chars() {
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of bytes required to represent a primitive {@code char} value.
|
||||
*/
|
||||
public static final int BYTES = Character.SIZE / Byte.SIZE;
|
||||
|
||||
/**
|
||||
* Returns a hash code for {@code value}; equal to the result of invoking
|
||||
* {@code ((Character) value).hashCode()}.
|
||||
*
|
||||
* @param value a primitive {@code char} value
|
||||
* @return a hash code for the value
|
||||
*/
|
||||
public static int hashCode(char value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code char} value that is equal to {@code value}, if possible.
|
||||
*
|
||||
* @param value any value in the range of the {@code char} type
|
||||
* @return the {@code char} value that equals {@code value}
|
||||
* @throws IllegalArgumentException if {@code value} is greater than
|
||||
* {@link Character#MAX_VALUE} or less than
|
||||
* {@link Character#MIN_VALUE}
|
||||
*/
|
||||
public static char checkedCast(long value) {
|
||||
char result = (char) value;
|
||||
if (result != value) {
|
||||
// don't use checkArgument here, to avoid boxing
|
||||
throw new IllegalArgumentException("Out of range: " + value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code char} nearest in value to {@code value}.
|
||||
*
|
||||
* @param value any {@code long} value
|
||||
* @return the same value cast to {@code char} if it is in the range of the
|
||||
* {@code char} type, {@link Character#MAX_VALUE} if it is too large, or
|
||||
* {@link Character#MIN_VALUE} if it is too small
|
||||
*/
|
||||
public static char saturatedCast(long value) {
|
||||
if (value > Character.MAX_VALUE) {
|
||||
return Character.MAX_VALUE;
|
||||
}
|
||||
if (value < Character.MIN_VALUE) {
|
||||
return Character.MIN_VALUE;
|
||||
}
|
||||
return (char) value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the two specified {@code char} values. The sign of the value
|
||||
* returned is the same as that of {@code ((Character) a).compareTo(b)}.
|
||||
*
|
||||
* <p>
|
||||
* <b>Note:</b> projects using JDK 7 or later should use the equivalent
|
||||
* {@link Character#compare} method instead.
|
||||
*
|
||||
* @param a the first {@code char} to compare
|
||||
* @param b the second {@code char} to compare
|
||||
* @return a negative value if {@code a} is less than {@code b}; a positive
|
||||
* value if {@code a} is greater than {@code b}; or zero if they are
|
||||
* equal
|
||||
*/
|
||||
public static int compare(char a, char b) {
|
||||
return a - b; // safe due to restricted range
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if {@code target} is present as an element anywhere in
|
||||
* {@code array}.
|
||||
*
|
||||
* @param array an array of {@code char} values, possibly empty
|
||||
* @param target a primitive {@code char} value
|
||||
* @return {@code true} if {@code array[i] == target} for some value of {@code
|
||||
* i}
|
||||
*/
|
||||
public static boolean contains(char[] array, char target) {
|
||||
for (char value : array) {
|
||||
if (value == target) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the first appearance of the value {@code target} in
|
||||
* {@code array}.
|
||||
*
|
||||
* @param array an array of {@code char} values, possibly empty
|
||||
* @param target a primitive {@code char} value
|
||||
* @return the least index {@code i} for which {@code array[i] == target}, or
|
||||
* {@code -1} if no such index exists.
|
||||
*/
|
||||
public static int indexOf(char[] array, char target) {
|
||||
return indexOf(array, target, 0, array.length);
|
||||
}
|
||||
|
||||
// TODO(kevinb): consider making this public
|
||||
private static int indexOf(char[] array, char target, int start, int end) {
|
||||
for (int i = start; i < end; i++) {
|
||||
if (array[i] == target) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the start position of the first occurrence of the specified {@code
|
||||
* target} within {@code array}, or {@code -1} if there is no such occurrence.
|
||||
*
|
||||
* <p>
|
||||
* More formally, returns the lowest index {@code i} such that {@code
|
||||
* java.util.Arrays.copyOfRange(array, i, i + target.length)} contains exactly
|
||||
* the same elements as {@code target}.
|
||||
*
|
||||
* @param array the array to search for the sequence {@code target}
|
||||
* @param target the array to search for as a sub-sequence of {@code array}
|
||||
*/
|
||||
public static int indexOf(char[] array, char[] target) {
|
||||
checkNotNull(array, "array");
|
||||
checkNotNull(target, "target");
|
||||
if (target.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
outer: for (int i = 0; i < array.length - target.length + 1; i++) {
|
||||
for (int j = 0; j < target.length; j++) {
|
||||
if (array[i + j] != target[j]) {
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the last appearance of the value {@code target} in
|
||||
* {@code array}.
|
||||
*
|
||||
* @param array an array of {@code char} values, possibly empty
|
||||
* @param target a primitive {@code char} value
|
||||
* @return the greatest index {@code i} for which {@code array[i] == target}, or
|
||||
* {@code -1} if no such index exists.
|
||||
*/
|
||||
public static int lastIndexOf(char[] array, char target) {
|
||||
return lastIndexOf(array, target, 0, array.length);
|
||||
}
|
||||
|
||||
// TODO(kevinb): consider making this public
|
||||
private static int lastIndexOf(char[] array, char target, int start, int end) {
|
||||
for (int i = end - 1; i >= start; i--) {
|
||||
if (array[i] == target) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the least value present in {@code array}.
|
||||
*
|
||||
* @param array a <i>nonempty</i> array of {@code char} values
|
||||
* @return the value present in {@code array} that is less than or equal to
|
||||
* every other value in the array
|
||||
* @throws IllegalArgumentException if {@code array} is empty
|
||||
*/
|
||||
public static char min(char... array) {
|
||||
checkArgument(array.length > 0);
|
||||
char min = array[0];
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
if (array[i] < min) {
|
||||
min = array[i];
|
||||
}
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the greatest value present in {@code array}.
|
||||
*
|
||||
* @param array a <i>nonempty</i> array of {@code char} values
|
||||
* @return the value present in {@code array} that is greater than or equal to
|
||||
* every other value in the array
|
||||
* @throws IllegalArgumentException if {@code array} is empty
|
||||
*/
|
||||
public static char max(char... array) {
|
||||
checkArgument(array.length > 0);
|
||||
char max = array[0];
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
if (array[i] > max) {
|
||||
max = array[i];
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the values from each provided array combined into a single array. For
|
||||
* example, {@code concat(new char[] {a, b}, new char[] {}, new char[] {c}}
|
||||
* returns the array {@code {a, b, c}}.
|
||||
*
|
||||
* @param arrays zero or more {@code char} arrays
|
||||
* @return a single array containing all the values from the source arrays, in
|
||||
* order
|
||||
*/
|
||||
public static char[] concat(char[]... arrays) {
|
||||
int length = 0;
|
||||
for (char[] array : arrays) {
|
||||
length += array.length;
|
||||
}
|
||||
char[] result = new char[length];
|
||||
int pos = 0;
|
||||
for (char[] array : arrays) {
|
||||
System.arraycopy(array, 0, result, pos, array.length);
|
||||
pos += array.length;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing the same values as {@code array}, but guaranteed
|
||||
* to be of a specified minimum length. If {@code array} already has a length of
|
||||
* at least {@code minLength}, it is returned directly. Otherwise, a new array
|
||||
* of size {@code minLength + padding} is returned, containing the values of
|
||||
* {@code array}, and zeroes in the remaining places.
|
||||
*
|
||||
* @param array the source array
|
||||
* @param minLength the minimum length the returned array must guarantee
|
||||
* @param padding an extra amount to "grow" the array by if growth is
|
||||
* necessary
|
||||
* @throws IllegalArgumentException if {@code minLength} or {@code padding} is
|
||||
* negative
|
||||
* @return an array containing the values of {@code array}, with guaranteed
|
||||
* minimum length {@code minLength}
|
||||
*/
|
||||
public static char[] ensureCapacity(char[] array, int minLength, int padding) {
|
||||
checkArgument(minLength >= 0, "Invalid minLength: %s", minLength);
|
||||
checkArgument(padding >= 0, "Invalid padding: %s", padding);
|
||||
return (array.length < minLength) ? copyOf(array, minLength + padding) : array;
|
||||
}
|
||||
|
||||
// Arrays.copyOf() requires Java 6
|
||||
private static char[] copyOf(char[] original, int length) {
|
||||
char[] copy = new char[length];
|
||||
System.arraycopy(original, 0, copy, 0, Math.min(original.length, length));
|
||||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string containing the supplied {@code char} values separated by
|
||||
* {@code separator}. For example, {@code join("-", '1', '2', '3')} returns the
|
||||
* string {@code "1-2-3"}.
|
||||
*
|
||||
* @param separator the text that should appear between consecutive values in
|
||||
* the resulting string (but not at the start or end)
|
||||
* @param array an array of {@code char} values, possibly empty
|
||||
*/
|
||||
public static String join(String separator, char... array) {
|
||||
checkNotNull(separator);
|
||||
int len = array.length;
|
||||
if (len == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
StringBuilder builder = new StringBuilder(len + separator.length() * (len - 1));
|
||||
builder.append(array[0]);
|
||||
for (int i = 1; i < len; i++) {
|
||||
builder.append(separator).append(array[i]);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a comparator that compares two {@code char} arrays lexicographically.
|
||||
* That is, it compares, using {@link #compare(char, char)}), the first pair of
|
||||
* values that follow any common prefix, or when one array is a prefix of the
|
||||
* other, treats the shorter array as the lesser. For example,
|
||||
* {@code [] < ['a'] < ['a', 'b'] < ['b']}.
|
||||
*
|
||||
* <p>
|
||||
* The returned comparator is inconsistent with {@link Object#equals(Object)}
|
||||
* (since arrays support only identity equality), but it is consistent with
|
||||
* {@link Arrays#equals(char[], char[])}.
|
||||
*
|
||||
* @see <a href="http://en.wikipedia.org/wiki/Lexicographical_order">
|
||||
* Lexicographical order article at Wikipedia</a>
|
||||
* @since 2.0
|
||||
*/
|
||||
public static Comparator<char[]> lexicographicalComparator() {
|
||||
return LexicographicalComparator.INSTANCE;
|
||||
}
|
||||
|
||||
private enum LexicographicalComparator implements Comparator<char[]> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public int compare(char[] left, char[] right) {
|
||||
int minLength = Math.min(left.length, right.length);
|
||||
for (int i = 0; i < minLength; i++) {
|
||||
int result = Chars.compare(left[i], right[i]);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return left.length - right.length;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies a collection of {@code Character} instances into a new array of
|
||||
* primitive {@code char} values.
|
||||
*
|
||||
* <p>
|
||||
* Elements are copied from the argument collection as if by {@code
|
||||
* collection.toArray()}. Calling this method is as thread-safe as calling that
|
||||
* method.
|
||||
*
|
||||
* @param collection a collection of {@code Character} objects
|
||||
* @return an array containing the same values as {@code collection}, in the
|
||||
* same order, converted to primitives
|
||||
* @throws NullPointerException if {@code collection} or any of its elements is
|
||||
* null
|
||||
*/
|
||||
public static char[] toArray(Collection<Character> collection) {
|
||||
if (collection instanceof CharArrayAsList) {
|
||||
return ((CharArrayAsList) collection).toCharArray();
|
||||
}
|
||||
|
||||
Object[] boxedArray = collection.toArray();
|
||||
int len = boxedArray.length;
|
||||
char[] array = new char[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
// checkNotNull for GWT (do not optimize)
|
||||
array[i] = (Character) checkNotNull(boxedArray[i]);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a fixed-size list backed by the specified array, similar to
|
||||
* {@link Arrays#asList(Object[])}. The list supports
|
||||
* {@link List#set(int, Object)}, but any attempt to set a value to {@code null}
|
||||
* will result in a {@link NullPointerException}.
|
||||
*
|
||||
* <p>
|
||||
* The returned list maintains the values, but not the identities, of
|
||||
* {@code Character} objects written to or read from it. For example, whether
|
||||
* {@code list.get(0) == list.get(0)} is true for the returned list is
|
||||
* unspecified.
|
||||
*
|
||||
* @param backingArray the array to back the list
|
||||
* @return a list view of the array
|
||||
*/
|
||||
public static List<Character> asList(char... backingArray) {
|
||||
if (backingArray.length == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return new CharArrayAsList(backingArray);
|
||||
}
|
||||
|
||||
@GwtCompatible
|
||||
private static class CharArrayAsList extends AbstractList<Character> implements RandomAccess, Serializable {
|
||||
final char[] array;
|
||||
final int start;
|
||||
final int end;
|
||||
|
||||
CharArrayAsList(char[] array) {
|
||||
this(array, 0, array.length);
|
||||
}
|
||||
|
||||
CharArrayAsList(char[] array, int start, int end) {
|
||||
this.array = array;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return end - start;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Character get(int index) {
|
||||
checkElementIndex(index, size());
|
||||
return array[start + index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
return (target instanceof Character) && Chars.indexOf(array, (Character) target, start, end) != -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
if (target instanceof Character) {
|
||||
int i = Chars.indexOf(array, (Character) target, start, end);
|
||||
if (i >= 0) {
|
||||
return i - start;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lastIndexOf(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
if (target instanceof Character) {
|
||||
int i = Chars.lastIndexOf(array, (Character) target, start, end);
|
||||
if (i >= 0) {
|
||||
return i - start;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Character set(int index, Character element) {
|
||||
checkElementIndex(index, size());
|
||||
char oldValue = array[start + index];
|
||||
// checkNotNull for GWT (do not optimize)
|
||||
array[start + index] = checkNotNull(element);
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Character> subList(int fromIndex, int toIndex) {
|
||||
int size = size();
|
||||
checkPositionIndexes(fromIndex, toIndex, size);
|
||||
if (fromIndex == toIndex) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return new CharArrayAsList(array, start + fromIndex, start + toIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object == this) {
|
||||
return true;
|
||||
}
|
||||
if (object instanceof CharArrayAsList) {
|
||||
CharArrayAsList that = (CharArrayAsList) object;
|
||||
int size = size();
|
||||
if (that.size() != size) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (array[start + i] != that.array[that.start + i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return super.equals(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
for (int i = start; i < end; i++) {
|
||||
result = 31 * result + Chars.hashCode(array[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder(size() * 3);
|
||||
builder.append('[').append(array[start]);
|
||||
for (int i = start + 1; i < end; i++) {
|
||||
builder.append(", ").append(array[i]);
|
||||
}
|
||||
return builder.append(']').toString();
|
||||
}
|
||||
|
||||
char[] toCharArray() {
|
||||
// Arrays.copyOfRange() is not available under GWT
|
||||
int size = size();
|
||||
char[] result = new char[size];
|
||||
System.arraycopy(array, start, result, 0, size);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0;
|
||||
}
|
||||
}
|
649
sources/main/java/com/google/common/primitives/Doubles.java
Normal file
649
sources/main/java/com/google/common/primitives/Doubles.java
Normal file
@ -0,0 +1,649 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.common.primitives;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkElementIndex;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkPositionIndexes;
|
||||
import static java.lang.Double.NEGATIVE_INFINITY;
|
||||
import static java.lang.Double.POSITIVE_INFINITY;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.AbstractList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.RandomAccess;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
import com.google.common.annotations.GwtIncompatible;
|
||||
import com.google.common.base.Converter;
|
||||
|
||||
/**
|
||||
* Static utility methods pertaining to {@code double} primitives, that are not
|
||||
* already found in either {@link Double} or {@link Arrays}.
|
||||
*
|
||||
* <p>
|
||||
* See the Guava User Guide article on
|
||||
* <a href= "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained">
|
||||
* primitive utilities</a>.
|
||||
*
|
||||
* @author Kevin Bourrillion
|
||||
* @since 1.0
|
||||
*/
|
||||
@GwtCompatible(emulated = true)
|
||||
public final class Doubles {
|
||||
private Doubles() {
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of bytes required to represent a primitive {@code double} value.
|
||||
*
|
||||
* @since 10.0
|
||||
*/
|
||||
public static final int BYTES = Double.SIZE / Byte.SIZE;
|
||||
|
||||
/**
|
||||
* Returns a hash code for {@code value}; equal to the result of invoking
|
||||
* {@code ((Double) value).hashCode()}.
|
||||
*
|
||||
* @param value a primitive {@code double} value
|
||||
* @return a hash code for the value
|
||||
*/
|
||||
public static int hashCode(double value) {
|
||||
return ((Double) value).hashCode();
|
||||
// TODO(kevinb): do it this way when we can (GWT problem):
|
||||
// long bits = Double.doubleToLongBits(value);
|
||||
// return (int) (bits ^ (bits >>> 32));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the two specified {@code double} values. The sign of the value
|
||||
* returned is the same as that of <code>((Double) a).{@linkplain
|
||||
* Double#compareTo compareTo}(b)</code>. As with that method, {@code NaN} is
|
||||
* treated as greater than all other values, and {@code 0.0 > -0.0}.
|
||||
*
|
||||
* <p>
|
||||
* <b>Note:</b> this method simply delegates to the JDK method
|
||||
* {@link Double#compare}. It is provided for consistency with the other
|
||||
* primitive types, whose compare methods were not added to the JDK until JDK 7.
|
||||
*
|
||||
* @param a the first {@code double} to compare
|
||||
* @param b the second {@code double} to compare
|
||||
* @return a negative value if {@code a} is less than {@code b}; a positive
|
||||
* value if {@code a} is greater than {@code b}; or zero if they are
|
||||
* equal
|
||||
*/
|
||||
public static int compare(double a, double b) {
|
||||
return Double.compare(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if {@code value} represents a real number. This is
|
||||
* equivalent to, but not necessarily implemented as,
|
||||
* {@code !(Double.isInfinite(value) || Double.isNaN(value))}.
|
||||
*
|
||||
* @since 10.0
|
||||
*/
|
||||
public static boolean isFinite(double value) {
|
||||
return NEGATIVE_INFINITY < value & value < POSITIVE_INFINITY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if {@code target} is present as an element anywhere in
|
||||
* {@code array}. Note that this always returns {@code false} when {@code
|
||||
* target} is {@code NaN}.
|
||||
*
|
||||
* @param array an array of {@code double} values, possibly empty
|
||||
* @param target a primitive {@code double} value
|
||||
* @return {@code true} if {@code array[i] == target} for some value of {@code
|
||||
* i}
|
||||
*/
|
||||
public static boolean contains(double[] array, double target) {
|
||||
for (double value : array) {
|
||||
if (value == target) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the first appearance of the value {@code target} in
|
||||
* {@code array}. Note that this always returns {@code -1} when {@code target}
|
||||
* is {@code NaN}.
|
||||
*
|
||||
* @param array an array of {@code double} values, possibly empty
|
||||
* @param target a primitive {@code double} value
|
||||
* @return the least index {@code i} for which {@code array[i] == target}, or
|
||||
* {@code -1} if no such index exists.
|
||||
*/
|
||||
public static int indexOf(double[] array, double target) {
|
||||
return indexOf(array, target, 0, array.length);
|
||||
}
|
||||
|
||||
// TODO(kevinb): consider making this public
|
||||
private static int indexOf(double[] array, double target, int start, int end) {
|
||||
for (int i = start; i < end; i++) {
|
||||
if (array[i] == target) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the start position of the first occurrence of the specified {@code
|
||||
* target} within {@code array}, or {@code -1} if there is no such occurrence.
|
||||
*
|
||||
* <p>
|
||||
* More formally, returns the lowest index {@code i} such that {@code
|
||||
* java.util.Arrays.copyOfRange(array, i, i + target.length)} contains exactly
|
||||
* the same elements as {@code target}.
|
||||
*
|
||||
* <p>
|
||||
* Note that this always returns {@code -1} when {@code target} contains
|
||||
* {@code NaN}.
|
||||
*
|
||||
* @param array the array to search for the sequence {@code target}
|
||||
* @param target the array to search for as a sub-sequence of {@code array}
|
||||
*/
|
||||
public static int indexOf(double[] array, double[] target) {
|
||||
checkNotNull(array, "array");
|
||||
checkNotNull(target, "target");
|
||||
if (target.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
outer: for (int i = 0; i < array.length - target.length + 1; i++) {
|
||||
for (int j = 0; j < target.length; j++) {
|
||||
if (array[i + j] != target[j]) {
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the last appearance of the value {@code target} in
|
||||
* {@code array}. Note that this always returns {@code -1} when {@code target}
|
||||
* is {@code NaN}.
|
||||
*
|
||||
* @param array an array of {@code double} values, possibly empty
|
||||
* @param target a primitive {@code double} value
|
||||
* @return the greatest index {@code i} for which {@code array[i] == target}, or
|
||||
* {@code -1} if no such index exists.
|
||||
*/
|
||||
public static int lastIndexOf(double[] array, double target) {
|
||||
return lastIndexOf(array, target, 0, array.length);
|
||||
}
|
||||
|
||||
// TODO(kevinb): consider making this public
|
||||
private static int lastIndexOf(double[] array, double target, int start, int end) {
|
||||
for (int i = end - 1; i >= start; i--) {
|
||||
if (array[i] == target) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the least value present in {@code array}, using the same rules of
|
||||
* comparison as {@link Math#min(double, double)}.
|
||||
*
|
||||
* @param array a <i>nonempty</i> array of {@code double} values
|
||||
* @return the value present in {@code array} that is less than or equal to
|
||||
* every other value in the array
|
||||
* @throws IllegalArgumentException if {@code array} is empty
|
||||
*/
|
||||
public static double min(double... array) {
|
||||
checkArgument(array.length > 0);
|
||||
double min = array[0];
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
min = Math.min(min, array[i]);
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the greatest value present in {@code array}, using the same rules of
|
||||
* comparison as {@link Math#max(double, double)}.
|
||||
*
|
||||
* @param array a <i>nonempty</i> array of {@code double} values
|
||||
* @return the value present in {@code array} that is greater than or equal to
|
||||
* every other value in the array
|
||||
* @throws IllegalArgumentException if {@code array} is empty
|
||||
*/
|
||||
public static double max(double... array) {
|
||||
checkArgument(array.length > 0);
|
||||
double max = array[0];
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
max = Math.max(max, array[i]);
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the values from each provided array combined into a single array. For
|
||||
* example, {@code concat(new double[] {a, b}, new double[] {}, new double[]
|
||||
* {c}} returns the array {@code {a, b, c}}.
|
||||
*
|
||||
* @param arrays zero or more {@code double} arrays
|
||||
* @return a single array containing all the values from the source arrays, in
|
||||
* order
|
||||
*/
|
||||
public static double[] concat(double[]... arrays) {
|
||||
int length = 0;
|
||||
for (double[] array : arrays) {
|
||||
length += array.length;
|
||||
}
|
||||
double[] result = new double[length];
|
||||
int pos = 0;
|
||||
for (double[] array : arrays) {
|
||||
System.arraycopy(array, 0, result, pos, array.length);
|
||||
pos += array.length;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static final class DoubleConverter extends Converter<String, Double> implements Serializable {
|
||||
static final DoubleConverter INSTANCE = new DoubleConverter();
|
||||
|
||||
@Override
|
||||
protected Double doForward(String value) {
|
||||
return Double.valueOf(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doBackward(Double value) {
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Doubles.stringConverter()";
|
||||
}
|
||||
|
||||
private Object readResolve() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a serializable converter object that converts between strings and
|
||||
* doubles using {@link Double#valueOf} and {@link Double#toString()}.
|
||||
*
|
||||
* @since 16.0
|
||||
*/
|
||||
@Beta
|
||||
public static Converter<String, Double> stringConverter() {
|
||||
return DoubleConverter.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing the same values as {@code array}, but guaranteed
|
||||
* to be of a specified minimum length. If {@code array} already has a length of
|
||||
* at least {@code minLength}, it is returned directly. Otherwise, a new array
|
||||
* of size {@code minLength + padding} is returned, containing the values of
|
||||
* {@code array}, and zeroes in the remaining places.
|
||||
*
|
||||
* @param array the source array
|
||||
* @param minLength the minimum length the returned array must guarantee
|
||||
* @param padding an extra amount to "grow" the array by if growth is
|
||||
* necessary
|
||||
* @throws IllegalArgumentException if {@code minLength} or {@code padding} is
|
||||
* negative
|
||||
* @return an array containing the values of {@code array}, with guaranteed
|
||||
* minimum length {@code minLength}
|
||||
*/
|
||||
public static double[] ensureCapacity(double[] array, int minLength, int padding) {
|
||||
checkArgument(minLength >= 0, "Invalid minLength: %s", minLength);
|
||||
checkArgument(padding >= 0, "Invalid padding: %s", padding);
|
||||
return (array.length < minLength) ? copyOf(array, minLength + padding) : array;
|
||||
}
|
||||
|
||||
// Arrays.copyOf() requires Java 6
|
||||
private static double[] copyOf(double[] original, int length) {
|
||||
double[] copy = new double[length];
|
||||
System.arraycopy(original, 0, copy, 0, Math.min(original.length, length));
|
||||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string containing the supplied {@code double} values, converted to
|
||||
* strings as specified by {@link Double#toString(double)}, and separated by
|
||||
* {@code separator}. For example, {@code join("-", 1.0, 2.0, 3.0)} returns the
|
||||
* string {@code "1.0-2.0-3.0"}.
|
||||
*
|
||||
* <p>
|
||||
* Note that {@link Double#toString(double)} formats {@code double} differently
|
||||
* in GWT sometimes. In the previous example, it returns the string
|
||||
* {@code "1-2-3"}.
|
||||
*
|
||||
* @param separator the text that should appear between consecutive values in
|
||||
* the resulting string (but not at the start or end)
|
||||
* @param array an array of {@code double} values, possibly empty
|
||||
*/
|
||||
public static String join(String separator, double... array) {
|
||||
checkNotNull(separator);
|
||||
if (array.length == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// For pre-sizing a builder, just get the right order of magnitude
|
||||
StringBuilder builder = new StringBuilder(array.length * 12);
|
||||
builder.append(array[0]);
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
builder.append(separator).append(array[i]);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a comparator that compares two {@code double} arrays
|
||||
* lexicographically. That is, it compares, using
|
||||
* {@link #compare(double, double)}), the first pair of values that follow any
|
||||
* common prefix, or when one array is a prefix of the other, treats the shorter
|
||||
* array as the lesser. For example, {@code [] < [1.0] < [1.0, 2.0] < [2.0]}.
|
||||
*
|
||||
* <p>
|
||||
* The returned comparator is inconsistent with {@link Object#equals(Object)}
|
||||
* (since arrays support only identity equality), but it is consistent with
|
||||
* {@link Arrays#equals(double[], double[])}.
|
||||
*
|
||||
* @see <a href="http://en.wikipedia.org/wiki/Lexicographical_order">
|
||||
* Lexicographical order article at Wikipedia</a>
|
||||
* @since 2.0
|
||||
*/
|
||||
public static Comparator<double[]> lexicographicalComparator() {
|
||||
return LexicographicalComparator.INSTANCE;
|
||||
}
|
||||
|
||||
private enum LexicographicalComparator implements Comparator<double[]> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public int compare(double[] left, double[] right) {
|
||||
int minLength = Math.min(left.length, right.length);
|
||||
for (int i = 0; i < minLength; i++) {
|
||||
int result = Doubles.compare(left[i], right[i]);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return left.length - right.length;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing each value of {@code collection}, converted to a
|
||||
* {@code double} value in the manner of {@link Number#doubleValue}.
|
||||
*
|
||||
* <p>
|
||||
* Elements are copied from the argument collection as if by {@code
|
||||
* collection.toArray()}. Calling this method is as thread-safe as calling that
|
||||
* method.
|
||||
*
|
||||
* @param collection a collection of {@code Number} instances
|
||||
* @return an array containing the same values as {@code collection}, in the
|
||||
* same order, converted to primitives
|
||||
* @throws NullPointerException if {@code collection} or any of its elements is
|
||||
* null
|
||||
* @since 1.0 (parameter was {@code Collection<Double>} before 12.0)
|
||||
*/
|
||||
public static double[] toArray(Collection<? extends Number> collection) {
|
||||
if (collection instanceof DoubleArrayAsList) {
|
||||
return ((DoubleArrayAsList) collection).toDoubleArray();
|
||||
}
|
||||
|
||||
Object[] boxedArray = collection.toArray();
|
||||
int len = boxedArray.length;
|
||||
double[] array = new double[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
// checkNotNull for GWT (do not optimize)
|
||||
array[i] = ((Number) checkNotNull(boxedArray[i])).doubleValue();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a fixed-size list backed by the specified array, similar to
|
||||
* {@link Arrays#asList(Object[])}. The list supports
|
||||
* {@link List#set(int, Object)}, but any attempt to set a value to {@code null}
|
||||
* will result in a {@link NullPointerException}.
|
||||
*
|
||||
* <p>
|
||||
* The returned list maintains the values, but not the identities, of
|
||||
* {@code Double} objects written to or read from it. For example, whether
|
||||
* {@code list.get(0) == list.get(0)} is true for the returned list is
|
||||
* unspecified.
|
||||
*
|
||||
* <p>
|
||||
* The returned list may have unexpected behavior if it contains {@code
|
||||
* NaN}, or if {@code NaN} is used as a parameter to any of its methods.
|
||||
*
|
||||
* @param backingArray the array to back the list
|
||||
* @return a list view of the array
|
||||
*/
|
||||
public static List<Double> asList(double... backingArray) {
|
||||
if (backingArray.length == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return new DoubleArrayAsList(backingArray);
|
||||
}
|
||||
|
||||
@GwtCompatible
|
||||
private static class DoubleArrayAsList extends AbstractList<Double> implements RandomAccess, Serializable {
|
||||
final double[] array;
|
||||
final int start;
|
||||
final int end;
|
||||
|
||||
DoubleArrayAsList(double[] array) {
|
||||
this(array, 0, array.length);
|
||||
}
|
||||
|
||||
DoubleArrayAsList(double[] array, int start, int end) {
|
||||
this.array = array;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return end - start;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double get(int index) {
|
||||
checkElementIndex(index, size());
|
||||
return array[start + index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
return (target instanceof Double) && Doubles.indexOf(array, (Double) target, start, end) != -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
if (target instanceof Double) {
|
||||
int i = Doubles.indexOf(array, (Double) target, start, end);
|
||||
if (i >= 0) {
|
||||
return i - start;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lastIndexOf(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
if (target instanceof Double) {
|
||||
int i = Doubles.lastIndexOf(array, (Double) target, start, end);
|
||||
if (i >= 0) {
|
||||
return i - start;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double set(int index, Double element) {
|
||||
checkElementIndex(index, size());
|
||||
double oldValue = array[start + index];
|
||||
// checkNotNull for GWT (do not optimize)
|
||||
array[start + index] = checkNotNull(element);
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Double> subList(int fromIndex, int toIndex) {
|
||||
int size = size();
|
||||
checkPositionIndexes(fromIndex, toIndex, size);
|
||||
if (fromIndex == toIndex) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return new DoubleArrayAsList(array, start + fromIndex, start + toIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object == this) {
|
||||
return true;
|
||||
}
|
||||
if (object instanceof DoubleArrayAsList) {
|
||||
DoubleArrayAsList that = (DoubleArrayAsList) object;
|
||||
int size = size();
|
||||
if (that.size() != size) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (array[start + i] != that.array[that.start + i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return super.equals(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
for (int i = start; i < end; i++) {
|
||||
result = 31 * result + Doubles.hashCode(array[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder(size() * 12);
|
||||
builder.append('[').append(array[start]);
|
||||
for (int i = start + 1; i < end; i++) {
|
||||
builder.append(", ").append(array[i]);
|
||||
}
|
||||
return builder.append(']').toString();
|
||||
}
|
||||
|
||||
double[] toDoubleArray() {
|
||||
// Arrays.copyOfRange() is not available under GWT
|
||||
int size = size();
|
||||
double[] result = new double[size];
|
||||
System.arraycopy(array, start, result, 0, size);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is adapted from the regex suggested by {@link Double#valueOf(String)}
|
||||
* for prevalidating inputs. All valid inputs must pass this regex, but it's
|
||||
* semantically fine if not all inputs that pass this regex are valid -- only a
|
||||
* performance hit is incurred, not a semantics bug.
|
||||
*/
|
||||
@GwtIncompatible("regular expressions")
|
||||
static final Pattern FLOATING_POINT_PATTERN = fpPattern();
|
||||
|
||||
@GwtIncompatible("regular expressions")
|
||||
private static Pattern fpPattern() {
|
||||
String decimal = "(?:\\d++(?:\\.\\d*+)?|\\.\\d++)";
|
||||
String completeDec = decimal + "(?:[eE][+-]?\\d++)?[fFdD]?";
|
||||
String hex = "(?:\\p{XDigit}++(?:\\.\\p{XDigit}*+)?|\\.\\p{XDigit}++)";
|
||||
String completeHex = "0[xX]" + hex + "[pP][+-]?\\d++[fFdD]?";
|
||||
String fpPattern = "[+-]?(?:NaN|Infinity|" + completeDec + "|" + completeHex + ")";
|
||||
return Pattern.compile(fpPattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the specified string as a double-precision floating point value. The
|
||||
* ASCII character {@code '-'} (<code>'\u002D'</code>) is recognized as the
|
||||
* minus sign.
|
||||
*
|
||||
* <p>
|
||||
* Unlike {@link Double#parseDouble(String)}, this method returns {@code null}
|
||||
* instead of throwing an exception if parsing fails. Valid inputs are exactly
|
||||
* those accepted by {@link Double#valueOf(String)}, except that leading and
|
||||
* trailing whitespace is not permitted.
|
||||
*
|
||||
* <p>
|
||||
* This implementation is likely to be faster than {@code
|
||||
* Double.parseDouble} if many failures are expected.
|
||||
*
|
||||
* @param string the string representation of a {@code double} value
|
||||
* @return the floating point value represented by {@code string}, or
|
||||
* {@code null} if {@code string} has a length of zero or cannot be
|
||||
* parsed as a {@code double} value
|
||||
* @since 14.0
|
||||
*/
|
||||
@GwtIncompatible("regular expressions")
|
||||
@Nullable
|
||||
@Beta
|
||||
public static Double tryParse(String string) {
|
||||
if (FLOATING_POINT_PATTERN.matcher(string).matches()) {
|
||||
// TODO(user): could be potentially optimized, but only with
|
||||
// extensive testing
|
||||
try {
|
||||
return Double.parseDouble(string);
|
||||
} catch (NumberFormatException e) {
|
||||
// Double.parseDouble has changed specs several times, so fall through
|
||||
// gracefully
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
626
sources/main/java/com/google/common/primitives/Floats.java
Normal file
626
sources/main/java/com/google/common/primitives/Floats.java
Normal file
@ -0,0 +1,626 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.common.primitives;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkElementIndex;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkPositionIndexes;
|
||||
import static java.lang.Float.NEGATIVE_INFINITY;
|
||||
import static java.lang.Float.POSITIVE_INFINITY;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.AbstractList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.RandomAccess;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
import com.google.common.annotations.GwtIncompatible;
|
||||
import com.google.common.base.Converter;
|
||||
|
||||
/**
|
||||
* Static utility methods pertaining to {@code float} primitives, that are not
|
||||
* already found in either {@link Float} or {@link Arrays}.
|
||||
*
|
||||
* <p>
|
||||
* See the Guava User Guide article on
|
||||
* <a href= "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained">
|
||||
* primitive utilities</a>.
|
||||
*
|
||||
* @author Kevin Bourrillion
|
||||
* @since 1.0
|
||||
*/
|
||||
@GwtCompatible(emulated = true)
|
||||
public final class Floats {
|
||||
private Floats() {
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of bytes required to represent a primitive {@code float} value.
|
||||
*
|
||||
* @since 10.0
|
||||
*/
|
||||
public static final int BYTES = Float.SIZE / Byte.SIZE;
|
||||
|
||||
/**
|
||||
* Returns a hash code for {@code value}; equal to the result of invoking
|
||||
* {@code ((Float) value).hashCode()}.
|
||||
*
|
||||
* @param value a primitive {@code float} value
|
||||
* @return a hash code for the value
|
||||
*/
|
||||
public static int hashCode(float value) {
|
||||
// TODO(kevinb): is there a better way, that's still gwt-safe?
|
||||
return ((Float) value).hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the two specified {@code float} values using
|
||||
* {@link Float#compare(float, float)}. You may prefer to invoke that method
|
||||
* directly; this method exists only for consistency with the other utilities in
|
||||
* this package.
|
||||
*
|
||||
* <p>
|
||||
* <b>Note:</b> this method simply delegates to the JDK method
|
||||
* {@link Float#compare}. It is provided for consistency with the other
|
||||
* primitive types, whose compare methods were not added to the JDK until JDK 7.
|
||||
*
|
||||
* @param a the first {@code float} to compare
|
||||
* @param b the second {@code float} to compare
|
||||
* @return the result of invoking {@link Float#compare(float, float)}
|
||||
*/
|
||||
public static int compare(float a, float b) {
|
||||
return Float.compare(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if {@code value} represents a real number. This is
|
||||
* equivalent to, but not necessarily implemented as,
|
||||
* {@code !(Float.isInfinite(value) || Float.isNaN(value))}.
|
||||
*
|
||||
* @since 10.0
|
||||
*/
|
||||
public static boolean isFinite(float value) {
|
||||
return NEGATIVE_INFINITY < value & value < POSITIVE_INFINITY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if {@code target} is present as an element anywhere in
|
||||
* {@code array}. Note that this always returns {@code false} when {@code
|
||||
* target} is {@code NaN}.
|
||||
*
|
||||
* @param array an array of {@code float} values, possibly empty
|
||||
* @param target a primitive {@code float} value
|
||||
* @return {@code true} if {@code array[i] == target} for some value of {@code
|
||||
* i}
|
||||
*/
|
||||
public static boolean contains(float[] array, float target) {
|
||||
for (float value : array) {
|
||||
if (value == target) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the first appearance of the value {@code target} in
|
||||
* {@code array}. Note that this always returns {@code -1} when {@code target}
|
||||
* is {@code NaN}.
|
||||
*
|
||||
* @param array an array of {@code float} values, possibly empty
|
||||
* @param target a primitive {@code float} value
|
||||
* @return the least index {@code i} for which {@code array[i] == target}, or
|
||||
* {@code -1} if no such index exists.
|
||||
*/
|
||||
public static int indexOf(float[] array, float target) {
|
||||
return indexOf(array, target, 0, array.length);
|
||||
}
|
||||
|
||||
// TODO(kevinb): consider making this public
|
||||
private static int indexOf(float[] array, float target, int start, int end) {
|
||||
for (int i = start; i < end; i++) {
|
||||
if (array[i] == target) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the start position of the first occurrence of the specified {@code
|
||||
* target} within {@code array}, or {@code -1} if there is no such occurrence.
|
||||
*
|
||||
* <p>
|
||||
* More formally, returns the lowest index {@code i} such that {@code
|
||||
* java.util.Arrays.copyOfRange(array, i, i + target.length)} contains exactly
|
||||
* the same elements as {@code target}.
|
||||
*
|
||||
* <p>
|
||||
* Note that this always returns {@code -1} when {@code target} contains
|
||||
* {@code NaN}.
|
||||
*
|
||||
* @param array the array to search for the sequence {@code target}
|
||||
* @param target the array to search for as a sub-sequence of {@code array}
|
||||
*/
|
||||
public static int indexOf(float[] array, float[] target) {
|
||||
checkNotNull(array, "array");
|
||||
checkNotNull(target, "target");
|
||||
if (target.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
outer: for (int i = 0; i < array.length - target.length + 1; i++) {
|
||||
for (int j = 0; j < target.length; j++) {
|
||||
if (array[i + j] != target[j]) {
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the last appearance of the value {@code target} in
|
||||
* {@code array}. Note that this always returns {@code -1} when {@code target}
|
||||
* is {@code NaN}.
|
||||
*
|
||||
* @param array an array of {@code float} values, possibly empty
|
||||
* @param target a primitive {@code float} value
|
||||
* @return the greatest index {@code i} for which {@code array[i] == target}, or
|
||||
* {@code -1} if no such index exists.
|
||||
*/
|
||||
public static int lastIndexOf(float[] array, float target) {
|
||||
return lastIndexOf(array, target, 0, array.length);
|
||||
}
|
||||
|
||||
// TODO(kevinb): consider making this public
|
||||
private static int lastIndexOf(float[] array, float target, int start, int end) {
|
||||
for (int i = end - 1; i >= start; i--) {
|
||||
if (array[i] == target) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the least value present in {@code array}, using the same rules of
|
||||
* comparison as {@link Math#min(float, float)}.
|
||||
*
|
||||
* @param array a <i>nonempty</i> array of {@code float} values
|
||||
* @return the value present in {@code array} that is less than or equal to
|
||||
* every other value in the array
|
||||
* @throws IllegalArgumentException if {@code array} is empty
|
||||
*/
|
||||
public static float min(float... array) {
|
||||
checkArgument(array.length > 0);
|
||||
float min = array[0];
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
min = Math.min(min, array[i]);
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the greatest value present in {@code array}, using the same rules of
|
||||
* comparison as {@link Math#min(float, float)}.
|
||||
*
|
||||
* @param array a <i>nonempty</i> array of {@code float} values
|
||||
* @return the value present in {@code array} that is greater than or equal to
|
||||
* every other value in the array
|
||||
* @throws IllegalArgumentException if {@code array} is empty
|
||||
*/
|
||||
public static float max(float... array) {
|
||||
checkArgument(array.length > 0);
|
||||
float max = array[0];
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
max = Math.max(max, array[i]);
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the values from each provided array combined into a single array. For
|
||||
* example, {@code concat(new float[] {a, b}, new float[] {}, new float[] {c}}
|
||||
* returns the array {@code {a, b, c}}.
|
||||
*
|
||||
* @param arrays zero or more {@code float} arrays
|
||||
* @return a single array containing all the values from the source arrays, in
|
||||
* order
|
||||
*/
|
||||
public static float[] concat(float[]... arrays) {
|
||||
int length = 0;
|
||||
for (float[] array : arrays) {
|
||||
length += array.length;
|
||||
}
|
||||
float[] result = new float[length];
|
||||
int pos = 0;
|
||||
for (float[] array : arrays) {
|
||||
System.arraycopy(array, 0, result, pos, array.length);
|
||||
pos += array.length;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static final class FloatConverter extends Converter<String, Float> implements Serializable {
|
||||
static final FloatConverter INSTANCE = new FloatConverter();
|
||||
|
||||
@Override
|
||||
protected Float doForward(String value) {
|
||||
return Float.valueOf(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doBackward(Float value) {
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Floats.stringConverter()";
|
||||
}
|
||||
|
||||
private Object readResolve() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a serializable converter object that converts between strings and
|
||||
* floats using {@link Float#valueOf} and {@link Float#toString()}.
|
||||
*
|
||||
* @since 16.0
|
||||
*/
|
||||
@Beta
|
||||
public static Converter<String, Float> stringConverter() {
|
||||
return FloatConverter.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing the same values as {@code array}, but guaranteed
|
||||
* to be of a specified minimum length. If {@code array} already has a length of
|
||||
* at least {@code minLength}, it is returned directly. Otherwise, a new array
|
||||
* of size {@code minLength + padding} is returned, containing the values of
|
||||
* {@code array}, and zeroes in the remaining places.
|
||||
*
|
||||
* @param array the source array
|
||||
* @param minLength the minimum length the returned array must guarantee
|
||||
* @param padding an extra amount to "grow" the array by if growth is
|
||||
* necessary
|
||||
* @throws IllegalArgumentException if {@code minLength} or {@code padding} is
|
||||
* negative
|
||||
* @return an array containing the values of {@code array}, with guaranteed
|
||||
* minimum length {@code minLength}
|
||||
*/
|
||||
public static float[] ensureCapacity(float[] array, int minLength, int padding) {
|
||||
checkArgument(minLength >= 0, "Invalid minLength: %s", minLength);
|
||||
checkArgument(padding >= 0, "Invalid padding: %s", padding);
|
||||
return (array.length < minLength) ? copyOf(array, minLength + padding) : array;
|
||||
}
|
||||
|
||||
// Arrays.copyOf() requires Java 6
|
||||
private static float[] copyOf(float[] original, int length) {
|
||||
float[] copy = new float[length];
|
||||
System.arraycopy(original, 0, copy, 0, Math.min(original.length, length));
|
||||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string containing the supplied {@code float} values, converted to
|
||||
* strings as specified by {@link Float#toString(float)}, and separated by
|
||||
* {@code separator}. For example, {@code join("-", 1.0f, 2.0f, 3.0f)} returns
|
||||
* the string {@code "1.0-2.0-3.0"}.
|
||||
*
|
||||
* <p>
|
||||
* Note that {@link Float#toString(float)} formats {@code float} differently in
|
||||
* GWT. In the previous example, it returns the string {@code
|
||||
* "1-2-3"}.
|
||||
*
|
||||
* @param separator the text that should appear between consecutive values in
|
||||
* the resulting string (but not at the start or end)
|
||||
* @param array an array of {@code float} values, possibly empty
|
||||
*/
|
||||
public static String join(String separator, float... array) {
|
||||
checkNotNull(separator);
|
||||
if (array.length == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// For pre-sizing a builder, just get the right order of magnitude
|
||||
StringBuilder builder = new StringBuilder(array.length * 12);
|
||||
builder.append(array[0]);
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
builder.append(separator).append(array[i]);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a comparator that compares two {@code float} arrays
|
||||
* lexicographically. That is, it compares, using
|
||||
* {@link #compare(float, float)}), the first pair of values that follow any
|
||||
* common prefix, or when one array is a prefix of the other, treats the shorter
|
||||
* array as the lesser. For example, {@code [] < [1.0f] < [1.0f, 2.0f]
|
||||
* < [2.0f]}.
|
||||
*
|
||||
* <p>
|
||||
* The returned comparator is inconsistent with {@link Object#equals(Object)}
|
||||
* (since arrays support only identity equality), but it is consistent with
|
||||
* {@link Arrays#equals(float[], float[])}.
|
||||
*
|
||||
* @see <a href="http://en.wikipedia.org/wiki/Lexicographical_order">
|
||||
* Lexicographical order article at Wikipedia</a>
|
||||
* @since 2.0
|
||||
*/
|
||||
public static Comparator<float[]> lexicographicalComparator() {
|
||||
return LexicographicalComparator.INSTANCE;
|
||||
}
|
||||
|
||||
private enum LexicographicalComparator implements Comparator<float[]> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public int compare(float[] left, float[] right) {
|
||||
int minLength = Math.min(left.length, right.length);
|
||||
for (int i = 0; i < minLength; i++) {
|
||||
int result = Floats.compare(left[i], right[i]);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return left.length - right.length;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing each value of {@code collection}, converted to a
|
||||
* {@code float} value in the manner of {@link Number#floatValue}.
|
||||
*
|
||||
* <p>
|
||||
* Elements are copied from the argument collection as if by {@code
|
||||
* collection.toArray()}. Calling this method is as thread-safe as calling that
|
||||
* method.
|
||||
*
|
||||
* @param collection a collection of {@code Number} instances
|
||||
* @return an array containing the same values as {@code collection}, in the
|
||||
* same order, converted to primitives
|
||||
* @throws NullPointerException if {@code collection} or any of its elements is
|
||||
* null
|
||||
* @since 1.0 (parameter was {@code Collection<Float>} before 12.0)
|
||||
*/
|
||||
public static float[] toArray(Collection<? extends Number> collection) {
|
||||
if (collection instanceof FloatArrayAsList) {
|
||||
return ((FloatArrayAsList) collection).toFloatArray();
|
||||
}
|
||||
|
||||
Object[] boxedArray = collection.toArray();
|
||||
int len = boxedArray.length;
|
||||
float[] array = new float[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
// checkNotNull for GWT (do not optimize)
|
||||
array[i] = ((Number) checkNotNull(boxedArray[i])).floatValue();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a fixed-size list backed by the specified array, similar to
|
||||
* {@link Arrays#asList(Object[])}. The list supports
|
||||
* {@link List#set(int, Object)}, but any attempt to set a value to {@code null}
|
||||
* will result in a {@link NullPointerException}.
|
||||
*
|
||||
* <p>
|
||||
* The returned list maintains the values, but not the identities, of
|
||||
* {@code Float} objects written to or read from it. For example, whether
|
||||
* {@code list.get(0) == list.get(0)} is true for the returned list is
|
||||
* unspecified.
|
||||
*
|
||||
* <p>
|
||||
* The returned list may have unexpected behavior if it contains {@code
|
||||
* NaN}, or if {@code NaN} is used as a parameter to any of its methods.
|
||||
*
|
||||
* @param backingArray the array to back the list
|
||||
* @return a list view of the array
|
||||
*/
|
||||
public static List<Float> asList(float... backingArray) {
|
||||
if (backingArray.length == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return new FloatArrayAsList(backingArray);
|
||||
}
|
||||
|
||||
@GwtCompatible
|
||||
private static class FloatArrayAsList extends AbstractList<Float> implements RandomAccess, Serializable {
|
||||
final float[] array;
|
||||
final int start;
|
||||
final int end;
|
||||
|
||||
FloatArrayAsList(float[] array) {
|
||||
this(array, 0, array.length);
|
||||
}
|
||||
|
||||
FloatArrayAsList(float[] array, int start, int end) {
|
||||
this.array = array;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return end - start;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float get(int index) {
|
||||
checkElementIndex(index, size());
|
||||
return array[start + index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
return (target instanceof Float) && Floats.indexOf(array, (Float) target, start, end) != -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
if (target instanceof Float) {
|
||||
int i = Floats.indexOf(array, (Float) target, start, end);
|
||||
if (i >= 0) {
|
||||
return i - start;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lastIndexOf(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
if (target instanceof Float) {
|
||||
int i = Floats.lastIndexOf(array, (Float) target, start, end);
|
||||
if (i >= 0) {
|
||||
return i - start;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float set(int index, Float element) {
|
||||
checkElementIndex(index, size());
|
||||
float oldValue = array[start + index];
|
||||
// checkNotNull for GWT (do not optimize)
|
||||
array[start + index] = checkNotNull(element);
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Float> subList(int fromIndex, int toIndex) {
|
||||
int size = size();
|
||||
checkPositionIndexes(fromIndex, toIndex, size);
|
||||
if (fromIndex == toIndex) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return new FloatArrayAsList(array, start + fromIndex, start + toIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object == this) {
|
||||
return true;
|
||||
}
|
||||
if (object instanceof FloatArrayAsList) {
|
||||
FloatArrayAsList that = (FloatArrayAsList) object;
|
||||
int size = size();
|
||||
if (that.size() != size) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (array[start + i] != that.array[that.start + i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return super.equals(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
for (int i = start; i < end; i++) {
|
||||
result = 31 * result + Floats.hashCode(array[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder(size() * 12);
|
||||
builder.append('[').append(array[start]);
|
||||
for (int i = start + 1; i < end; i++) {
|
||||
builder.append(", ").append(array[i]);
|
||||
}
|
||||
return builder.append(']').toString();
|
||||
}
|
||||
|
||||
float[] toFloatArray() {
|
||||
// Arrays.copyOfRange() is not available under GWT
|
||||
int size = size();
|
||||
float[] result = new float[size];
|
||||
System.arraycopy(array, start, result, 0, size);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the specified string as a single-precision floating point value. The
|
||||
* ASCII character {@code '-'} (<code>'\u002D'</code>) is recognized as the
|
||||
* minus sign.
|
||||
*
|
||||
* <p>
|
||||
* Unlike {@link Float#parseFloat(String)}, this method returns {@code null}
|
||||
* instead of throwing an exception if parsing fails. Valid inputs are exactly
|
||||
* those accepted by {@link Float#valueOf(String)}, except that leading and
|
||||
* trailing whitespace is not permitted.
|
||||
*
|
||||
* <p>
|
||||
* This implementation is likely to be faster than {@code
|
||||
* Float.parseFloat} if many failures are expected.
|
||||
*
|
||||
* @param string the string representation of a {@code float} value
|
||||
* @return the floating point value represented by {@code string}, or
|
||||
* {@code null} if {@code string} has a length of zero or cannot be
|
||||
* parsed as a {@code float} value
|
||||
* @since 14.0
|
||||
*/
|
||||
@GwtIncompatible("regular expressions")
|
||||
@Nullable
|
||||
@Beta
|
||||
public static Float tryParse(String string) {
|
||||
if (Doubles.FLOATING_POINT_PATTERN.matcher(string).matches()) {
|
||||
// TODO(user): could be potentially optimized, but only with
|
||||
// extensive testing
|
||||
try {
|
||||
return Float.parseFloat(string);
|
||||
} catch (NumberFormatException e) {
|
||||
// Float.parseFloat has changed specs several times, so fall through
|
||||
// gracefully
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
760
sources/main/java/com/google/common/primitives/Ints.java
Normal file
760
sources/main/java/com/google/common/primitives/Ints.java
Normal file
@ -0,0 +1,760 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.common.primitives;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkElementIndex;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkPositionIndexes;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.AbstractList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.RandomAccess;
|
||||
|
||||
import javax.annotation.CheckForNull;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
import com.google.common.annotations.GwtIncompatible;
|
||||
import com.google.common.base.Converter;
|
||||
|
||||
/**
|
||||
* Static utility methods pertaining to {@code int} primitives, that are not
|
||||
* already found in either {@link Integer} or {@link Arrays}.
|
||||
*
|
||||
* <p>
|
||||
* See the Guava User Guide article on
|
||||
* <a href= "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained">
|
||||
* primitive utilities</a>.
|
||||
*
|
||||
* @author Kevin Bourrillion
|
||||
* @since 1.0
|
||||
*/
|
||||
@GwtCompatible(emulated = true)
|
||||
public final class Ints {
|
||||
private Ints() {
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of bytes required to represent a primitive {@code int} value.
|
||||
*/
|
||||
public static final int BYTES = Integer.SIZE / Byte.SIZE;
|
||||
|
||||
/**
|
||||
* The largest power of two that can be represented as an {@code int}.
|
||||
*
|
||||
* @since 10.0
|
||||
*/
|
||||
public static final int MAX_POWER_OF_TWO = 1 << (Integer.SIZE - 2);
|
||||
|
||||
/**
|
||||
* Returns a hash code for {@code value}; equal to the result of invoking
|
||||
* {@code ((Integer) value).hashCode()}.
|
||||
*
|
||||
* @param value a primitive {@code int} value
|
||||
* @return a hash code for the value
|
||||
*/
|
||||
public static int hashCode(int value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code int} value that is equal to {@code value}, if possible.
|
||||
*
|
||||
* @param value any value in the range of the {@code int} type
|
||||
* @return the {@code int} value that equals {@code value}
|
||||
* @throws IllegalArgumentException if {@code value} is greater than
|
||||
* {@link Integer#MAX_VALUE} or less than
|
||||
* {@link Integer#MIN_VALUE}
|
||||
*/
|
||||
public static int checkedCast(long value) {
|
||||
int result = (int) value;
|
||||
if (result != value) {
|
||||
// don't use checkArgument here, to avoid boxing
|
||||
throw new IllegalArgumentException("Out of range: " + value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code int} nearest in value to {@code value}.
|
||||
*
|
||||
* @param value any {@code long} value
|
||||
* @return the same value cast to {@code int} if it is in the range of the
|
||||
* {@code int} type, {@link Integer#MAX_VALUE} if it is too large, or
|
||||
* {@link Integer#MIN_VALUE} if it is too small
|
||||
*/
|
||||
public static int saturatedCast(long value) {
|
||||
if (value > Integer.MAX_VALUE) {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
if (value < Integer.MIN_VALUE) {
|
||||
return Integer.MIN_VALUE;
|
||||
}
|
||||
return (int) value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the two specified {@code int} values. The sign of the value returned
|
||||
* is the same as that of {@code ((Integer) a).compareTo(b)}.
|
||||
*
|
||||
* <p>
|
||||
* <b>Note:</b> projects using JDK 7 or later should use the equivalent
|
||||
* {@link Integer#compare} method instead.
|
||||
*
|
||||
* @param a the first {@code int} to compare
|
||||
* @param b the second {@code int} to compare
|
||||
* @return a negative value if {@code a} is less than {@code b}; a positive
|
||||
* value if {@code a} is greater than {@code b}; or zero if they are
|
||||
* equal
|
||||
*/
|
||||
public static int compare(int a, int b) {
|
||||
return (a < b) ? -1 : ((a > b) ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if {@code target} is present as an element anywhere in
|
||||
* {@code array}.
|
||||
*
|
||||
* @param array an array of {@code int} values, possibly empty
|
||||
* @param target a primitive {@code int} value
|
||||
* @return {@code true} if {@code array[i] == target} for some value of {@code
|
||||
* i}
|
||||
*/
|
||||
public static boolean contains(int[] array, int target) {
|
||||
for (int value : array) {
|
||||
if (value == target) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the first appearance of the value {@code target} in
|
||||
* {@code array}.
|
||||
*
|
||||
* @param array an array of {@code int} values, possibly empty
|
||||
* @param target a primitive {@code int} value
|
||||
* @return the least index {@code i} for which {@code array[i] == target}, or
|
||||
* {@code -1} if no such index exists.
|
||||
*/
|
||||
public static int indexOf(int[] array, int target) {
|
||||
return indexOf(array, target, 0, array.length);
|
||||
}
|
||||
|
||||
// TODO(kevinb): consider making this public
|
||||
private static int indexOf(int[] array, int target, int start, int end) {
|
||||
for (int i = start; i < end; i++) {
|
||||
if (array[i] == target) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the start position of the first occurrence of the specified {@code
|
||||
* target} within {@code array}, or {@code -1} if there is no such occurrence.
|
||||
*
|
||||
* <p>
|
||||
* More formally, returns the lowest index {@code i} such that {@code
|
||||
* java.util.Arrays.copyOfRange(array, i, i + target.length)} contains exactly
|
||||
* the same elements as {@code target}.
|
||||
*
|
||||
* @param array the array to search for the sequence {@code target}
|
||||
* @param target the array to search for as a sub-sequence of {@code array}
|
||||
*/
|
||||
public static int indexOf(int[] array, int[] target) {
|
||||
checkNotNull(array, "array");
|
||||
checkNotNull(target, "target");
|
||||
if (target.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
outer: for (int i = 0; i < array.length - target.length + 1; i++) {
|
||||
for (int j = 0; j < target.length; j++) {
|
||||
if (array[i + j] != target[j]) {
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the last appearance of the value {@code target} in
|
||||
* {@code array}.
|
||||
*
|
||||
* @param array an array of {@code int} values, possibly empty
|
||||
* @param target a primitive {@code int} value
|
||||
* @return the greatest index {@code i} for which {@code array[i] == target}, or
|
||||
* {@code -1} if no such index exists.
|
||||
*/
|
||||
public static int lastIndexOf(int[] array, int target) {
|
||||
return lastIndexOf(array, target, 0, array.length);
|
||||
}
|
||||
|
||||
// TODO(kevinb): consider making this public
|
||||
private static int lastIndexOf(int[] array, int target, int start, int end) {
|
||||
for (int i = end - 1; i >= start; i--) {
|
||||
if (array[i] == target) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the least value present in {@code array}.
|
||||
*
|
||||
* @param array a <i>nonempty</i> array of {@code int} values
|
||||
* @return the value present in {@code array} that is less than or equal to
|
||||
* every other value in the array
|
||||
* @throws IllegalArgumentException if {@code array} is empty
|
||||
*/
|
||||
public static int min(int... array) {
|
||||
checkArgument(array.length > 0);
|
||||
int min = array[0];
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
if (array[i] < min) {
|
||||
min = array[i];
|
||||
}
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the greatest value present in {@code array}.
|
||||
*
|
||||
* @param array a <i>nonempty</i> array of {@code int} values
|
||||
* @return the value present in {@code array} that is greater than or equal to
|
||||
* every other value in the array
|
||||
* @throws IllegalArgumentException if {@code array} is empty
|
||||
*/
|
||||
public static int max(int... array) {
|
||||
checkArgument(array.length > 0);
|
||||
int max = array[0];
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
if (array[i] > max) {
|
||||
max = array[i];
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the values from each provided array combined into a single array. For
|
||||
* example, {@code concat(new int[] {a, b}, new int[] {}, new int[] {c}} returns
|
||||
* the array {@code {a, b, c}}.
|
||||
*
|
||||
* @param arrays zero or more {@code int} arrays
|
||||
* @return a single array containing all the values from the source arrays, in
|
||||
* order
|
||||
*/
|
||||
public static int[] concat(int[]... arrays) {
|
||||
int length = 0;
|
||||
for (int[] array : arrays) {
|
||||
length += array.length;
|
||||
}
|
||||
int[] result = new int[length];
|
||||
int pos = 0;
|
||||
for (int[] array : arrays) {
|
||||
System.arraycopy(array, 0, result, pos, array.length);
|
||||
pos += array.length;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a big-endian representation of {@code value} in a 4-element byte
|
||||
* array; equivalent to {@code ByteBuffer.allocate(4).putInt(value).array()}.
|
||||
* For example, the input value {@code 0x12131415} would yield the byte array
|
||||
* {@code {0x12, 0x13, 0x14, 0x15}}.
|
||||
*
|
||||
* <p>
|
||||
* If you need to convert and concatenate several values (possibly even of
|
||||
* different types), use a shared {@link java.nio.ByteBuffer} instance, or use
|
||||
* {@link com.google.common.io.ByteStreams#newDataOutput()} to get a growable
|
||||
* buffer.
|
||||
*/
|
||||
@GwtIncompatible("doesn't work")
|
||||
public static byte[] toByteArray(int value) {
|
||||
return new byte[] { (byte) (value >> 24), (byte) (value >> 16), (byte) (value >> 8), (byte) value };
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code int} value whose big-endian representation is stored in
|
||||
* the first 4 bytes of {@code bytes}; equivalent to {@code
|
||||
* ByteBuffer.wrap(bytes).getInt()}. For example, the input byte array
|
||||
* {@code {0x12, 0x13, 0x14, 0x15, 0x33}} would yield the {@code int} value
|
||||
* {@code
|
||||
* 0x12131415}.
|
||||
*
|
||||
* <p>
|
||||
* Arguably, it's preferable to use {@link java.nio.ByteBuffer}; that library
|
||||
* exposes much more flexibility at little cost in readability.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code bytes} has fewer than 4 elements
|
||||
*/
|
||||
@GwtIncompatible("doesn't work")
|
||||
public static int fromByteArray(byte[] bytes) {
|
||||
checkArgument(bytes.length >= BYTES, "array too small: %s < %s", bytes.length, BYTES);
|
||||
return fromBytes(bytes[0], bytes[1], bytes[2], bytes[3]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code int} value whose byte representation is the given 4 bytes,
|
||||
* in big-endian order; equivalent to {@code Ints.fromByteArray(new byte[] {b1,
|
||||
* b2, b3, b4})}.
|
||||
*
|
||||
* @since 7.0
|
||||
*/
|
||||
@GwtIncompatible("doesn't work")
|
||||
public static int fromBytes(byte b1, byte b2, byte b3, byte b4) {
|
||||
return b1 << 24 | (b2 & 0xFF) << 16 | (b3 & 0xFF) << 8 | (b4 & 0xFF);
|
||||
}
|
||||
|
||||
private static final class IntConverter extends Converter<String, Integer> implements Serializable {
|
||||
static final IntConverter INSTANCE = new IntConverter();
|
||||
|
||||
@Override
|
||||
protected Integer doForward(String value) {
|
||||
return Integer.decode(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doBackward(Integer value) {
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Ints.stringConverter()";
|
||||
}
|
||||
|
||||
private Object readResolve() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a serializable converter object that converts between strings and
|
||||
* integers using {@link Integer#decode} and {@link Integer#toString()}.
|
||||
*
|
||||
* @since 16.0
|
||||
*/
|
||||
@Beta
|
||||
public static Converter<String, Integer> stringConverter() {
|
||||
return IntConverter.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing the same values as {@code array}, but guaranteed
|
||||
* to be of a specified minimum length. If {@code array} already has a length of
|
||||
* at least {@code minLength}, it is returned directly. Otherwise, a new array
|
||||
* of size {@code minLength + padding} is returned, containing the values of
|
||||
* {@code array}, and zeroes in the remaining places.
|
||||
*
|
||||
* @param array the source array
|
||||
* @param minLength the minimum length the returned array must guarantee
|
||||
* @param padding an extra amount to "grow" the array by if growth is
|
||||
* necessary
|
||||
* @throws IllegalArgumentException if {@code minLength} or {@code padding} is
|
||||
* negative
|
||||
* @return an array containing the values of {@code array}, with guaranteed
|
||||
* minimum length {@code minLength}
|
||||
*/
|
||||
public static int[] ensureCapacity(int[] array, int minLength, int padding) {
|
||||
checkArgument(minLength >= 0, "Invalid minLength: %s", minLength);
|
||||
checkArgument(padding >= 0, "Invalid padding: %s", padding);
|
||||
return (array.length < minLength) ? copyOf(array, minLength + padding) : array;
|
||||
}
|
||||
|
||||
// Arrays.copyOf() requires Java 6
|
||||
private static int[] copyOf(int[] original, int length) {
|
||||
int[] copy = new int[length];
|
||||
System.arraycopy(original, 0, copy, 0, Math.min(original.length, length));
|
||||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string containing the supplied {@code int} values separated by
|
||||
* {@code separator}. For example, {@code join("-", 1, 2, 3)} returns the string
|
||||
* {@code "1-2-3"}.
|
||||
*
|
||||
* @param separator the text that should appear between consecutive values in
|
||||
* the resulting string (but not at the start or end)
|
||||
* @param array an array of {@code int} values, possibly empty
|
||||
*/
|
||||
public static String join(String separator, int... array) {
|
||||
checkNotNull(separator);
|
||||
if (array.length == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// For pre-sizing a builder, just get the right order of magnitude
|
||||
StringBuilder builder = new StringBuilder(array.length * 5);
|
||||
builder.append(array[0]);
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
builder.append(separator).append(array[i]);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a comparator that compares two {@code int} arrays lexicographically.
|
||||
* That is, it compares, using {@link #compare(int, int)}), the first pair of
|
||||
* values that follow any common prefix, or when one array is a prefix of the
|
||||
* other, treats the shorter array as the lesser. For example,
|
||||
* {@code [] < [1] < [1, 2] < [2]}.
|
||||
*
|
||||
* <p>
|
||||
* The returned comparator is inconsistent with {@link Object#equals(Object)}
|
||||
* (since arrays support only identity equality), but it is consistent with
|
||||
* {@link Arrays#equals(int[], int[])}.
|
||||
*
|
||||
* @see <a href="http://en.wikipedia.org/wiki/Lexicographical_order">
|
||||
* Lexicographical order article at Wikipedia</a>
|
||||
* @since 2.0
|
||||
*/
|
||||
public static Comparator<int[]> lexicographicalComparator() {
|
||||
return LexicographicalComparator.INSTANCE;
|
||||
}
|
||||
|
||||
private enum LexicographicalComparator implements Comparator<int[]> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public int compare(int[] left, int[] right) {
|
||||
int minLength = Math.min(left.length, right.length);
|
||||
for (int i = 0; i < minLength; i++) {
|
||||
int result = Ints.compare(left[i], right[i]);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return left.length - right.length;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing each value of {@code collection}, converted to a
|
||||
* {@code int} value in the manner of {@link Number#intValue}.
|
||||
*
|
||||
* <p>
|
||||
* Elements are copied from the argument collection as if by {@code
|
||||
* collection.toArray()}. Calling this method is as thread-safe as calling that
|
||||
* method.
|
||||
*
|
||||
* @param collection a collection of {@code Number} instances
|
||||
* @return an array containing the same values as {@code collection}, in the
|
||||
* same order, converted to primitives
|
||||
* @throws NullPointerException if {@code collection} or any of its elements is
|
||||
* null
|
||||
* @since 1.0 (parameter was {@code Collection<Integer>} before 12.0)
|
||||
*/
|
||||
public static int[] toArray(Collection<? extends Number> collection) {
|
||||
if (collection instanceof IntArrayAsList) {
|
||||
return ((IntArrayAsList) collection).toIntArray();
|
||||
}
|
||||
|
||||
Object[] boxedArray = collection.toArray();
|
||||
int len = boxedArray.length;
|
||||
int[] array = new int[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
// checkNotNull for GWT (do not optimize)
|
||||
array[i] = ((Number) checkNotNull(boxedArray[i])).intValue();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a fixed-size list backed by the specified array, similar to
|
||||
* {@link Arrays#asList(Object[])}. The list supports
|
||||
* {@link List#set(int, Object)}, but any attempt to set a value to {@code null}
|
||||
* will result in a {@link NullPointerException}.
|
||||
*
|
||||
* <p>
|
||||
* The returned list maintains the values, but not the identities, of
|
||||
* {@code Integer} objects written to or read from it. For example, whether
|
||||
* {@code list.get(0) == list.get(0)} is true for the returned list is
|
||||
* unspecified.
|
||||
*
|
||||
* @param backingArray the array to back the list
|
||||
* @return a list view of the array
|
||||
*/
|
||||
public static List<Integer> asList(int... backingArray) {
|
||||
if (backingArray.length == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return new IntArrayAsList(backingArray);
|
||||
}
|
||||
|
||||
@GwtCompatible
|
||||
private static class IntArrayAsList extends AbstractList<Integer> implements RandomAccess, Serializable {
|
||||
final int[] array;
|
||||
final int start;
|
||||
final int end;
|
||||
|
||||
IntArrayAsList(int[] array) {
|
||||
this(array, 0, array.length);
|
||||
}
|
||||
|
||||
IntArrayAsList(int[] array, int start, int end) {
|
||||
this.array = array;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return end - start;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer get(int index) {
|
||||
checkElementIndex(index, size());
|
||||
return array[start + index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
return (target instanceof Integer) && Ints.indexOf(array, (Integer) target, start, end) != -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
if (target instanceof Integer) {
|
||||
int i = Ints.indexOf(array, (Integer) target, start, end);
|
||||
if (i >= 0) {
|
||||
return i - start;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lastIndexOf(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
if (target instanceof Integer) {
|
||||
int i = Ints.lastIndexOf(array, (Integer) target, start, end);
|
||||
if (i >= 0) {
|
||||
return i - start;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer set(int index, Integer element) {
|
||||
checkElementIndex(index, size());
|
||||
int oldValue = array[start + index];
|
||||
// checkNotNull for GWT (do not optimize)
|
||||
array[start + index] = checkNotNull(element);
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Integer> subList(int fromIndex, int toIndex) {
|
||||
int size = size();
|
||||
checkPositionIndexes(fromIndex, toIndex, size);
|
||||
if (fromIndex == toIndex) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return new IntArrayAsList(array, start + fromIndex, start + toIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object == this) {
|
||||
return true;
|
||||
}
|
||||
if (object instanceof IntArrayAsList) {
|
||||
IntArrayAsList that = (IntArrayAsList) object;
|
||||
int size = size();
|
||||
if (that.size() != size) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (array[start + i] != that.array[that.start + i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return super.equals(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
for (int i = start; i < end; i++) {
|
||||
result = 31 * result + Ints.hashCode(array[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder(size() * 5);
|
||||
builder.append('[').append(array[start]);
|
||||
for (int i = start + 1; i < end; i++) {
|
||||
builder.append(", ").append(array[i]);
|
||||
}
|
||||
return builder.append(']').toString();
|
||||
}
|
||||
|
||||
int[] toIntArray() {
|
||||
// Arrays.copyOfRange() is not available under GWT
|
||||
int size = size();
|
||||
int[] result = new int[size];
|
||||
System.arraycopy(array, start, result, 0, size);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0;
|
||||
}
|
||||
|
||||
private static final byte[] asciiDigits = new byte[128];
|
||||
|
||||
static {
|
||||
Arrays.fill(asciiDigits, (byte) -1);
|
||||
for (int i = 0; i <= 9; i++) {
|
||||
asciiDigits['0' + i] = (byte) i;
|
||||
}
|
||||
for (int i = 0; i <= 26; i++) {
|
||||
asciiDigits['A' + i] = (byte) (10 + i);
|
||||
asciiDigits['a' + i] = (byte) (10 + i);
|
||||
}
|
||||
}
|
||||
|
||||
private static int digit(char c) {
|
||||
return (c < 128) ? asciiDigits[c] : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the specified string as a signed decimal integer value. The ASCII
|
||||
* character {@code '-'} (<code>'\u002D'</code>) is recognized as the minus
|
||||
* sign.
|
||||
*
|
||||
* <p>
|
||||
* Unlike {@link Integer#parseInt(String)}, this method returns {@code null}
|
||||
* instead of throwing an exception if parsing fails. Additionally, this method
|
||||
* only accepts ASCII digits, and returns {@code null} if non-ASCII digits are
|
||||
* present in the string.
|
||||
*
|
||||
* <p>
|
||||
* Note that strings prefixed with ASCII {@code '+'} are rejected, even under
|
||||
* JDK 7, despite the change to {@link Integer#parseInt(String)} for that
|
||||
* version.
|
||||
*
|
||||
* @param string the string representation of an integer value
|
||||
* @return the integer value represented by {@code string}, or {@code null} if
|
||||
* {@code string} has a length of zero or cannot be parsed as an integer
|
||||
* value
|
||||
* @since 11.0
|
||||
*/
|
||||
@Beta
|
||||
@CheckForNull
|
||||
@GwtIncompatible("TODO")
|
||||
public static Integer tryParse(String string) {
|
||||
return tryParse(string, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the specified string as a signed integer value using the specified
|
||||
* radix. The ASCII character {@code '-'} (<code>'\u002D'</code>) is
|
||||
* recognized as the minus sign.
|
||||
*
|
||||
* <p>
|
||||
* Unlike {@link Integer#parseInt(String, int)}, this method returns
|
||||
* {@code null} instead of throwing an exception if parsing fails. Additionally,
|
||||
* this method only accepts ASCII digits, and returns {@code null} if non-ASCII
|
||||
* digits are present in the string.
|
||||
*
|
||||
* <p>
|
||||
* Note that strings prefixed with ASCII {@code '+'} are rejected, even under
|
||||
* JDK 7, despite the change to {@link Integer#parseInt(String, int)} for that
|
||||
* version.
|
||||
*
|
||||
* @param string the string representation of an integer value
|
||||
* @param radix the radix to use when parsing
|
||||
* @return the integer value represented by {@code string} using {@code radix},
|
||||
* or {@code null} if {@code string} has a length of zero or cannot be
|
||||
* parsed as an integer value
|
||||
* @throws IllegalArgumentException if {@code radix < Character.MIN_RADIX} or
|
||||
* {@code radix > Character.MAX_RADIX}
|
||||
*/
|
||||
@CheckForNull
|
||||
@GwtIncompatible("TODO")
|
||||
static Integer tryParse(String string, int radix) {
|
||||
if (checkNotNull(string).isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
|
||||
throw new IllegalArgumentException("radix must be between MIN_RADIX and MAX_RADIX but was " + radix);
|
||||
}
|
||||
boolean negative = string.charAt(0) == '-';
|
||||
int index = negative ? 1 : 0;
|
||||
if (index == string.length()) {
|
||||
return null;
|
||||
}
|
||||
int digit = digit(string.charAt(index++));
|
||||
if (digit < 0 || digit >= radix) {
|
||||
return null;
|
||||
}
|
||||
int accum = -digit;
|
||||
|
||||
int cap = Integer.MIN_VALUE / radix;
|
||||
|
||||
while (index < string.length()) {
|
||||
digit = digit(string.charAt(index++));
|
||||
if (digit < 0 || digit >= radix || accum < cap) {
|
||||
return null;
|
||||
}
|
||||
accum *= radix;
|
||||
if (accum < Integer.MIN_VALUE + digit) {
|
||||
return null;
|
||||
}
|
||||
accum -= digit;
|
||||
}
|
||||
|
||||
if (negative) {
|
||||
return accum;
|
||||
} else if (accum == Integer.MIN_VALUE) {
|
||||
return null;
|
||||
} else {
|
||||
return -accum;
|
||||
}
|
||||
}
|
||||
}
|
674
sources/main/java/com/google/common/primitives/Longs.java
Normal file
674
sources/main/java/com/google/common/primitives/Longs.java
Normal file
@ -0,0 +1,674 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.common.primitives;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkElementIndex;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkPositionIndexes;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.AbstractList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.RandomAccess;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
import com.google.common.base.Converter;
|
||||
|
||||
/**
|
||||
* Static utility methods pertaining to {@code long} primitives, that are not
|
||||
* already found in either {@link Long} or {@link Arrays}.
|
||||
*
|
||||
* <p>
|
||||
* See the Guava User Guide article on
|
||||
* <a href= "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained">
|
||||
* primitive utilities</a>.
|
||||
*
|
||||
* @author Kevin Bourrillion
|
||||
* @since 1.0
|
||||
*/
|
||||
@GwtCompatible
|
||||
public final class Longs {
|
||||
private Longs() {
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of bytes required to represent a primitive {@code long} value.
|
||||
*/
|
||||
public static final int BYTES = Long.SIZE / Byte.SIZE;
|
||||
|
||||
/**
|
||||
* The largest power of two that can be represented as a {@code long}.
|
||||
*
|
||||
* @since 10.0
|
||||
*/
|
||||
public static final long MAX_POWER_OF_TWO = 1L << (Long.SIZE - 2);
|
||||
|
||||
/**
|
||||
* Returns a hash code for {@code value}; equal to the result of invoking
|
||||
* {@code ((Long) value).hashCode()}.
|
||||
*
|
||||
* <p>
|
||||
* This method always return the value specified by {@link Long#hashCode()} in
|
||||
* java, which might be different from {@code ((Long) value).hashCode()} in GWT
|
||||
* because {@link Long#hashCode()} in GWT does not obey the JRE contract.
|
||||
*
|
||||
* @param value a primitive {@code long} value
|
||||
* @return a hash code for the value
|
||||
*/
|
||||
public static int hashCode(long value) {
|
||||
return (int) (value ^ (value >>> 32));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the two specified {@code long} values. The sign of the value
|
||||
* returned is the same as that of {@code ((Long) a).compareTo(b)}.
|
||||
*
|
||||
* <p>
|
||||
* <b>Note:</b> projects using JDK 7 or later should use the equivalent
|
||||
* {@link Long#compare} method instead.
|
||||
*
|
||||
* @param a the first {@code long} to compare
|
||||
* @param b the second {@code long} to compare
|
||||
* @return a negative value if {@code a} is less than {@code b}; a positive
|
||||
* value if {@code a} is greater than {@code b}; or zero if they are
|
||||
* equal
|
||||
*/
|
||||
public static int compare(long a, long b) {
|
||||
return (a < b) ? -1 : ((a > b) ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if {@code target} is present as an element anywhere in
|
||||
* {@code array}.
|
||||
*
|
||||
* @param array an array of {@code long} values, possibly empty
|
||||
* @param target a primitive {@code long} value
|
||||
* @return {@code true} if {@code array[i] == target} for some value of {@code
|
||||
* i}
|
||||
*/
|
||||
public static boolean contains(long[] array, long target) {
|
||||
for (long value : array) {
|
||||
if (value == target) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the first appearance of the value {@code target} in
|
||||
* {@code array}.
|
||||
*
|
||||
* @param array an array of {@code long} values, possibly empty
|
||||
* @param target a primitive {@code long} value
|
||||
* @return the least index {@code i} for which {@code array[i] == target}, or
|
||||
* {@code -1} if no such index exists.
|
||||
*/
|
||||
public static int indexOf(long[] array, long target) {
|
||||
return indexOf(array, target, 0, array.length);
|
||||
}
|
||||
|
||||
// TODO(kevinb): consider making this public
|
||||
private static int indexOf(long[] array, long target, int start, int end) {
|
||||
for (int i = start; i < end; i++) {
|
||||
if (array[i] == target) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the start position of the first occurrence of the specified {@code
|
||||
* target} within {@code array}, or {@code -1} if there is no such occurrence.
|
||||
*
|
||||
* <p>
|
||||
* More formally, returns the lowest index {@code i} such that {@code
|
||||
* java.util.Arrays.copyOfRange(array, i, i + target.length)} contains exactly
|
||||
* the same elements as {@code target}.
|
||||
*
|
||||
* @param array the array to search for the sequence {@code target}
|
||||
* @param target the array to search for as a sub-sequence of {@code array}
|
||||
*/
|
||||
public static int indexOf(long[] array, long[] target) {
|
||||
checkNotNull(array, "array");
|
||||
checkNotNull(target, "target");
|
||||
if (target.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
outer: for (int i = 0; i < array.length - target.length + 1; i++) {
|
||||
for (int j = 0; j < target.length; j++) {
|
||||
if (array[i + j] != target[j]) {
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the last appearance of the value {@code target} in
|
||||
* {@code array}.
|
||||
*
|
||||
* @param array an array of {@code long} values, possibly empty
|
||||
* @param target a primitive {@code long} value
|
||||
* @return the greatest index {@code i} for which {@code array[i] == target}, or
|
||||
* {@code -1} if no such index exists.
|
||||
*/
|
||||
public static int lastIndexOf(long[] array, long target) {
|
||||
return lastIndexOf(array, target, 0, array.length);
|
||||
}
|
||||
|
||||
// TODO(kevinb): consider making this public
|
||||
private static int lastIndexOf(long[] array, long target, int start, int end) {
|
||||
for (int i = end - 1; i >= start; i--) {
|
||||
if (array[i] == target) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the least value present in {@code array}.
|
||||
*
|
||||
* @param array a <i>nonempty</i> array of {@code long} values
|
||||
* @return the value present in {@code array} that is less than or equal to
|
||||
* every other value in the array
|
||||
* @throws IllegalArgumentException if {@code array} is empty
|
||||
*/
|
||||
public static long min(long... array) {
|
||||
checkArgument(array.length > 0);
|
||||
long min = array[0];
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
if (array[i] < min) {
|
||||
min = array[i];
|
||||
}
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the greatest value present in {@code array}.
|
||||
*
|
||||
* @param array a <i>nonempty</i> array of {@code long} values
|
||||
* @return the value present in {@code array} that is greater than or equal to
|
||||
* every other value in the array
|
||||
* @throws IllegalArgumentException if {@code array} is empty
|
||||
*/
|
||||
public static long max(long... array) {
|
||||
checkArgument(array.length > 0);
|
||||
long max = array[0];
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
if (array[i] > max) {
|
||||
max = array[i];
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the values from each provided array combined into a single array. For
|
||||
* example, {@code concat(new long[] {a, b}, new long[] {}, new long[] {c}}
|
||||
* returns the array {@code {a, b, c}}.
|
||||
*
|
||||
* @param arrays zero or more {@code long} arrays
|
||||
* @return a single array containing all the values from the source arrays, in
|
||||
* order
|
||||
*/
|
||||
public static long[] concat(long[]... arrays) {
|
||||
int length = 0;
|
||||
for (long[] array : arrays) {
|
||||
length += array.length;
|
||||
}
|
||||
long[] result = new long[length];
|
||||
int pos = 0;
|
||||
for (long[] array : arrays) {
|
||||
System.arraycopy(array, 0, result, pos, array.length);
|
||||
pos += array.length;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a big-endian representation of {@code value} in an 8-element byte
|
||||
* array; equivalent to {@code ByteBuffer.allocate(8).putLong(value).array()}.
|
||||
* For example, the input value {@code 0x1213141516171819L} would yield the byte
|
||||
* array {@code {0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19}}.
|
||||
*
|
||||
* <p>
|
||||
* If you need to convert and concatenate several values (possibly even of
|
||||
* different types), use a shared {@link java.nio.ByteBuffer} instance, or use
|
||||
* {@link com.google.common.io.ByteStreams#newDataOutput()} to get a growable
|
||||
* buffer.
|
||||
*/
|
||||
public static byte[] toByteArray(long value) {
|
||||
// Note that this code needs to stay compatible with GWT, which has known
|
||||
// bugs when narrowing byte casts of long values occur.
|
||||
byte[] result = new byte[8];
|
||||
for (int i = 7; i >= 0; i--) {
|
||||
result[i] = (byte) (value & 0xffL);
|
||||
value >>= 8;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code long} value whose big-endian representation is stored in
|
||||
* the first 8 bytes of {@code bytes}; equivalent to {@code
|
||||
* ByteBuffer.wrap(bytes).getLong()}. For example, the input byte array
|
||||
* {@code {0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19}} would yield the
|
||||
* {@code long} value {@code 0x1213141516171819L}.
|
||||
*
|
||||
* <p>
|
||||
* Arguably, it's preferable to use {@link java.nio.ByteBuffer}; that library
|
||||
* exposes much more flexibility at little cost in readability.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code bytes} has fewer than 8 elements
|
||||
*/
|
||||
public static long fromByteArray(byte[] bytes) {
|
||||
checkArgument(bytes.length >= BYTES, "array too small: %s < %s", bytes.length, BYTES);
|
||||
return fromBytes(bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code long} value whose byte representation is the given 8
|
||||
* bytes, in big-endian order; equivalent to {@code Longs.fromByteArray(new
|
||||
* byte[] {b1, b2, b3, b4, b5, b6, b7, b8})}.
|
||||
*
|
||||
* @since 7.0
|
||||
*/
|
||||
public static long fromBytes(byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8) {
|
||||
return (b1 & 0xFFL) << 56 | (b2 & 0xFFL) << 48 | (b3 & 0xFFL) << 40 | (b4 & 0xFFL) << 32 | (b5 & 0xFFL) << 24
|
||||
| (b6 & 0xFFL) << 16 | (b7 & 0xFFL) << 8 | (b8 & 0xFFL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the specified string as a signed decimal long value. The ASCII
|
||||
* character {@code '-'} (<code>'\u002D'</code>) is recognized as the minus
|
||||
* sign.
|
||||
*
|
||||
* <p>
|
||||
* Unlike {@link Long#parseLong(String)}, this method returns {@code null}
|
||||
* instead of throwing an exception if parsing fails. Additionally, this method
|
||||
* only accepts ASCII digits, and returns {@code null} if non-ASCII digits are
|
||||
* present in the string.
|
||||
*
|
||||
* <p>
|
||||
* Note that strings prefixed with ASCII {@code '+'} are rejected, even under
|
||||
* JDK 7, despite the change to {@link Long#parseLong(String)} for that version.
|
||||
*
|
||||
* @param string the string representation of a long value
|
||||
* @return the long value represented by {@code string}, or {@code null} if
|
||||
* {@code string} has a length of zero or cannot be parsed as a long
|
||||
* value
|
||||
* @since 14.0
|
||||
*/
|
||||
@Beta
|
||||
public static Long tryParse(String string) {
|
||||
if (checkNotNull(string).isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
boolean negative = string.charAt(0) == '-';
|
||||
int index = negative ? 1 : 0;
|
||||
if (index == string.length()) {
|
||||
return null;
|
||||
}
|
||||
int digit = string.charAt(index++) - '0';
|
||||
if (digit < 0 || digit > 9) {
|
||||
return null;
|
||||
}
|
||||
long accum = -digit;
|
||||
while (index < string.length()) {
|
||||
digit = string.charAt(index++) - '0';
|
||||
if (digit < 0 || digit > 9 || accum < Long.MIN_VALUE / 10) {
|
||||
return null;
|
||||
}
|
||||
accum *= 10;
|
||||
if (accum < Long.MIN_VALUE + digit) {
|
||||
return null;
|
||||
}
|
||||
accum -= digit;
|
||||
}
|
||||
|
||||
if (negative) {
|
||||
return accum;
|
||||
} else if (accum == Long.MIN_VALUE) {
|
||||
return null;
|
||||
} else {
|
||||
return -accum;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class LongConverter extends Converter<String, Long> implements Serializable {
|
||||
static final LongConverter INSTANCE = new LongConverter();
|
||||
|
||||
@Override
|
||||
protected Long doForward(String value) {
|
||||
return Long.decode(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doBackward(Long value) {
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Longs.stringConverter()";
|
||||
}
|
||||
|
||||
private Object readResolve() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a serializable converter object that converts between strings and
|
||||
* longs using {@link Long#decode} and {@link Long#toString()}.
|
||||
*
|
||||
* @since 16.0
|
||||
*/
|
||||
@Beta
|
||||
public static Converter<String, Long> stringConverter() {
|
||||
return LongConverter.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing the same values as {@code array}, but guaranteed
|
||||
* to be of a specified minimum length. If {@code array} already has a length of
|
||||
* at least {@code minLength}, it is returned directly. Otherwise, a new array
|
||||
* of size {@code minLength + padding} is returned, containing the values of
|
||||
* {@code array}, and zeroes in the remaining places.
|
||||
*
|
||||
* @param array the source array
|
||||
* @param minLength the minimum length the returned array must guarantee
|
||||
* @param padding an extra amount to "grow" the array by if growth is
|
||||
* necessary
|
||||
* @throws IllegalArgumentException if {@code minLength} or {@code padding} is
|
||||
* negative
|
||||
* @return an array containing the values of {@code array}, with guaranteed
|
||||
* minimum length {@code minLength}
|
||||
*/
|
||||
public static long[] ensureCapacity(long[] array, int minLength, int padding) {
|
||||
checkArgument(minLength >= 0, "Invalid minLength: %s", minLength);
|
||||
checkArgument(padding >= 0, "Invalid padding: %s", padding);
|
||||
return (array.length < minLength) ? copyOf(array, minLength + padding) : array;
|
||||
}
|
||||
|
||||
// Arrays.copyOf() requires Java 6
|
||||
private static long[] copyOf(long[] original, int length) {
|
||||
long[] copy = new long[length];
|
||||
System.arraycopy(original, 0, copy, 0, Math.min(original.length, length));
|
||||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string containing the supplied {@code long} values separated by
|
||||
* {@code separator}. For example, {@code join("-", 1L, 2L, 3L)} returns the
|
||||
* string {@code "1-2-3"}.
|
||||
*
|
||||
* @param separator the text that should appear between consecutive values in
|
||||
* the resulting string (but not at the start or end)
|
||||
* @param array an array of {@code long} values, possibly empty
|
||||
*/
|
||||
public static String join(String separator, long... array) {
|
||||
checkNotNull(separator);
|
||||
if (array.length == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// For pre-sizing a builder, just get the right order of magnitude
|
||||
StringBuilder builder = new StringBuilder(array.length * 10);
|
||||
builder.append(array[0]);
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
builder.append(separator).append(array[i]);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a comparator that compares two {@code long} arrays lexicographically.
|
||||
* That is, it compares, using {@link #compare(long, long)}), the first pair of
|
||||
* values that follow any common prefix, or when one array is a prefix of the
|
||||
* other, treats the shorter array as the lesser. For example,
|
||||
* {@code [] < [1L] < [1L, 2L] < [2L]}.
|
||||
*
|
||||
* <p>
|
||||
* The returned comparator is inconsistent with {@link Object#equals(Object)}
|
||||
* (since arrays support only identity equality), but it is consistent with
|
||||
* {@link Arrays#equals(long[], long[])}.
|
||||
*
|
||||
* @see <a href="http://en.wikipedia.org/wiki/Lexicographical_order">
|
||||
* Lexicographical order article at Wikipedia</a>
|
||||
* @since 2.0
|
||||
*/
|
||||
public static Comparator<long[]> lexicographicalComparator() {
|
||||
return LexicographicalComparator.INSTANCE;
|
||||
}
|
||||
|
||||
private enum LexicographicalComparator implements Comparator<long[]> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public int compare(long[] left, long[] right) {
|
||||
int minLength = Math.min(left.length, right.length);
|
||||
for (int i = 0; i < minLength; i++) {
|
||||
int result = Longs.compare(left[i], right[i]);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return left.length - right.length;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing each value of {@code collection}, converted to a
|
||||
* {@code long} value in the manner of {@link Number#longValue}.
|
||||
*
|
||||
* <p>
|
||||
* Elements are copied from the argument collection as if by {@code
|
||||
* collection.toArray()}. Calling this method is as thread-safe as calling that
|
||||
* method.
|
||||
*
|
||||
* @param collection a collection of {@code Number} instances
|
||||
* @return an array containing the same values as {@code collection}, in the
|
||||
* same order, converted to primitives
|
||||
* @throws NullPointerException if {@code collection} or any of its elements is
|
||||
* null
|
||||
* @since 1.0 (parameter was {@code Collection<Long>} before 12.0)
|
||||
*/
|
||||
public static long[] toArray(Collection<? extends Number> collection) {
|
||||
if (collection instanceof LongArrayAsList) {
|
||||
return ((LongArrayAsList) collection).toLongArray();
|
||||
}
|
||||
|
||||
Object[] boxedArray = collection.toArray();
|
||||
int len = boxedArray.length;
|
||||
long[] array = new long[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
// checkNotNull for GWT (do not optimize)
|
||||
array[i] = ((Number) checkNotNull(boxedArray[i])).longValue();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a fixed-size list backed by the specified array, similar to
|
||||
* {@link Arrays#asList(Object[])}. The list supports
|
||||
* {@link List#set(int, Object)}, but any attempt to set a value to {@code null}
|
||||
* will result in a {@link NullPointerException}.
|
||||
*
|
||||
* <p>
|
||||
* The returned list maintains the values, but not the identities, of
|
||||
* {@code Long} objects written to or read from it. For example, whether
|
||||
* {@code list.get(0) == list.get(0)} is true for the returned list is
|
||||
* unspecified.
|
||||
*
|
||||
* @param backingArray the array to back the list
|
||||
* @return a list view of the array
|
||||
*/
|
||||
public static List<Long> asList(long... backingArray) {
|
||||
if (backingArray.length == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return new LongArrayAsList(backingArray);
|
||||
}
|
||||
|
||||
@GwtCompatible
|
||||
private static class LongArrayAsList extends AbstractList<Long> implements RandomAccess, Serializable {
|
||||
final long[] array;
|
||||
final int start;
|
||||
final int end;
|
||||
|
||||
LongArrayAsList(long[] array) {
|
||||
this(array, 0, array.length);
|
||||
}
|
||||
|
||||
LongArrayAsList(long[] array, int start, int end) {
|
||||
this.array = array;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return end - start;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long get(int index) {
|
||||
checkElementIndex(index, size());
|
||||
return array[start + index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
return (target instanceof Long) && Longs.indexOf(array, (Long) target, start, end) != -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
if (target instanceof Long) {
|
||||
int i = Longs.indexOf(array, (Long) target, start, end);
|
||||
if (i >= 0) {
|
||||
return i - start;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lastIndexOf(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
if (target instanceof Long) {
|
||||
int i = Longs.lastIndexOf(array, (Long) target, start, end);
|
||||
if (i >= 0) {
|
||||
return i - start;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long set(int index, Long element) {
|
||||
checkElementIndex(index, size());
|
||||
long oldValue = array[start + index];
|
||||
// checkNotNull for GWT (do not optimize)
|
||||
array[start + index] = checkNotNull(element);
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> subList(int fromIndex, int toIndex) {
|
||||
int size = size();
|
||||
checkPositionIndexes(fromIndex, toIndex, size);
|
||||
if (fromIndex == toIndex) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return new LongArrayAsList(array, start + fromIndex, start + toIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object == this) {
|
||||
return true;
|
||||
}
|
||||
if (object instanceof LongArrayAsList) {
|
||||
LongArrayAsList that = (LongArrayAsList) object;
|
||||
int size = size();
|
||||
if (that.size() != size) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (array[start + i] != that.array[that.start + i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return super.equals(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
for (int i = start; i < end; i++) {
|
||||
result = 31 * result + Longs.hashCode(array[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder(size() * 10);
|
||||
builder.append('[').append(array[start]);
|
||||
for (int i = start + 1; i < end; i++) {
|
||||
builder.append(", ").append(array[i]);
|
||||
}
|
||||
return builder.append(']').toString();
|
||||
}
|
||||
|
||||
long[] toLongArray() {
|
||||
// Arrays.copyOfRange() is not available under GWT
|
||||
int size = size();
|
||||
long[] result = new long[size];
|
||||
System.arraycopy(array, start, result, 0, size);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0;
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.common.primitives;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
|
||||
/**
|
||||
* A string to be parsed as a number and the radix to interpret it in.
|
||||
*/
|
||||
@GwtCompatible
|
||||
final class ParseRequest {
|
||||
final String rawValue;
|
||||
final int radix;
|
||||
|
||||
private ParseRequest(String rawValue, int radix) {
|
||||
this.rawValue = rawValue;
|
||||
this.radix = radix;
|
||||
}
|
||||
|
||||
static ParseRequest fromString(String stringValue) {
|
||||
if (stringValue.length() == 0) {
|
||||
throw new NumberFormatException("empty string");
|
||||
}
|
||||
|
||||
// Handle radix specifier if present
|
||||
String rawValue;
|
||||
int radix;
|
||||
char firstChar = stringValue.charAt(0);
|
||||
if (stringValue.startsWith("0x") || stringValue.startsWith("0X")) {
|
||||
rawValue = stringValue.substring(2);
|
||||
radix = 16;
|
||||
} else if (firstChar == '#') {
|
||||
rawValue = stringValue.substring(1);
|
||||
radix = 16;
|
||||
} else if (firstChar == '0' && stringValue.length() > 1) {
|
||||
rawValue = stringValue.substring(1);
|
||||
radix = 8;
|
||||
} else {
|
||||
rawValue = stringValue;
|
||||
radix = 10;
|
||||
}
|
||||
|
||||
return new ParseRequest(rawValue, radix);
|
||||
}
|
||||
}
|
137
sources/main/java/com/google/common/primitives/Primitives.java
Normal file
137
sources/main/java/com/google/common/primitives/Primitives.java
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.common.primitives;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Contains static utility methods pertaining to primitive types and their
|
||||
* corresponding wrapper types.
|
||||
*
|
||||
* @author Kevin Bourrillion
|
||||
* @since 1.0
|
||||
*/
|
||||
public final class Primitives {
|
||||
private Primitives() {
|
||||
}
|
||||
|
||||
/** A map from primitive types to their corresponding wrapper types. */
|
||||
private static final Map<Class<?>, Class<?>> PRIMITIVE_TO_WRAPPER_TYPE;
|
||||
|
||||
/** A map from wrapper types to their corresponding primitive types. */
|
||||
private static final Map<Class<?>, Class<?>> WRAPPER_TO_PRIMITIVE_TYPE;
|
||||
|
||||
// Sad that we can't use a BiMap. :(
|
||||
|
||||
static {
|
||||
Map<Class<?>, Class<?>> primToWrap = new HashMap<Class<?>, Class<?>>(16);
|
||||
Map<Class<?>, Class<?>> wrapToPrim = new HashMap<Class<?>, Class<?>>(16);
|
||||
|
||||
add(primToWrap, wrapToPrim, boolean.class, Boolean.class);
|
||||
add(primToWrap, wrapToPrim, byte.class, Byte.class);
|
||||
add(primToWrap, wrapToPrim, char.class, Character.class);
|
||||
add(primToWrap, wrapToPrim, double.class, Double.class);
|
||||
add(primToWrap, wrapToPrim, float.class, Float.class);
|
||||
add(primToWrap, wrapToPrim, int.class, Integer.class);
|
||||
add(primToWrap, wrapToPrim, long.class, Long.class);
|
||||
add(primToWrap, wrapToPrim, short.class, Short.class);
|
||||
add(primToWrap, wrapToPrim, void.class, Void.class);
|
||||
|
||||
PRIMITIVE_TO_WRAPPER_TYPE = Collections.unmodifiableMap(primToWrap);
|
||||
WRAPPER_TO_PRIMITIVE_TYPE = Collections.unmodifiableMap(wrapToPrim);
|
||||
}
|
||||
|
||||
private static void add(Map<Class<?>, Class<?>> forward, Map<Class<?>, Class<?>> backward, Class<?> key,
|
||||
Class<?> value) {
|
||||
forward.put(key, value);
|
||||
backward.put(value, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable set of all nine primitive types (including {@code
|
||||
* void}). Note that a simpler way to test whether a {@code Class} instance is a
|
||||
* member of this set is to call {@link Class#isPrimitive}.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
public static Set<Class<?>> allPrimitiveTypes() {
|
||||
return PRIMITIVE_TO_WRAPPER_TYPE.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable set of all nine primitive-wrapper types (including
|
||||
* {@link Void}).
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
public static Set<Class<?>> allWrapperTypes() {
|
||||
return WRAPPER_TO_PRIMITIVE_TYPE.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if {@code type} is one of the nine primitive-wrapper
|
||||
* types, such as {@link Integer}.
|
||||
*
|
||||
* @see Class#isPrimitive
|
||||
*/
|
||||
public static boolean isWrapperType(Class<?> type) {
|
||||
return WRAPPER_TO_PRIMITIVE_TYPE.containsKey(checkNotNull(type));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the corresponding wrapper type of {@code type} if it is a primitive
|
||||
* type; otherwise returns {@code type} itself. Idempotent.
|
||||
*
|
||||
* <pre>
|
||||
* wrap(int.class) == Integer.class
|
||||
* wrap(Integer.class) == Integer.class
|
||||
* wrap(String.class) == String.class
|
||||
* </pre>
|
||||
*/
|
||||
public static <T> Class<T> wrap(Class<T> type) {
|
||||
checkNotNull(type);
|
||||
|
||||
// cast is safe: long.class and Long.class are both of type Class<Long>
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<T> wrapped = (Class<T>) PRIMITIVE_TO_WRAPPER_TYPE.get(type);
|
||||
return (wrapped == null) ? type : wrapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the corresponding primitive type of {@code type} if it is a wrapper
|
||||
* type; otherwise returns {@code type} itself. Idempotent.
|
||||
*
|
||||
* <pre>
|
||||
* unwrap(Integer.class) == int.class
|
||||
* unwrap(int.class) == int.class
|
||||
* unwrap(String.class) == String.class
|
||||
* </pre>
|
||||
*/
|
||||
public static <T> Class<T> unwrap(Class<T> type) {
|
||||
checkNotNull(type);
|
||||
|
||||
// cast is safe: long.class and Long.class are both of type Class<Long>
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<T> unwrapped = (Class<T>) WRAPPER_TO_PRIMITIVE_TYPE.get(type);
|
||||
return (unwrapped == null) ? type : unwrapped;
|
||||
}
|
||||
}
|
644
sources/main/java/com/google/common/primitives/Shorts.java
Normal file
644
sources/main/java/com/google/common/primitives/Shorts.java
Normal file
@ -0,0 +1,644 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.common.primitives;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkElementIndex;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkPositionIndexes;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.AbstractList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.RandomAccess;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
import com.google.common.annotations.GwtIncompatible;
|
||||
import com.google.common.base.Converter;
|
||||
|
||||
/**
|
||||
* Static utility methods pertaining to {@code short} primitives, that are not
|
||||
* already found in either {@link Short} or {@link Arrays}.
|
||||
*
|
||||
* <p>
|
||||
* See the Guava User Guide article on
|
||||
* <a href= "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained">
|
||||
* primitive utilities</a>.
|
||||
*
|
||||
* @author Kevin Bourrillion
|
||||
* @since 1.0
|
||||
*/
|
||||
@GwtCompatible(emulated = true)
|
||||
public final class Shorts {
|
||||
private Shorts() {
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of bytes required to represent a primitive {@code short} value.
|
||||
*/
|
||||
public static final int BYTES = Short.SIZE / Byte.SIZE;
|
||||
|
||||
/**
|
||||
* The largest power of two that can be represented as a {@code short}.
|
||||
*
|
||||
* @since 10.0
|
||||
*/
|
||||
public static final short MAX_POWER_OF_TWO = 1 << (Short.SIZE - 2);
|
||||
|
||||
/**
|
||||
* Returns a hash code for {@code value}; equal to the result of invoking
|
||||
* {@code ((Short) value).hashCode()}.
|
||||
*
|
||||
* @param value a primitive {@code short} value
|
||||
* @return a hash code for the value
|
||||
*/
|
||||
public static int hashCode(short value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code short} value that is equal to {@code value}, if possible.
|
||||
*
|
||||
* @param value any value in the range of the {@code short} type
|
||||
* @return the {@code short} value that equals {@code value}
|
||||
* @throws IllegalArgumentException if {@code value} is greater than
|
||||
* {@link Short#MAX_VALUE} or less than
|
||||
* {@link Short#MIN_VALUE}
|
||||
*/
|
||||
public static short checkedCast(long value) {
|
||||
short result = (short) value;
|
||||
if (result != value) {
|
||||
// don't use checkArgument here, to avoid boxing
|
||||
throw new IllegalArgumentException("Out of range: " + value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code short} nearest in value to {@code value}.
|
||||
*
|
||||
* @param value any {@code long} value
|
||||
* @return the same value cast to {@code short} if it is in the range of the
|
||||
* {@code short} type, {@link Short#MAX_VALUE} if it is too large, or
|
||||
* {@link Short#MIN_VALUE} if it is too small
|
||||
*/
|
||||
public static short saturatedCast(long value) {
|
||||
if (value > Short.MAX_VALUE) {
|
||||
return Short.MAX_VALUE;
|
||||
}
|
||||
if (value < Short.MIN_VALUE) {
|
||||
return Short.MIN_VALUE;
|
||||
}
|
||||
return (short) value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the two specified {@code short} values. The sign of the value
|
||||
* returned is the same as that of {@code ((Short) a).compareTo(b)}.
|
||||
*
|
||||
* <p>
|
||||
* <b>Note:</b> projects using JDK 7 or later should use the equivalent
|
||||
* {@link Short#compare} method instead.
|
||||
*
|
||||
* @param a the first {@code short} to compare
|
||||
* @param b the second {@code short} to compare
|
||||
* @return a negative value if {@code a} is less than {@code b}; a positive
|
||||
* value if {@code a} is greater than {@code b}; or zero if they are
|
||||
* equal
|
||||
*/
|
||||
public static int compare(short a, short b) {
|
||||
return a - b; // safe due to restricted range
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if {@code target} is present as an element anywhere in
|
||||
* {@code array}.
|
||||
*
|
||||
* @param array an array of {@code short} values, possibly empty
|
||||
* @param target a primitive {@code short} value
|
||||
* @return {@code true} if {@code array[i] == target} for some value of {@code
|
||||
* i}
|
||||
*/
|
||||
public static boolean contains(short[] array, short target) {
|
||||
for (short value : array) {
|
||||
if (value == target) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the first appearance of the value {@code target} in
|
||||
* {@code array}.
|
||||
*
|
||||
* @param array an array of {@code short} values, possibly empty
|
||||
* @param target a primitive {@code short} value
|
||||
* @return the least index {@code i} for which {@code array[i] == target}, or
|
||||
* {@code -1} if no such index exists.
|
||||
*/
|
||||
public static int indexOf(short[] array, short target) {
|
||||
return indexOf(array, target, 0, array.length);
|
||||
}
|
||||
|
||||
// TODO(kevinb): consider making this public
|
||||
private static int indexOf(short[] array, short target, int start, int end) {
|
||||
for (int i = start; i < end; i++) {
|
||||
if (array[i] == target) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the start position of the first occurrence of the specified {@code
|
||||
* target} within {@code array}, or {@code -1} if there is no such occurrence.
|
||||
*
|
||||
* <p>
|
||||
* More formally, returns the lowest index {@code i} such that {@code
|
||||
* java.util.Arrays.copyOfRange(array, i, i + target.length)} contains exactly
|
||||
* the same elements as {@code target}.
|
||||
*
|
||||
* @param array the array to search for the sequence {@code target}
|
||||
* @param target the array to search for as a sub-sequence of {@code array}
|
||||
*/
|
||||
public static int indexOf(short[] array, short[] target) {
|
||||
checkNotNull(array, "array");
|
||||
checkNotNull(target, "target");
|
||||
if (target.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
outer: for (int i = 0; i < array.length - target.length + 1; i++) {
|
||||
for (int j = 0; j < target.length; j++) {
|
||||
if (array[i + j] != target[j]) {
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the last appearance of the value {@code target} in
|
||||
* {@code array}.
|
||||
*
|
||||
* @param array an array of {@code short} values, possibly empty
|
||||
* @param target a primitive {@code short} value
|
||||
* @return the greatest index {@code i} for which {@code array[i] == target}, or
|
||||
* {@code -1} if no such index exists.
|
||||
*/
|
||||
public static int lastIndexOf(short[] array, short target) {
|
||||
return lastIndexOf(array, target, 0, array.length);
|
||||
}
|
||||
|
||||
// TODO(kevinb): consider making this public
|
||||
private static int lastIndexOf(short[] array, short target, int start, int end) {
|
||||
for (int i = end - 1; i >= start; i--) {
|
||||
if (array[i] == target) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the least value present in {@code array}.
|
||||
*
|
||||
* @param array a <i>nonempty</i> array of {@code short} values
|
||||
* @return the value present in {@code array} that is less than or equal to
|
||||
* every other value in the array
|
||||
* @throws IllegalArgumentException if {@code array} is empty
|
||||
*/
|
||||
public static short min(short... array) {
|
||||
checkArgument(array.length > 0);
|
||||
short min = array[0];
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
if (array[i] < min) {
|
||||
min = array[i];
|
||||
}
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the greatest value present in {@code array}.
|
||||
*
|
||||
* @param array a <i>nonempty</i> array of {@code short} values
|
||||
* @return the value present in {@code array} that is greater than or equal to
|
||||
* every other value in the array
|
||||
* @throws IllegalArgumentException if {@code array} is empty
|
||||
*/
|
||||
public static short max(short... array) {
|
||||
checkArgument(array.length > 0);
|
||||
short max = array[0];
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
if (array[i] > max) {
|
||||
max = array[i];
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the values from each provided array combined into a single array. For
|
||||
* example, {@code concat(new short[] {a, b}, new short[] {}, new short[] {c}}
|
||||
* returns the array {@code {a, b, c}}.
|
||||
*
|
||||
* @param arrays zero or more {@code short} arrays
|
||||
* @return a single array containing all the values from the source arrays, in
|
||||
* order
|
||||
*/
|
||||
public static short[] concat(short[]... arrays) {
|
||||
int length = 0;
|
||||
for (short[] array : arrays) {
|
||||
length += array.length;
|
||||
}
|
||||
short[] result = new short[length];
|
||||
int pos = 0;
|
||||
for (short[] array : arrays) {
|
||||
System.arraycopy(array, 0, result, pos, array.length);
|
||||
pos += array.length;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a big-endian representation of {@code value} in a 2-element byte
|
||||
* array; equivalent to {@code
|
||||
* ByteBuffer.allocate(2).putShort(value).array()}. For example, the input value
|
||||
* {@code (short) 0x1234} would yield the byte array {@code {0x12, 0x34}}.
|
||||
*
|
||||
* <p>
|
||||
* If you need to convert and concatenate several values (possibly even of
|
||||
* different types), use a shared {@link java.nio.ByteBuffer} instance, or use
|
||||
* {@link com.google.common.io.ByteStreams#newDataOutput()} to get a growable
|
||||
* buffer.
|
||||
*/
|
||||
@GwtIncompatible("doesn't work")
|
||||
public static byte[] toByteArray(short value) {
|
||||
return new byte[] { (byte) (value >> 8), (byte) value };
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code short} value whose big-endian representation is stored in
|
||||
* the first 2 bytes of {@code bytes}; equivalent to {@code
|
||||
* ByteBuffer.wrap(bytes).getShort()}. For example, the input byte array
|
||||
* {@code {0x54, 0x32}} would yield the {@code short} value {@code 0x5432}.
|
||||
*
|
||||
* <p>
|
||||
* Arguably, it's preferable to use {@link java.nio.ByteBuffer}; that library
|
||||
* exposes much more flexibility at little cost in readability.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code bytes} has fewer than 2 elements
|
||||
*/
|
||||
@GwtIncompatible("doesn't work")
|
||||
public static short fromByteArray(byte[] bytes) {
|
||||
checkArgument(bytes.length >= BYTES, "array too small: %s < %s", bytes.length, BYTES);
|
||||
return fromBytes(bytes[0], bytes[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code short} value whose byte representation is the given 2
|
||||
* bytes, in big-endian order; equivalent to {@code Shorts.fromByteArray(new
|
||||
* byte[] {b1, b2})}.
|
||||
*
|
||||
* @since 7.0
|
||||
*/
|
||||
@GwtIncompatible("doesn't work")
|
||||
public static short fromBytes(byte b1, byte b2) {
|
||||
return (short) ((b1 << 8) | (b2 & 0xFF));
|
||||
}
|
||||
|
||||
private static final class ShortConverter extends Converter<String, Short> implements Serializable {
|
||||
static final ShortConverter INSTANCE = new ShortConverter();
|
||||
|
||||
@Override
|
||||
protected Short doForward(String value) {
|
||||
return Short.decode(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doBackward(Short value) {
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Shorts.stringConverter()";
|
||||
}
|
||||
|
||||
private Object readResolve() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a serializable converter object that converts between strings and
|
||||
* shorts using {@link Short#decode} and {@link Short#toString()}.
|
||||
*
|
||||
* @since 16.0
|
||||
*/
|
||||
@Beta
|
||||
public static Converter<String, Short> stringConverter() {
|
||||
return ShortConverter.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing the same values as {@code array}, but guaranteed
|
||||
* to be of a specified minimum length. If {@code array} already has a length of
|
||||
* at least {@code minLength}, it is returned directly. Otherwise, a new array
|
||||
* of size {@code minLength + padding} is returned, containing the values of
|
||||
* {@code array}, and zeroes in the remaining places.
|
||||
*
|
||||
* @param array the source array
|
||||
* @param minLength the minimum length the returned array must guarantee
|
||||
* @param padding an extra amount to "grow" the array by if growth is
|
||||
* necessary
|
||||
* @throws IllegalArgumentException if {@code minLength} or {@code padding} is
|
||||
* negative
|
||||
* @return an array containing the values of {@code array}, with guaranteed
|
||||
* minimum length {@code minLength}
|
||||
*/
|
||||
public static short[] ensureCapacity(short[] array, int minLength, int padding) {
|
||||
checkArgument(minLength >= 0, "Invalid minLength: %s", minLength);
|
||||
checkArgument(padding >= 0, "Invalid padding: %s", padding);
|
||||
return (array.length < minLength) ? copyOf(array, minLength + padding) : array;
|
||||
}
|
||||
|
||||
// Arrays.copyOf() requires Java 6
|
||||
private static short[] copyOf(short[] original, int length) {
|
||||
short[] copy = new short[length];
|
||||
System.arraycopy(original, 0, copy, 0, Math.min(original.length, length));
|
||||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string containing the supplied {@code short} values separated by
|
||||
* {@code separator}. For example, {@code join("-", (short) 1, (short) 2,
|
||||
* (short) 3)} returns the string {@code "1-2-3"}.
|
||||
*
|
||||
* @param separator the text that should appear between consecutive values in
|
||||
* the resulting string (but not at the start or end)
|
||||
* @param array an array of {@code short} values, possibly empty
|
||||
*/
|
||||
public static String join(String separator, short... array) {
|
||||
checkNotNull(separator);
|
||||
if (array.length == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// For pre-sizing a builder, just get the right order of magnitude
|
||||
StringBuilder builder = new StringBuilder(array.length * 6);
|
||||
builder.append(array[0]);
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
builder.append(separator).append(array[i]);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a comparator that compares two {@code short} arrays
|
||||
* lexicographically. That is, it compares, using
|
||||
* {@link #compare(short, short)}), the first pair of values that follow any
|
||||
* common prefix, or when one array is a prefix of the other, treats the shorter
|
||||
* array as the lesser. For example, {@code [] < [(short) 1] <
|
||||
* [(short) 1, (short) 2] < [(short) 2]}.
|
||||
*
|
||||
* <p>
|
||||
* The returned comparator is inconsistent with {@link Object#equals(Object)}
|
||||
* (since arrays support only identity equality), but it is consistent with
|
||||
* {@link Arrays#equals(short[], short[])}.
|
||||
*
|
||||
* @see <a href="http://en.wikipedia.org/wiki/Lexicographical_order">
|
||||
* Lexicographical order article at Wikipedia</a>
|
||||
* @since 2.0
|
||||
*/
|
||||
public static Comparator<short[]> lexicographicalComparator() {
|
||||
return LexicographicalComparator.INSTANCE;
|
||||
}
|
||||
|
||||
private enum LexicographicalComparator implements Comparator<short[]> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public int compare(short[] left, short[] right) {
|
||||
int minLength = Math.min(left.length, right.length);
|
||||
for (int i = 0; i < minLength; i++) {
|
||||
int result = Shorts.compare(left[i], right[i]);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return left.length - right.length;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing each value of {@code collection}, converted to a
|
||||
* {@code short} value in the manner of {@link Number#shortValue}.
|
||||
*
|
||||
* <p>
|
||||
* Elements are copied from the argument collection as if by {@code
|
||||
* collection.toArray()}. Calling this method is as thread-safe as calling that
|
||||
* method.
|
||||
*
|
||||
* @param collection a collection of {@code Number} instances
|
||||
* @return an array containing the same values as {@code collection}, in the
|
||||
* same order, converted to primitives
|
||||
* @throws NullPointerException if {@code collection} or any of its elements is
|
||||
* null
|
||||
* @since 1.0 (parameter was {@code Collection<Short>} before 12.0)
|
||||
*/
|
||||
public static short[] toArray(Collection<? extends Number> collection) {
|
||||
if (collection instanceof ShortArrayAsList) {
|
||||
return ((ShortArrayAsList) collection).toShortArray();
|
||||
}
|
||||
|
||||
Object[] boxedArray = collection.toArray();
|
||||
int len = boxedArray.length;
|
||||
short[] array = new short[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
// checkNotNull for GWT (do not optimize)
|
||||
array[i] = ((Number) checkNotNull(boxedArray[i])).shortValue();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a fixed-size list backed by the specified array, similar to
|
||||
* {@link Arrays#asList(Object[])}. The list supports
|
||||
* {@link List#set(int, Object)}, but any attempt to set a value to {@code null}
|
||||
* will result in a {@link NullPointerException}.
|
||||
*
|
||||
* <p>
|
||||
* The returned list maintains the values, but not the identities, of
|
||||
* {@code Short} objects written to or read from it. For example, whether
|
||||
* {@code list.get(0) == list.get(0)} is true for the returned list is
|
||||
* unspecified.
|
||||
*
|
||||
* @param backingArray the array to back the list
|
||||
* @return a list view of the array
|
||||
*/
|
||||
public static List<Short> asList(short... backingArray) {
|
||||
if (backingArray.length == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return new ShortArrayAsList(backingArray);
|
||||
}
|
||||
|
||||
@GwtCompatible
|
||||
private static class ShortArrayAsList extends AbstractList<Short> implements RandomAccess, Serializable {
|
||||
final short[] array;
|
||||
final int start;
|
||||
final int end;
|
||||
|
||||
ShortArrayAsList(short[] array) {
|
||||
this(array, 0, array.length);
|
||||
}
|
||||
|
||||
ShortArrayAsList(short[] array, int start, int end) {
|
||||
this.array = array;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return end - start;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Short get(int index) {
|
||||
checkElementIndex(index, size());
|
||||
return array[start + index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
return (target instanceof Short) && Shorts.indexOf(array, (Short) target, start, end) != -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
if (target instanceof Short) {
|
||||
int i = Shorts.indexOf(array, (Short) target, start, end);
|
||||
if (i >= 0) {
|
||||
return i - start;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lastIndexOf(Object target) {
|
||||
// Overridden to prevent a ton of boxing
|
||||
if (target instanceof Short) {
|
||||
int i = Shorts.lastIndexOf(array, (Short) target, start, end);
|
||||
if (i >= 0) {
|
||||
return i - start;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Short set(int index, Short element) {
|
||||
checkElementIndex(index, size());
|
||||
short oldValue = array[start + index];
|
||||
// checkNotNull for GWT (do not optimize)
|
||||
array[start + index] = checkNotNull(element);
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Short> subList(int fromIndex, int toIndex) {
|
||||
int size = size();
|
||||
checkPositionIndexes(fromIndex, toIndex, size);
|
||||
if (fromIndex == toIndex) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return new ShortArrayAsList(array, start + fromIndex, start + toIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object == this) {
|
||||
return true;
|
||||
}
|
||||
if (object instanceof ShortArrayAsList) {
|
||||
ShortArrayAsList that = (ShortArrayAsList) object;
|
||||
int size = size();
|
||||
if (that.size() != size) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (array[start + i] != that.array[that.start + i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return super.equals(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
for (int i = start; i < end; i++) {
|
||||
result = 31 * result + Shorts.hashCode(array[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder(size() * 6);
|
||||
builder.append('[').append(array[start]);
|
||||
for (int i = start + 1; i < end; i++) {
|
||||
builder.append(", ").append(array[i]);
|
||||
}
|
||||
return builder.append(']').toString();
|
||||
}
|
||||
|
||||
short[] toShortArray() {
|
||||
// Arrays.copyOfRange() is not available under GWT
|
||||
int size = size();
|
||||
short[] result = new short[size];
|
||||
System.arraycopy(array, start, result, 0, size);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0;
|
||||
}
|
||||
}
|
208
sources/main/java/com/google/common/primitives/SignedBytes.java
Normal file
208
sources/main/java/com/google/common/primitives/SignedBytes.java
Normal file
@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (C) 2009 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.common.primitives;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
|
||||
/**
|
||||
* Static utility methods pertaining to {@code byte} primitives that interpret
|
||||
* values as signed. The corresponding methods that treat the values as unsigned
|
||||
* are found in {@link UnsignedBytes}, and the methods for which signedness is
|
||||
* not an issue are in {@link Bytes}.
|
||||
*
|
||||
* <p>
|
||||
* See the Guava User Guide article on
|
||||
* <a href= "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained">
|
||||
* primitive utilities</a>.
|
||||
*
|
||||
* @author Kevin Bourrillion
|
||||
* @since 1.0
|
||||
*/
|
||||
// TODO(kevinb): how to prevent warning on UnsignedBytes when building GWT
|
||||
// javadoc?
|
||||
@GwtCompatible
|
||||
public final class SignedBytes {
|
||||
private SignedBytes() {
|
||||
}
|
||||
|
||||
/**
|
||||
* The largest power of two that can be represented as a signed {@code byte}.
|
||||
*
|
||||
* @since 10.0
|
||||
*/
|
||||
public static final byte MAX_POWER_OF_TWO = 1 << 6;
|
||||
|
||||
/**
|
||||
* Returns the {@code byte} value that is equal to {@code value}, if possible.
|
||||
*
|
||||
* @param value any value in the range of the {@code byte} type
|
||||
* @return the {@code byte} value that equals {@code value}
|
||||
* @throws IllegalArgumentException if {@code value} is greater than
|
||||
* {@link Byte#MAX_VALUE} or less than
|
||||
* {@link Byte#MIN_VALUE}
|
||||
*/
|
||||
public static byte checkedCast(long value) {
|
||||
byte result = (byte) value;
|
||||
if (result != value) {
|
||||
// don't use checkArgument here, to avoid boxing
|
||||
throw new IllegalArgumentException("Out of range: " + value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code byte} nearest in value to {@code value}.
|
||||
*
|
||||
* @param value any {@code long} value
|
||||
* @return the same value cast to {@code byte} if it is in the range of the
|
||||
* {@code byte} type, {@link Byte#MAX_VALUE} if it is too large, or
|
||||
* {@link Byte#MIN_VALUE} if it is too small
|
||||
*/
|
||||
public static byte saturatedCast(long value) {
|
||||
if (value > Byte.MAX_VALUE) {
|
||||
return Byte.MAX_VALUE;
|
||||
}
|
||||
if (value < Byte.MIN_VALUE) {
|
||||
return Byte.MIN_VALUE;
|
||||
}
|
||||
return (byte) value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the two specified {@code byte} values. The sign of the value
|
||||
* returned is the same as that of {@code ((Byte) a).compareTo(b)}.
|
||||
*
|
||||
* <p>
|
||||
* <b>Note:</b> this method behaves identically to the JDK 7 method
|
||||
* {@link Byte#compare}.
|
||||
*
|
||||
* @param a the first {@code byte} to compare
|
||||
* @param b the second {@code byte} to compare
|
||||
* @return a negative value if {@code a} is less than {@code b}; a positive
|
||||
* value if {@code a} is greater than {@code b}; or zero if they are
|
||||
* equal
|
||||
*/
|
||||
// TODO(kevinb): if Ints.compare etc. are ever removed, *maybe* remove this
|
||||
// one too, which would leave compare methods only on the Unsigned* classes.
|
||||
public static int compare(byte a, byte b) {
|
||||
return a - b; // safe due to restricted range
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the least value present in {@code array}.
|
||||
*
|
||||
* @param array a <i>nonempty</i> array of {@code byte} values
|
||||
* @return the value present in {@code array} that is less than or equal to
|
||||
* every other value in the array
|
||||
* @throws IllegalArgumentException if {@code array} is empty
|
||||
*/
|
||||
public static byte min(byte... array) {
|
||||
checkArgument(array.length > 0);
|
||||
byte min = array[0];
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
if (array[i] < min) {
|
||||
min = array[i];
|
||||
}
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the greatest value present in {@code array}.
|
||||
*
|
||||
* @param array a <i>nonempty</i> array of {@code byte} values
|
||||
* @return the value present in {@code array} that is greater than or equal to
|
||||
* every other value in the array
|
||||
* @throws IllegalArgumentException if {@code array} is empty
|
||||
*/
|
||||
public static byte max(byte... array) {
|
||||
checkArgument(array.length > 0);
|
||||
byte max = array[0];
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
if (array[i] > max) {
|
||||
max = array[i];
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string containing the supplied {@code byte} values separated by
|
||||
* {@code separator}. For example, {@code join(":", 0x01, 0x02, -0x01)} returns
|
||||
* the string {@code "1:2:-1"}.
|
||||
*
|
||||
* @param separator the text that should appear between consecutive values in
|
||||
* the resulting string (but not at the start or end)
|
||||
* @param array an array of {@code byte} values, possibly empty
|
||||
*/
|
||||
public static String join(String separator, byte... array) {
|
||||
checkNotNull(separator);
|
||||
if (array.length == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// For pre-sizing a builder, just get the right order of magnitude
|
||||
StringBuilder builder = new StringBuilder(array.length * 5);
|
||||
builder.append(array[0]);
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
builder.append(separator).append(array[i]);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a comparator that compares two {@code byte} arrays lexicographically.
|
||||
* That is, it compares, using {@link #compare(byte, byte)}), the first pair of
|
||||
* values that follow any common prefix, or when one array is a prefix of the
|
||||
* other, treats the shorter array as the lesser. For example,
|
||||
* {@code [] < [0x01] < [0x01, 0x80] <
|
||||
* [0x01, 0x7F] < [0x02]}. Values are treated as signed.
|
||||
*
|
||||
* <p>
|
||||
* The returned comparator is inconsistent with {@link Object#equals(Object)}
|
||||
* (since arrays support only identity equality), but it is consistent with
|
||||
* {@link java.util.Arrays#equals(byte[], byte[])}.
|
||||
*
|
||||
* @see <a href="http://en.wikipedia.org/wiki/Lexicographical_order">
|
||||
* Lexicographical order article at Wikipedia</a>
|
||||
* @since 2.0
|
||||
*/
|
||||
public static Comparator<byte[]> lexicographicalComparator() {
|
||||
return LexicographicalComparator.INSTANCE;
|
||||
}
|
||||
|
||||
private enum LexicographicalComparator implements Comparator<byte[]> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public int compare(byte[] left, byte[] right) {
|
||||
int minLength = Math.min(left.length, right.length);
|
||||
for (int i = 0; i < minLength; i++) {
|
||||
int result = SignedBytes.compare(left[i], right[i]);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return left.length - right.length;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,262 @@
|
||||
/*
|
||||
* Copyright (C) 2009 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.common.primitives;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
|
||||
/**
|
||||
* Static utility methods pertaining to {@code byte} primitives that interpret
|
||||
* values as <i>unsigned</i> (that is, any negative value {@code b} is treated
|
||||
* as the positive value {@code 256 + b}). The corresponding methods that treat
|
||||
* the values as signed are found in {@link SignedBytes}, and the methods for
|
||||
* which signedness is not an issue are in {@link Bytes}.
|
||||
*
|
||||
* <p>
|
||||
* See the Guava User Guide article on
|
||||
* <a href= "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained">
|
||||
* primitive utilities</a>.
|
||||
*
|
||||
* @author Kevin Bourrillion
|
||||
* @author Martin Buchholz
|
||||
* @author Hiroshi Yamauchi
|
||||
* @author Louis Wasserman
|
||||
* @since 1.0
|
||||
*/
|
||||
public final class UnsignedBytes {
|
||||
private UnsignedBytes() {
|
||||
}
|
||||
|
||||
/**
|
||||
* The largest power of two that can be represented as an unsigned {@code
|
||||
* byte}.
|
||||
*
|
||||
* @since 10.0
|
||||
*/
|
||||
public static final byte MAX_POWER_OF_TWO = (byte) 0x80;
|
||||
|
||||
/**
|
||||
* The largest value that fits into an unsigned byte.
|
||||
*
|
||||
* @since 13.0
|
||||
*/
|
||||
public static final byte MAX_VALUE = (byte) 0xFF;
|
||||
|
||||
private static final int UNSIGNED_MASK = 0xFF;
|
||||
|
||||
/**
|
||||
* Returns the value of the given byte as an integer, when treated as unsigned.
|
||||
* That is, returns {@code value + 256} if {@code value} is negative;
|
||||
* {@code value} itself otherwise.
|
||||
*
|
||||
* @since 6.0
|
||||
*/
|
||||
public static int toInt(byte value) {
|
||||
return value & UNSIGNED_MASK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code byte} value that, when treated as unsigned, is equal to
|
||||
* {@code value}, if possible.
|
||||
*
|
||||
* @param value a value between 0 and 255 inclusive
|
||||
* @return the {@code byte} value that, when treated as unsigned, equals
|
||||
* {@code value}
|
||||
* @throws IllegalArgumentException if {@code value} is negative or greater than
|
||||
* 255
|
||||
*/
|
||||
public static byte checkedCast(long value) {
|
||||
if ((value >> Byte.SIZE) != 0) {
|
||||
// don't use checkArgument here, to avoid boxing
|
||||
throw new IllegalArgumentException("Out of range: " + value);
|
||||
}
|
||||
return (byte) value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code byte} value that, when treated as unsigned, is nearest in
|
||||
* value to {@code value}.
|
||||
*
|
||||
* @param value any {@code long} value
|
||||
* @return {@code (byte) 255} if {@code value >= 255}, {@code (byte) 0} if
|
||||
* {@code value <= 0}, and {@code value} cast to {@code byte} otherwise
|
||||
*/
|
||||
public static byte saturatedCast(long value) {
|
||||
if (value > toInt(MAX_VALUE)) {
|
||||
return MAX_VALUE; // -1
|
||||
}
|
||||
if (value < 0) {
|
||||
return (byte) 0;
|
||||
}
|
||||
return (byte) value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the two specified {@code byte} values, treating them as unsigned
|
||||
* values between 0 and 255 inclusive. For example, {@code (byte) -127} is
|
||||
* considered greater than {@code (byte) 127} because it is seen as having the
|
||||
* value of positive {@code 129}.
|
||||
*
|
||||
* @param a the first {@code byte} to compare
|
||||
* @param b the second {@code byte} to compare
|
||||
* @return a negative value if {@code a} is less than {@code b}; a positive
|
||||
* value if {@code a} is greater than {@code b}; or zero if they are
|
||||
* equal
|
||||
*/
|
||||
public static int compare(byte a, byte b) {
|
||||
return toInt(a) - toInt(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the least value present in {@code array}.
|
||||
*
|
||||
* @param array a <i>nonempty</i> array of {@code byte} values
|
||||
* @return the value present in {@code array} that is less than or equal to
|
||||
* every other value in the array
|
||||
* @throws IllegalArgumentException if {@code array} is empty
|
||||
*/
|
||||
public static byte min(byte... array) {
|
||||
checkArgument(array.length > 0);
|
||||
int min = toInt(array[0]);
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
int next = toInt(array[i]);
|
||||
if (next < min) {
|
||||
min = next;
|
||||
}
|
||||
}
|
||||
return (byte) min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the greatest value present in {@code array}.
|
||||
*
|
||||
* @param array a <i>nonempty</i> array of {@code byte} values
|
||||
* @return the value present in {@code array} that is greater than or equal to
|
||||
* every other value in the array
|
||||
* @throws IllegalArgumentException if {@code array} is empty
|
||||
*/
|
||||
public static byte max(byte... array) {
|
||||
checkArgument(array.length > 0);
|
||||
int max = toInt(array[0]);
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
int next = toInt(array[i]);
|
||||
if (next > max) {
|
||||
max = next;
|
||||
}
|
||||
}
|
||||
return (byte) max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of x, where x is treated as unsigned.
|
||||
*
|
||||
* @since 13.0
|
||||
*/
|
||||
@Beta
|
||||
public static String toString(byte x) {
|
||||
return toString(x, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of {@code x} for the given radix, where
|
||||
* {@code x} is treated as unsigned.
|
||||
*
|
||||
* @param x the value to convert to a string.
|
||||
* @param radix the radix to use while working with {@code x}
|
||||
* @throws IllegalArgumentException if {@code radix} is not between
|
||||
* {@link Character#MIN_RADIX} and
|
||||
* {@link Character#MAX_RADIX}.
|
||||
* @since 13.0
|
||||
*/
|
||||
@Beta
|
||||
public static String toString(byte x, int radix) {
|
||||
checkArgument(radix >= Character.MIN_RADIX && radix <= Character.MAX_RADIX,
|
||||
"radix (%s) must be between Character.MIN_RADIX and Character.MAX_RADIX", radix);
|
||||
// Benchmarks indicate this is probably not worth optimizing.
|
||||
return Integer.toString(toInt(x), radix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unsigned {@code byte} value represented by the given decimal
|
||||
* string.
|
||||
*
|
||||
* @throws NumberFormatException if the string does not contain a valid unsigned
|
||||
* {@code byte} value
|
||||
* @throws NullPointerException if {@code s} is null (in contrast to
|
||||
* {@link Byte#parseByte(String)})
|
||||
* @since 13.0
|
||||
*/
|
||||
@Beta
|
||||
public static byte parseUnsignedByte(String string) {
|
||||
return parseUnsignedByte(string, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unsigned {@code byte} value represented by a string with the
|
||||
* given radix.
|
||||
*
|
||||
* @param string the string containing the unsigned {@code byte} representation
|
||||
* to be parsed.
|
||||
* @param radix the radix to use while parsing {@code string}
|
||||
* @throws NumberFormatException if the string does not contain a valid unsigned
|
||||
* {@code byte} with the given radix, or if
|
||||
* {@code radix} is not between
|
||||
* {@link Character#MIN_RADIX} and
|
||||
* {@link Character#MAX_RADIX}.
|
||||
* @throws NullPointerException if {@code s} is null (in contrast to
|
||||
* {@link Byte#parseByte(String)})
|
||||
* @since 13.0
|
||||
*/
|
||||
@Beta
|
||||
public static byte parseUnsignedByte(String string, int radix) {
|
||||
int parse = Integer.parseInt(checkNotNull(string), radix);
|
||||
// We need to throw a NumberFormatException, so we have to duplicate
|
||||
// checkedCast. =(
|
||||
if (parse >> Byte.SIZE == 0) {
|
||||
return (byte) parse;
|
||||
} else {
|
||||
throw new NumberFormatException("out of range: " + parse);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string containing the supplied {@code byte} values separated by
|
||||
* {@code separator}. For example, {@code join(":", (byte) 1, (byte) 2,
|
||||
* (byte) 255)} returns the string {@code "1:2:255"}.
|
||||
*
|
||||
* @param separator the text that should appear between consecutive values in
|
||||
* the resulting string (but not at the start or end)
|
||||
* @param array an array of {@code byte} values, possibly empty
|
||||
*/
|
||||
public static String join(String separator, byte... array) {
|
||||
checkNotNull(separator);
|
||||
if (array.length == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// For pre-sizing a builder, just get the right order of magnitude
|
||||
StringBuilder builder = new StringBuilder(array.length * (3 + separator.length()));
|
||||
builder.append(toInt(array[0]));
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
builder.append(separator).append(toString(array[i]));
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,277 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.common.primitives;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.primitives.UnsignedInts.INT_MASK;
|
||||
import static com.google.common.primitives.UnsignedInts.compare;
|
||||
import static com.google.common.primitives.UnsignedInts.toLong;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import javax.annotation.CheckReturnValue;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
import com.google.common.annotations.GwtIncompatible;
|
||||
|
||||
/**
|
||||
* A wrapper class for unsigned {@code int} values, supporting arithmetic
|
||||
* operations.
|
||||
*
|
||||
* <p>
|
||||
* In some cases, when speed is more important than code readability, it may be
|
||||
* faster simply to treat primitive {@code int} values as unsigned, using the
|
||||
* methods from {@link UnsignedInts}.
|
||||
*
|
||||
* <p>
|
||||
* See the Guava User Guide article on <a href=
|
||||
* "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained#Unsigned_support">
|
||||
* unsigned primitive utilities</a>.
|
||||
*
|
||||
* @author Louis Wasserman
|
||||
* @since 11.0
|
||||
*/
|
||||
@GwtCompatible(emulated = true)
|
||||
public final class UnsignedInteger extends Number implements Comparable<UnsignedInteger> {
|
||||
public static final UnsignedInteger ZERO = fromIntBits(0);
|
||||
public static final UnsignedInteger ONE = fromIntBits(1);
|
||||
public static final UnsignedInteger MAX_VALUE = fromIntBits(-1);
|
||||
|
||||
private final int value;
|
||||
|
||||
private UnsignedInteger(int value) {
|
||||
// GWT doesn't consistently overflow values to make them 32-bit, so we need to
|
||||
// force it.
|
||||
this.value = value & 0xffffffff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@code UnsignedInteger} corresponding to a given bit
|
||||
* representation. The argument is interpreted as an unsigned 32-bit value.
|
||||
* Specifically, the sign bit of {@code bits} is interpreted as a normal bit,
|
||||
* and all other bits are treated as usual.
|
||||
*
|
||||
* <p>
|
||||
* If the argument is nonnegative, the returned result will be equal to
|
||||
* {@code bits}, otherwise, the result will be equal to {@code 2^32 + bits}.
|
||||
*
|
||||
* <p>
|
||||
* To represent unsigned decimal constants, consider {@link #valueOf(long)}
|
||||
* instead.
|
||||
*
|
||||
* @since 14.0
|
||||
*/
|
||||
public static UnsignedInteger fromIntBits(int bits) {
|
||||
return new UnsignedInteger(bits);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@code UnsignedInteger} that is equal to {@code value}, if
|
||||
* possible. The inverse operation of {@link #longValue()}.
|
||||
*/
|
||||
public static UnsignedInteger valueOf(long value) {
|
||||
checkArgument((value & INT_MASK) == value, "value (%s) is outside the range for an unsigned integer value",
|
||||
value);
|
||||
return fromIntBits((int) value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code UnsignedInteger} representing the same value as the
|
||||
* specified {@link BigInteger}. This is the inverse operation of
|
||||
* {@link #bigIntegerValue()}.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code value} is negative or
|
||||
* {@code value >= 2^32}
|
||||
*/
|
||||
public static UnsignedInteger valueOf(BigInteger value) {
|
||||
checkNotNull(value);
|
||||
checkArgument(value.signum() >= 0 && value.bitLength() <= Integer.SIZE,
|
||||
"value (%s) is outside the range for an unsigned integer value", value);
|
||||
return fromIntBits(value.intValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@code UnsignedInteger} holding the value of the specified
|
||||
* {@code String}, parsed as an unsigned {@code int} value.
|
||||
*
|
||||
* @throws NumberFormatException if the string does not contain a parsable
|
||||
* unsigned {@code int} value
|
||||
*/
|
||||
public static UnsignedInteger valueOf(String string) {
|
||||
return valueOf(string, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@code UnsignedInteger} holding the value of the specified
|
||||
* {@code String}, parsed as an unsigned {@code int} value in the specified
|
||||
* radix.
|
||||
*
|
||||
* @throws NumberFormatException if the string does not contain a parsable
|
||||
* unsigned {@code int} value
|
||||
*/
|
||||
public static UnsignedInteger valueOf(String string, int radix) {
|
||||
return fromIntBits(UnsignedInts.parseUnsignedInt(string, radix));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of adding this and {@code val}. If the result would have
|
||||
* more than 32 bits, returns the low 32 bits of the result.
|
||||
*
|
||||
* @since 14.0
|
||||
*/
|
||||
@CheckReturnValue
|
||||
public UnsignedInteger plus(UnsignedInteger val) {
|
||||
return fromIntBits(this.value + checkNotNull(val).value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of subtracting this and {@code val}. If the result would
|
||||
* be negative, returns the low 32 bits of the result.
|
||||
*
|
||||
* @since 14.0
|
||||
*/
|
||||
@CheckReturnValue
|
||||
public UnsignedInteger minus(UnsignedInteger val) {
|
||||
return fromIntBits(value - checkNotNull(val).value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of multiplying this and {@code val}. If the result would
|
||||
* have more than 32 bits, returns the low 32 bits of the result.
|
||||
*
|
||||
* @since 14.0
|
||||
*/
|
||||
@CheckReturnValue
|
||||
@GwtIncompatible("Does not truncate correctly")
|
||||
public UnsignedInteger times(UnsignedInteger val) {
|
||||
// TODO(user): make this GWT-compatible
|
||||
return fromIntBits(value * checkNotNull(val).value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of dividing this by {@code val}.
|
||||
*
|
||||
* @throws ArithmeticException if {@code val} is zero
|
||||
* @since 14.0
|
||||
*/
|
||||
@CheckReturnValue
|
||||
public UnsignedInteger dividedBy(UnsignedInteger val) {
|
||||
return fromIntBits(UnsignedInts.divide(value, checkNotNull(val).value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this mod {@code val}.
|
||||
*
|
||||
* @throws ArithmeticException if {@code val} is zero
|
||||
* @since 14.0
|
||||
*/
|
||||
@CheckReturnValue
|
||||
public UnsignedInteger mod(UnsignedInteger val) {
|
||||
return fromIntBits(UnsignedInts.remainder(value, checkNotNull(val).value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of this {@code UnsignedInteger} as an {@code int}. This is
|
||||
* an inverse operation to {@link #fromIntBits}.
|
||||
*
|
||||
* <p>
|
||||
* Note that if this {@code UnsignedInteger} holds a value {@code >= 2^31}, the
|
||||
* returned value will be equal to {@code this - 2^32}.
|
||||
*/
|
||||
@Override
|
||||
public int intValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of this {@code UnsignedInteger} as a {@code long}.
|
||||
*/
|
||||
@Override
|
||||
public long longValue() {
|
||||
return toLong(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of this {@code UnsignedInteger} as a {@code float},
|
||||
* analogous to a widening primitive conversion from {@code int} to
|
||||
* {@code float}, and correctly rounded.
|
||||
*/
|
||||
@Override
|
||||
public float floatValue() {
|
||||
return longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of this {@code UnsignedInteger} as a {@code float},
|
||||
* analogous to a widening primitive conversion from {@code int} to
|
||||
* {@code double}, and correctly rounded.
|
||||
*/
|
||||
@Override
|
||||
public double doubleValue() {
|
||||
return longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of this {@code UnsignedInteger} as a {@link BigInteger}.
|
||||
*/
|
||||
public BigInteger bigIntegerValue() {
|
||||
return BigInteger.valueOf(longValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this unsigned integer to another unsigned integer. Returns {@code 0}
|
||||
* if they are equal, a negative number if {@code this < other}, and a positive
|
||||
* number if {@code this > other}.
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(UnsignedInteger other) {
|
||||
checkNotNull(other);
|
||||
return compare(value, other.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
if (obj instanceof UnsignedInteger) {
|
||||
UnsignedInteger other = (UnsignedInteger) obj;
|
||||
return value == other.value;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the {@code UnsignedInteger} value, in base
|
||||
* 10.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString(10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the {@code UnsignedInteger} value, in base
|
||||
* {@code radix}. If {@code radix < Character.MIN_RADIX} or
|
||||
* {@code radix > Character.MAX_RADIX}, the radix {@code 10} is used.
|
||||
*/
|
||||
public String toString(int radix) {
|
||||
return UnsignedInts.toString(value, radix);
|
||||
}
|
||||
}
|
296
sources/main/java/com/google/common/primitives/UnsignedInts.java
Normal file
296
sources/main/java/com/google/common/primitives/UnsignedInts.java
Normal file
@ -0,0 +1,296 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.common.primitives;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
|
||||
/**
|
||||
* Static utility methods pertaining to {@code int} primitives that interpret
|
||||
* values as <i>unsigned</i> (that is, any negative value {@code x} is treated
|
||||
* as the positive value {@code 2^32 + x}). The methods for which signedness is
|
||||
* not an issue are in {@link Ints}, as well as signed versions of methods for
|
||||
* which signedness is an issue.
|
||||
*
|
||||
* <p>
|
||||
* In addition, this class provides several static methods for converting an
|
||||
* {@code int} to a {@code String} and a {@code String} to an {@code int} that
|
||||
* treat the {@code int} as an unsigned number.
|
||||
*
|
||||
* <p>
|
||||
* Users of these utilities must be <i>extremely careful</i> not to mix up
|
||||
* signed and unsigned {@code int} values. When possible, it is recommended that
|
||||
* the {@link UnsignedInteger} wrapper class be used, at a small efficiency
|
||||
* penalty, to enforce the distinction in the type system.
|
||||
*
|
||||
* <p>
|
||||
* See the Guava User Guide article on <a href=
|
||||
* "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained#Unsigned_support">
|
||||
* unsigned primitive utilities</a>.
|
||||
*
|
||||
* @author Louis Wasserman
|
||||
* @since 11.0
|
||||
*/
|
||||
@Beta
|
||||
@GwtCompatible
|
||||
public final class UnsignedInts {
|
||||
static final long INT_MASK = 0xffffffffL;
|
||||
|
||||
private UnsignedInts() {
|
||||
}
|
||||
|
||||
static int flip(int value) {
|
||||
return value ^ Integer.MIN_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the two specified {@code int} values, treating them as unsigned
|
||||
* values between {@code 0} and {@code 2^32 - 1} inclusive.
|
||||
*
|
||||
* @param a the first unsigned {@code int} to compare
|
||||
* @param b the second unsigned {@code int} to compare
|
||||
* @return a negative value if {@code a} is less than {@code b}; a positive
|
||||
* value if {@code a} is greater than {@code b}; or zero if they are
|
||||
* equal
|
||||
*/
|
||||
public static int compare(int a, int b) {
|
||||
return Ints.compare(flip(a), flip(b));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the given {@code int} as a {@code long}, when treated as
|
||||
* unsigned.
|
||||
*/
|
||||
public static long toLong(int value) {
|
||||
return value & INT_MASK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the least value present in {@code array}, treating values as
|
||||
* unsigned.
|
||||
*
|
||||
* @param array a <i>nonempty</i> array of unsigned {@code int} values
|
||||
* @return the value present in {@code array} that is less than or equal to
|
||||
* every other value in the array according to {@link #compare}
|
||||
* @throws IllegalArgumentException if {@code array} is empty
|
||||
*/
|
||||
public static int min(int... array) {
|
||||
checkArgument(array.length > 0);
|
||||
int min = flip(array[0]);
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
int next = flip(array[i]);
|
||||
if (next < min) {
|
||||
min = next;
|
||||
}
|
||||
}
|
||||
return flip(min);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the greatest value present in {@code array}, treating values as
|
||||
* unsigned.
|
||||
*
|
||||
* @param array a <i>nonempty</i> array of unsigned {@code int} values
|
||||
* @return the value present in {@code array} that is greater than or equal to
|
||||
* every other value in the array according to {@link #compare}
|
||||
* @throws IllegalArgumentException if {@code array} is empty
|
||||
*/
|
||||
public static int max(int... array) {
|
||||
checkArgument(array.length > 0);
|
||||
int max = flip(array[0]);
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
int next = flip(array[i]);
|
||||
if (next > max) {
|
||||
max = next;
|
||||
}
|
||||
}
|
||||
return flip(max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string containing the supplied unsigned {@code int} values
|
||||
* separated by {@code separator}. For example, {@code join("-", 1, 2, 3)}
|
||||
* returns the string {@code "1-2-3"}.
|
||||
*
|
||||
* @param separator the text that should appear between consecutive values in
|
||||
* the resulting string (but not at the start or end)
|
||||
* @param array an array of unsigned {@code int} values, possibly empty
|
||||
*/
|
||||
public static String join(String separator, int... array) {
|
||||
checkNotNull(separator);
|
||||
if (array.length == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// For pre-sizing a builder, just get the right order of magnitude
|
||||
StringBuilder builder = new StringBuilder(array.length * 5);
|
||||
builder.append(toString(array[0]));
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
builder.append(separator).append(toString(array[i]));
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a comparator that compares two arrays of unsigned {@code int} values
|
||||
* lexicographically. That is, it compares, using {@link #compare(int, int)}),
|
||||
* the first pair of values that follow any common prefix, or when one array is
|
||||
* a prefix of the other, treats the shorter array as the lesser. For example,
|
||||
* {@code [] < [1] < [1, 2] < [2] < [1 << 31]}.
|
||||
*
|
||||
* <p>
|
||||
* The returned comparator is inconsistent with {@link Object#equals(Object)}
|
||||
* (since arrays support only identity equality), but it is consistent with
|
||||
* {@link Arrays#equals(int[], int[])}.
|
||||
*
|
||||
* @see <a href="http://en.wikipedia.org/wiki/Lexicographical_order">
|
||||
* Lexicographical order article at Wikipedia</a>
|
||||
*/
|
||||
public static Comparator<int[]> lexicographicalComparator() {
|
||||
return LexicographicalComparator.INSTANCE;
|
||||
}
|
||||
|
||||
enum LexicographicalComparator implements Comparator<int[]> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public int compare(int[] left, int[] right) {
|
||||
int minLength = Math.min(left.length, right.length);
|
||||
for (int i = 0; i < minLength; i++) {
|
||||
if (left[i] != right[i]) {
|
||||
return UnsignedInts.compare(left[i], right[i]);
|
||||
}
|
||||
}
|
||||
return left.length - right.length;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns dividend / divisor, where the dividend and divisor are treated as
|
||||
* unsigned 32-bit quantities.
|
||||
*
|
||||
* @param dividend the dividend (numerator)
|
||||
* @param divisor the divisor (denominator)
|
||||
* @throws ArithmeticException if divisor is 0
|
||||
*/
|
||||
public static int divide(int dividend, int divisor) {
|
||||
return (int) (toLong(dividend) / toLong(divisor));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns dividend % divisor, where the dividend and divisor are treated as
|
||||
* unsigned 32-bit quantities.
|
||||
*
|
||||
* @param dividend the dividend (numerator)
|
||||
* @param divisor the divisor (denominator)
|
||||
* @throws ArithmeticException if divisor is 0
|
||||
*/
|
||||
public static int remainder(int dividend, int divisor) {
|
||||
return (int) (toLong(dividend) % toLong(divisor));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unsigned {@code int} value represented by the given string.
|
||||
*
|
||||
* Accepts a decimal, hexadecimal, or octal number given by specifying the
|
||||
* following prefix:
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@code 0x}<i>HexDigits</i>
|
||||
* <li>{@code 0X}<i>HexDigits</i>
|
||||
* <li>{@code #}<i>HexDigits</i>
|
||||
* <li>{@code 0}<i>OctalDigits</i>
|
||||
* </ul>
|
||||
*
|
||||
* @throws NumberFormatException if the string does not contain a valid unsigned
|
||||
* {@code int} value
|
||||
* @since 13.0
|
||||
*/
|
||||
public static int decode(String stringValue) {
|
||||
ParseRequest request = ParseRequest.fromString(stringValue);
|
||||
|
||||
try {
|
||||
return parseUnsignedInt(request.rawValue, request.radix);
|
||||
} catch (NumberFormatException e) {
|
||||
NumberFormatException decodeException = new NumberFormatException("Error parsing value: " + stringValue);
|
||||
decodeException.initCause(e);
|
||||
throw decodeException;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unsigned {@code int} value represented by the given decimal
|
||||
* string.
|
||||
*
|
||||
* @throws NumberFormatException if the string does not contain a valid unsigned
|
||||
* {@code int} value
|
||||
* @throws NullPointerException if {@code s} is null (in contrast to
|
||||
* {@link Integer#parseInt(String)})
|
||||
*/
|
||||
public static int parseUnsignedInt(String s) {
|
||||
return parseUnsignedInt(s, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unsigned {@code int} value represented by a string with the given
|
||||
* radix.
|
||||
*
|
||||
* @param string the string containing the unsigned integer representation to be
|
||||
* parsed.
|
||||
* @param radix the radix to use while parsing {@code s}; must be between
|
||||
* {@link Character#MIN_RADIX} and {@link Character#MAX_RADIX}.
|
||||
* @throws NumberFormatException if the string does not contain a valid unsigned
|
||||
* {@code int}, or if supplied radix is invalid.
|
||||
* @throws NullPointerException if {@code s} is null (in contrast to
|
||||
* {@link Integer#parseInt(String)})
|
||||
*/
|
||||
public static int parseUnsignedInt(String string, int radix) {
|
||||
checkNotNull(string);
|
||||
long result = Long.parseLong(string, radix);
|
||||
if ((result & INT_MASK) != result) {
|
||||
throw new NumberFormatException(
|
||||
"Input " + string + " in base " + radix + " is not in the range of an unsigned integer");
|
||||
}
|
||||
return (int) result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of x, where x is treated as unsigned.
|
||||
*/
|
||||
public static String toString(int x) {
|
||||
return toString(x, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of {@code x} for the given radix, where
|
||||
* {@code x} is treated as unsigned.
|
||||
*
|
||||
* @param x the value to convert to a string.
|
||||
* @param radix the radix to use while working with {@code x}
|
||||
* @throws IllegalArgumentException if {@code radix} is not between
|
||||
* {@link Character#MIN_RADIX} and
|
||||
* {@link Character#MAX_RADIX}.
|
||||
*/
|
||||
public static String toString(int x, int radix) {
|
||||
long asLong = x & INT_MASK;
|
||||
return Long.toString(asLong, radix);
|
||||
}
|
||||
}
|
284
sources/main/java/com/google/common/primitives/UnsignedLong.java
Normal file
284
sources/main/java/com/google/common/primitives/UnsignedLong.java
Normal file
@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.common.primitives;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import javax.annotation.CheckReturnValue;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
|
||||
/**
|
||||
* A wrapper class for unsigned {@code long} values, supporting arithmetic
|
||||
* operations.
|
||||
*
|
||||
* <p>
|
||||
* In some cases, when speed is more important than code readability, it may be
|
||||
* faster simply to treat primitive {@code long} values as unsigned, using the
|
||||
* methods from {@link UnsignedLongs}.
|
||||
*
|
||||
* <p>
|
||||
* See the Guava User Guide article on <a href=
|
||||
* "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained#Unsigned_support">
|
||||
* unsigned primitive utilities</a>.
|
||||
*
|
||||
* @author Louis Wasserman
|
||||
* @author Colin Evans
|
||||
* @since 11.0
|
||||
*/
|
||||
@GwtCompatible(serializable = true)
|
||||
public final class UnsignedLong extends Number implements Comparable<UnsignedLong>, Serializable {
|
||||
|
||||
private static final long UNSIGNED_MASK = 0x7fffffffffffffffL;
|
||||
|
||||
public static final UnsignedLong ZERO = new UnsignedLong(0);
|
||||
public static final UnsignedLong ONE = new UnsignedLong(1);
|
||||
public static final UnsignedLong MAX_VALUE = new UnsignedLong(-1L);
|
||||
|
||||
private final long value;
|
||||
|
||||
private UnsignedLong(long value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@code UnsignedLong} corresponding to a given bit representation.
|
||||
* The argument is interpreted as an unsigned 64-bit value. Specifically, the
|
||||
* sign bit of {@code bits} is interpreted as a normal bit, and all other bits
|
||||
* are treated as usual.
|
||||
*
|
||||
* <p>
|
||||
* If the argument is nonnegative, the returned result will be equal to
|
||||
* {@code bits}, otherwise, the result will be equal to {@code 2^64 + bits}.
|
||||
*
|
||||
* <p>
|
||||
* To represent decimal constants less than {@code 2^63}, consider
|
||||
* {@link #valueOf(long)} instead.
|
||||
*
|
||||
* @since 14.0
|
||||
*/
|
||||
public static UnsignedLong fromLongBits(long bits) {
|
||||
// TODO(user): consider caching small values, like Long.valueOf
|
||||
return new UnsignedLong(bits);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@code UnsignedLong} representing the same value as the specified
|
||||
* {@code long}.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code value} is negative
|
||||
* @since 14.0
|
||||
*/
|
||||
public static UnsignedLong valueOf(long value) {
|
||||
checkArgument(value >= 0, "value (%s) is outside the range for an unsigned long value", value);
|
||||
return fromLongBits(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code UnsignedLong} representing the same value as the specified
|
||||
* {@code BigInteger}. This is the inverse operation of
|
||||
* {@link #bigIntegerValue()}.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code value} is negative or
|
||||
* {@code value >= 2^64}
|
||||
*/
|
||||
public static UnsignedLong valueOf(BigInteger value) {
|
||||
checkNotNull(value);
|
||||
checkArgument(value.signum() >= 0 && value.bitLength() <= Long.SIZE,
|
||||
"value (%s) is outside the range for an unsigned long value", value);
|
||||
return fromLongBits(value.longValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@code UnsignedLong} holding the value of the specified
|
||||
* {@code String}, parsed as an unsigned {@code long} value.
|
||||
*
|
||||
* @throws NumberFormatException if the string does not contain a parsable
|
||||
* unsigned {@code long} value
|
||||
*/
|
||||
public static UnsignedLong valueOf(String string) {
|
||||
return valueOf(string, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@code UnsignedLong} holding the value of the specified
|
||||
* {@code String}, parsed as an unsigned {@code long} value in the specified
|
||||
* radix.
|
||||
*
|
||||
* @throws NumberFormatException if the string does not contain a parsable
|
||||
* unsigned {@code long} value, or {@code radix}
|
||||
* is not between {@link Character#MIN_RADIX} and
|
||||
* {@link Character#MAX_RADIX}
|
||||
*/
|
||||
public static UnsignedLong valueOf(String string, int radix) {
|
||||
return fromLongBits(UnsignedLongs.parseUnsignedLong(string, radix));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of adding this and {@code val}. If the result would have
|
||||
* more than 64 bits, returns the low 64 bits of the result.
|
||||
*
|
||||
* @since 14.0
|
||||
*/
|
||||
public UnsignedLong plus(UnsignedLong val) {
|
||||
return fromLongBits(this.value + checkNotNull(val).value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of subtracting this and {@code val}. If the result would
|
||||
* have more than 64 bits, returns the low 64 bits of the result.
|
||||
*
|
||||
* @since 14.0
|
||||
*/
|
||||
public UnsignedLong minus(UnsignedLong val) {
|
||||
return fromLongBits(this.value - checkNotNull(val).value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of multiplying this and {@code val}. If the result would
|
||||
* have more than 64 bits, returns the low 64 bits of the result.
|
||||
*
|
||||
* @since 14.0
|
||||
*/
|
||||
@CheckReturnValue
|
||||
public UnsignedLong times(UnsignedLong val) {
|
||||
return fromLongBits(value * checkNotNull(val).value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of dividing this by {@code val}.
|
||||
*
|
||||
* @since 14.0
|
||||
*/
|
||||
@CheckReturnValue
|
||||
public UnsignedLong dividedBy(UnsignedLong val) {
|
||||
return fromLongBits(UnsignedLongs.divide(value, checkNotNull(val).value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this modulo {@code val}.
|
||||
*
|
||||
* @since 14.0
|
||||
*/
|
||||
@CheckReturnValue
|
||||
public UnsignedLong mod(UnsignedLong val) {
|
||||
return fromLongBits(UnsignedLongs.remainder(value, checkNotNull(val).value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of this {@code UnsignedLong} as an {@code int}.
|
||||
*/
|
||||
@Override
|
||||
public int intValue() {
|
||||
return (int) value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of this {@code UnsignedLong} as a {@code long}. This is an
|
||||
* inverse operation to {@link #fromLongBits}.
|
||||
*
|
||||
* <p>
|
||||
* Note that if this {@code UnsignedLong} holds a value {@code >= 2^63}, the
|
||||
* returned value will be equal to {@code this - 2^64}.
|
||||
*/
|
||||
@Override
|
||||
public long longValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of this {@code UnsignedLong} as a {@code float}, analogous
|
||||
* to a widening primitive conversion from {@code long} to {@code float}, and
|
||||
* correctly rounded.
|
||||
*/
|
||||
@Override
|
||||
public float floatValue() {
|
||||
@SuppressWarnings("cast")
|
||||
float fValue = (float) (value & UNSIGNED_MASK);
|
||||
if (value < 0) {
|
||||
fValue += 0x1.0p63f;
|
||||
}
|
||||
return fValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of this {@code UnsignedLong} as a {@code double}, analogous
|
||||
* to a widening primitive conversion from {@code long} to {@code double}, and
|
||||
* correctly rounded.
|
||||
*/
|
||||
@Override
|
||||
public double doubleValue() {
|
||||
@SuppressWarnings("cast")
|
||||
double dValue = (double) (value & UNSIGNED_MASK);
|
||||
if (value < 0) {
|
||||
dValue += 0x1.0p63;
|
||||
}
|
||||
return dValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of this {@code UnsignedLong} as a {@link BigInteger}.
|
||||
*/
|
||||
public BigInteger bigIntegerValue() {
|
||||
BigInteger bigInt = BigInteger.valueOf(value & UNSIGNED_MASK);
|
||||
if (value < 0) {
|
||||
bigInt = bigInt.setBit(Long.SIZE - 1);
|
||||
}
|
||||
return bigInt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(UnsignedLong o) {
|
||||
checkNotNull(o);
|
||||
return UnsignedLongs.compare(value, o.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Longs.hashCode(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
if (obj instanceof UnsignedLong) {
|
||||
UnsignedLong other = (UnsignedLong) obj;
|
||||
return value == other.value;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the {@code UnsignedLong} value, in base
|
||||
* 10.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return UnsignedLongs.toString(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the {@code UnsignedLong} value, in base
|
||||
* {@code radix}. If {@code radix < Character.MIN_RADIX} or
|
||||
* {@code radix > Character.MAX_RADIX}, the radix {@code 10} is used.
|
||||
*/
|
||||
public String toString(int radix) {
|
||||
return UnsignedLongs.toString(value, radix);
|
||||
}
|
||||
}
|
@ -0,0 +1,415 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.common.primitives;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
|
||||
/**
|
||||
* Static utility methods pertaining to {@code long} primitives that interpret
|
||||
* values as <i>unsigned</i> (that is, any negative value {@code x} is treated
|
||||
* as the positive value {@code 2^64 + x}). The methods for which signedness is
|
||||
* not an issue are in {@link Longs}, as well as signed versions of methods for
|
||||
* which signedness is an issue.
|
||||
*
|
||||
* <p>
|
||||
* In addition, this class provides several static methods for converting a
|
||||
* {@code long} to a {@code String} and a {@code String} to a {@code long} that
|
||||
* treat the {@code long} as an unsigned number.
|
||||
*
|
||||
* <p>
|
||||
* Users of these utilities must be <i>extremely careful</i> not to mix up
|
||||
* signed and unsigned {@code long} values. When possible, it is recommended
|
||||
* that the {@link UnsignedLong} wrapper class be used, at a small efficiency
|
||||
* penalty, to enforce the distinction in the type system.
|
||||
*
|
||||
* <p>
|
||||
* See the Guava User Guide article on <a href=
|
||||
* "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained#Unsigned_support">
|
||||
* unsigned primitive utilities</a>.
|
||||
*
|
||||
* @author Louis Wasserman
|
||||
* @author Brian Milch
|
||||
* @author Colin Evans
|
||||
* @since 10.0
|
||||
*/
|
||||
@Beta
|
||||
@GwtCompatible
|
||||
public final class UnsignedLongs {
|
||||
private UnsignedLongs() {
|
||||
}
|
||||
|
||||
public static final long MAX_VALUE = -1L; // Equivalent to 2^64 - 1
|
||||
|
||||
/**
|
||||
* A (self-inverse) bijection which converts the ordering on unsigned longs to
|
||||
* the ordering on longs, that is, {@code a <= b} as unsigned longs if and only
|
||||
* if {@code flip(a) <= flip(b)} as signed longs.
|
||||
*/
|
||||
private static long flip(long a) {
|
||||
return a ^ Long.MIN_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the two specified {@code long} values, treating them as unsigned
|
||||
* values between {@code 0} and {@code 2^64 - 1} inclusive.
|
||||
*
|
||||
* @param a the first unsigned {@code long} to compare
|
||||
* @param b the second unsigned {@code long} to compare
|
||||
* @return a negative value if {@code a} is less than {@code b}; a positive
|
||||
* value if {@code a} is greater than {@code b}; or zero if they are
|
||||
* equal
|
||||
*/
|
||||
public static int compare(long a, long b) {
|
||||
return Longs.compare(flip(a), flip(b));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the least value present in {@code array}, treating values as
|
||||
* unsigned.
|
||||
*
|
||||
* @param array a <i>nonempty</i> array of unsigned {@code long} values
|
||||
* @return the value present in {@code array} that is less than or equal to
|
||||
* every other value in the array according to {@link #compare}
|
||||
* @throws IllegalArgumentException if {@code array} is empty
|
||||
*/
|
||||
public static long min(long... array) {
|
||||
checkArgument(array.length > 0);
|
||||
long min = flip(array[0]);
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
long next = flip(array[i]);
|
||||
if (next < min) {
|
||||
min = next;
|
||||
}
|
||||
}
|
||||
return flip(min);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the greatest value present in {@code array}, treating values as
|
||||
* unsigned.
|
||||
*
|
||||
* @param array a <i>nonempty</i> array of unsigned {@code long} values
|
||||
* @return the value present in {@code array} that is greater than or equal to
|
||||
* every other value in the array according to {@link #compare}
|
||||
* @throws IllegalArgumentException if {@code array} is empty
|
||||
*/
|
||||
public static long max(long... array) {
|
||||
checkArgument(array.length > 0);
|
||||
long max = flip(array[0]);
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
long next = flip(array[i]);
|
||||
if (next > max) {
|
||||
max = next;
|
||||
}
|
||||
}
|
||||
return flip(max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string containing the supplied unsigned {@code long} values
|
||||
* separated by {@code separator}. For example, {@code join("-", 1, 2, 3)}
|
||||
* returns the string {@code "1-2-3"}.
|
||||
*
|
||||
* @param separator the text that should appear between consecutive values in
|
||||
* the resulting string (but not at the start or end)
|
||||
* @param array an array of unsigned {@code long} values, possibly empty
|
||||
*/
|
||||
public static String join(String separator, long... array) {
|
||||
checkNotNull(separator);
|
||||
if (array.length == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// For pre-sizing a builder, just get the right order of magnitude
|
||||
StringBuilder builder = new StringBuilder(array.length * 5);
|
||||
builder.append(toString(array[0]));
|
||||
for (int i = 1; i < array.length; i++) {
|
||||
builder.append(separator).append(toString(array[i]));
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a comparator that compares two arrays of unsigned {@code long} values
|
||||
* lexicographically. That is, it compares, using {@link #compare(long, long)}),
|
||||
* the first pair of values that follow any common prefix, or when one array is
|
||||
* a prefix of the other, treats the shorter array as the lesser. For example,
|
||||
* {@code [] < [1L] < [1L, 2L] < [2L] < [1L << 63]}.
|
||||
*
|
||||
* <p>
|
||||
* The returned comparator is inconsistent with {@link Object#equals(Object)}
|
||||
* (since arrays support only identity equality), but it is consistent with
|
||||
* {@link Arrays#equals(long[], long[])}.
|
||||
*
|
||||
* @see <a href=
|
||||
* "http://en.wikipedia.org/wiki/Lexicographical_order">Lexicographical
|
||||
* order article at Wikipedia</a>
|
||||
*/
|
||||
public static Comparator<long[]> lexicographicalComparator() {
|
||||
return LexicographicalComparator.INSTANCE;
|
||||
}
|
||||
|
||||
enum LexicographicalComparator implements Comparator<long[]> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public int compare(long[] left, long[] right) {
|
||||
int minLength = Math.min(left.length, right.length);
|
||||
for (int i = 0; i < minLength; i++) {
|
||||
if (left[i] != right[i]) {
|
||||
return UnsignedLongs.compare(left[i], right[i]);
|
||||
}
|
||||
}
|
||||
return left.length - right.length;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns dividend / divisor, where the dividend and divisor are treated as
|
||||
* unsigned 64-bit quantities.
|
||||
*
|
||||
* @param dividend the dividend (numerator)
|
||||
* @param divisor the divisor (denominator)
|
||||
* @throws ArithmeticException if divisor is 0
|
||||
*/
|
||||
public static long divide(long dividend, long divisor) {
|
||||
if (divisor < 0) { // i.e., divisor >= 2^63:
|
||||
if (compare(dividend, divisor) < 0) {
|
||||
return 0; // dividend < divisor
|
||||
} else {
|
||||
return 1; // dividend >= divisor
|
||||
}
|
||||
}
|
||||
|
||||
// Optimization - use signed division if dividend < 2^63
|
||||
if (dividend >= 0) {
|
||||
return dividend / divisor;
|
||||
}
|
||||
|
||||
/*
|
||||
* Otherwise, approximate the quotient, check, and correct if necessary. Our
|
||||
* approximation is guaranteed to be either exact or one less than the correct
|
||||
* value. This follows from fact that floor(floor(x)/i) == floor(x/i) for any
|
||||
* real x and integer i != 0. The proof is not quite trivial.
|
||||
*/
|
||||
long quotient = ((dividend >>> 1) / divisor) << 1;
|
||||
long rem = dividend - quotient * divisor;
|
||||
return quotient + (compare(rem, divisor) >= 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns dividend % divisor, where the dividend and divisor are treated as
|
||||
* unsigned 64-bit quantities.
|
||||
*
|
||||
* @param dividend the dividend (numerator)
|
||||
* @param divisor the divisor (denominator)
|
||||
* @throws ArithmeticException if divisor is 0
|
||||
* @since 11.0
|
||||
*/
|
||||
public static long remainder(long dividend, long divisor) {
|
||||
if (divisor < 0) { // i.e., divisor >= 2^63:
|
||||
if (compare(dividend, divisor) < 0) {
|
||||
return dividend; // dividend < divisor
|
||||
} else {
|
||||
return dividend - divisor; // dividend >= divisor
|
||||
}
|
||||
}
|
||||
|
||||
// Optimization - use signed modulus if dividend < 2^63
|
||||
if (dividend >= 0) {
|
||||
return dividend % divisor;
|
||||
}
|
||||
|
||||
/*
|
||||
* Otherwise, approximate the quotient, check, and correct if necessary. Our
|
||||
* approximation is guaranteed to be either exact or one less than the correct
|
||||
* value. This follows from fact that floor(floor(x)/i) == floor(x/i) for any
|
||||
* real x and integer i != 0. The proof is not quite trivial.
|
||||
*/
|
||||
long quotient = ((dividend >>> 1) / divisor) << 1;
|
||||
long rem = dividend - quotient * divisor;
|
||||
return rem - (compare(rem, divisor) >= 0 ? divisor : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unsigned {@code long} value represented by the given decimal
|
||||
* string.
|
||||
*
|
||||
* @throws NumberFormatException if the string does not contain a valid unsigned
|
||||
* {@code long} value
|
||||
* @throws NullPointerException if {@code s} is null (in contrast to
|
||||
* {@link Long#parseLong(String)})
|
||||
*/
|
||||
public static long parseUnsignedLong(String s) {
|
||||
return parseUnsignedLong(s, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unsigned {@code long} value represented by the given string.
|
||||
*
|
||||
* Accepts a decimal, hexadecimal, or octal number given by specifying the
|
||||
* following prefix:
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@code 0x}<i>HexDigits</i>
|
||||
* <li>{@code 0X}<i>HexDigits</i>
|
||||
* <li>{@code #}<i>HexDigits</i>
|
||||
* <li>{@code 0}<i>OctalDigits</i>
|
||||
* </ul>
|
||||
*
|
||||
* @throws NumberFormatException if the string does not contain a valid unsigned
|
||||
* {@code long} value
|
||||
* @since 13.0
|
||||
*/
|
||||
public static long decode(String stringValue) {
|
||||
ParseRequest request = ParseRequest.fromString(stringValue);
|
||||
|
||||
try {
|
||||
return parseUnsignedLong(request.rawValue, request.radix);
|
||||
} catch (NumberFormatException e) {
|
||||
NumberFormatException decodeException = new NumberFormatException("Error parsing value: " + stringValue);
|
||||
decodeException.initCause(e);
|
||||
throw decodeException;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unsigned {@code long} value represented by a string with the
|
||||
* given radix.
|
||||
*
|
||||
* @param s the string containing the unsigned {@code long} representation
|
||||
* to be parsed.
|
||||
* @param radix the radix to use while parsing {@code s}
|
||||
* @throws NumberFormatException if the string does not contain a valid unsigned
|
||||
* {@code long} with the given radix, or if
|
||||
* {@code radix} is not between
|
||||
* {@link Character#MIN_RADIX} and
|
||||
* {@link Character#MAX_RADIX}.
|
||||
* @throws NullPointerException if {@code s} is null (in contrast to
|
||||
* {@link Long#parseLong(String)})
|
||||
*/
|
||||
public static long parseUnsignedLong(String s, int radix) {
|
||||
checkNotNull(s);
|
||||
if (s.length() == 0) {
|
||||
throw new NumberFormatException("empty string");
|
||||
}
|
||||
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
|
||||
throw new NumberFormatException("illegal radix: " + radix);
|
||||
}
|
||||
|
||||
int max_safe_pos = maxSafeDigits[radix] - 1;
|
||||
long value = 0;
|
||||
for (int pos = 0; pos < s.length(); pos++) {
|
||||
int digit = Character.digit(s.charAt(pos), radix);
|
||||
if (digit == -1) {
|
||||
throw new NumberFormatException(s);
|
||||
}
|
||||
if (pos > max_safe_pos && overflowInParse(value, digit, radix)) {
|
||||
throw new NumberFormatException("Too large for unsigned long: " + s);
|
||||
}
|
||||
value = (value * radix) + digit;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if (current * radix) + digit is a number too large to be
|
||||
* represented by an unsigned long. This is useful for detecting overflow while
|
||||
* parsing a string representation of a number. Does not verify whether supplied
|
||||
* radix is valid, passing an invalid radix will give undefined results or an
|
||||
* ArrayIndexOutOfBoundsException.
|
||||
*/
|
||||
private static boolean overflowInParse(long current, int digit, int radix) {
|
||||
if (current >= 0) {
|
||||
if (current < maxValueDivs[radix]) {
|
||||
return false;
|
||||
}
|
||||
if (current > maxValueDivs[radix]) {
|
||||
return true;
|
||||
}
|
||||
// current == maxValueDivs[radix]
|
||||
return (digit > maxValueMods[radix]);
|
||||
}
|
||||
|
||||
// current < 0: high bit is set
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of x, where x is treated as unsigned.
|
||||
*/
|
||||
public static String toString(long x) {
|
||||
return toString(x, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of {@code x} for the given radix, where
|
||||
* {@code x} is treated as unsigned.
|
||||
*
|
||||
* @param x the value to convert to a string.
|
||||
* @param radix the radix to use while working with {@code x}
|
||||
* @throws IllegalArgumentException if {@code radix} is not between
|
||||
* {@link Character#MIN_RADIX} and
|
||||
* {@link Character#MAX_RADIX}.
|
||||
*/
|
||||
public static String toString(long x, int radix) {
|
||||
checkArgument(radix >= Character.MIN_RADIX && radix <= Character.MAX_RADIX,
|
||||
"radix (%s) must be between Character.MIN_RADIX and Character.MAX_RADIX", radix);
|
||||
if (x == 0) {
|
||||
// Simply return "0"
|
||||
return "0";
|
||||
} else {
|
||||
char[] buf = new char[64];
|
||||
int i = buf.length;
|
||||
if (x < 0) {
|
||||
// Separate off the last digit using unsigned division. That will leave
|
||||
// a number that is nonnegative as a signed integer.
|
||||
long quotient = divide(x, radix);
|
||||
long rem = x - quotient * radix;
|
||||
buf[--i] = Character.forDigit((int) rem, radix);
|
||||
x = quotient;
|
||||
}
|
||||
// Simple modulo/division approach
|
||||
while (x > 0) {
|
||||
buf[--i] = Character.forDigit((int) (x % radix), radix);
|
||||
x /= radix;
|
||||
}
|
||||
// Generate string
|
||||
return new String(buf, i, buf.length - i);
|
||||
}
|
||||
}
|
||||
|
||||
// calculated as 0xffffffffffffffff / radix
|
||||
private static final long[] maxValueDivs = new long[Character.MAX_RADIX + 1];
|
||||
private static final int[] maxValueMods = new int[Character.MAX_RADIX + 1];
|
||||
private static final int[] maxSafeDigits = new int[Character.MAX_RADIX + 1];
|
||||
static {
|
||||
BigInteger overflow = new BigInteger("10000000000000000", 16);
|
||||
for (int i = Character.MIN_RADIX; i <= Character.MAX_RADIX; i++) {
|
||||
maxValueDivs[i] = divide(MAX_VALUE, i);
|
||||
maxValueMods[i] = (int) remainder(MAX_VALUE, i);
|
||||
maxSafeDigits[i] = overflow.toString(i).length() - 1;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Guava Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Static utilities for working with the eight primitive types and {@code void},
|
||||
* and value types for treating them as unsigned.
|
||||
*
|
||||
* <p>
|
||||
* This package is a part of the open-source
|
||||
* <a href="http://guava-libraries.googlecode.com">Guava libraries</a>.
|
||||
*
|
||||
* <p>
|
||||
* See the Guava User Guide article on
|
||||
* <a href= "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained">
|
||||
* primitive utilities</a>.
|
||||
*
|
||||
* <h2>Contents</h2>
|
||||
*
|
||||
* <h3>General static utilities</h3>
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@link com.google.common.primitives.Primitives}
|
||||
* </ul>
|
||||
*
|
||||
* <h3>Per-type static utilities</h3>
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@link com.google.common.primitives.Booleans}
|
||||
* <li>{@link com.google.common.primitives.Bytes}
|
||||
* <ul>
|
||||
* <li>{@link com.google.common.primitives.SignedBytes}
|
||||
* <li>{@link com.google.common.primitives.UnsignedBytes}
|
||||
* </ul>
|
||||
* <li>{@link com.google.common.primitives.Chars}
|
||||
* <li>{@link com.google.common.primitives.Doubles}
|
||||
* <li>{@link com.google.common.primitives.Floats}
|
||||
* <li>{@link com.google.common.primitives.Ints}
|
||||
* <ul>
|
||||
* <li>{@link com.google.common.primitives.UnsignedInts}
|
||||
* </ul>
|
||||
* <li>{@link com.google.common.primitives.Longs}
|
||||
* <ul>
|
||||
* <li>{@link com.google.common.primitives.UnsignedLongs}
|
||||
* </ul>
|
||||
* <li>{@link com.google.common.primitives.Shorts}
|
||||
* </ul>
|
||||
*
|
||||
* <h3>Value types</h3>
|
||||
* <ul>
|
||||
* <li>{@link com.google.common.primitives.UnsignedInteger}
|
||||
* <li>{@link com.google.common.primitives.UnsignedLong}
|
||||
* </ul>
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
package com.google.common.primitives;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
Reference in New Issue
Block a user