Integer
represent primitive
* int
values.
*
* Additionally, this class provides various helper functions and variables
* related to ints.
*
* @author Paul Fisher
* @author John Keiser
* @author Warren Levy
* @author Eric Blake (ebb9@email.byu.edu)
* @author Tom Tromey (tromey@redhat.com)
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
* @author Ian Rogers
* @since 1.0
* @status updated to 1.5
*/
public final class Integer extends Number implements Comparableint
can represent is -2147483648 (or
* -231).
*/
public static final int MIN_VALUE = 0x80000000;
/**
* The maximum value an int
can represent is 2147483647 (or
* 231 - 1).
*/
public static final int MAX_VALUE = 0x7fffffff;
/**
* The primitive type int
is represented by this
* Class
object.
* @since 1.1
*/
public static final Classint
.
* @since 1.5
*/
public static final int SIZE = 32;
// This caches some Integer values, and is used by boxing
// conversions via valueOf(). We must cache at least -128..127;
// these constants control how much we actually cache.
private static final int MIN_CACHE = -128;
private static final int MAX_CACHE = 127;
private static final Integer[] intCache = new Integer[MAX_CACHE - MIN_CACHE + 1];
static
{
for (int i=MIN_CACHE; i <= MAX_CACHE; i++)
intCache[i - MIN_CACHE] = new Integer(i);
}
/**
* The immutable value of this Integer.
*
* @serial the wrapped int
*/
private final int value;
/**
* Create an Integer
object representing the value of the
* int
argument.
*
* @param value the value to use
*/
public Integer(int value)
{
this.value = value;
}
/**
* Create an Integer
object representing the value of the
* argument after conversion to an int
.
*
* @param s the string to convert
* @throws NumberFormatException if the String does not contain an int
* @see #valueOf(String)
*/
public Integer(String s)
{
value = parseInt(s, 10, false);
}
/**
* Return the size of a string large enough to hold the given number
*
* @param num the number we want the string length for (must be positive)
* @param radix the radix (base) that will be used for the string
* @return a size sufficient for a string of num
*/
private static int stringSize(int num, int radix) {
int exp;
if (radix < 4)
{
exp = 1;
}
else if (radix < 8)
{
exp = 2;
}
else if (radix < 16)
{
exp = 3;
}
else if (radix < 32)
{
exp = 4;
}
else
{
exp = 5;
}
int size=0;
do
{
num >>>= exp;
size++;
}
while(num != 0);
return size;
}
/**
* Converts the int
to a String
using
* the specified radix (base). If the radix exceeds
* Character.MIN_RADIX
or Character.MAX_RADIX
, 10
* is used instead. If the result is negative, the leading character is
* '-' ('\\u002D'). The remaining characters come from
* Character.forDigit(digit, radix)
('0'-'9','a'-'z').
*
* @param num the int
to convert to String
* @param radix the radix (base) to use in the conversion
* @return the String
representation of the argument
*/
public static String toString(int num, int radix)
{
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
radix = 10;
// Is the value negative?
boolean isNeg = num < 0;
// Is the string a single character?
if (!isNeg && num < radix)
return new String(digits, num, 1, true);
// Compute string size and allocate buffer
// account for a leading '-' if the value is negative
int size;
int i;
char[] buffer;
if (isNeg)
{
num = -num;
// When the value is MIN_VALUE, it overflows when made positive
if (num < 0)
{
i = size = stringSize(MAX_VALUE, radix) + 2;
buffer = new char[size];
buffer[--i] = digits[(int) (-(num + radix) % radix)];
num = -(num / radix);
}
else
{
i = size = stringSize(num, radix) + 1;
buffer = new char[size];
}
}
else
{
i = size = stringSize(num, radix);
buffer = new char[size];
}
do
{
buffer[--i] = digits[num % radix];
num /= radix;
}
while (num > 0);
if (isNeg)
buffer[--i] = '-';
// Package constructor avoids an array copy.
return new String(buffer, i, size - i, true);
}
/**
* Converts the int
to a String
assuming it is
* unsigned in base 16.
*
* @param i the int
to convert to String
* @return the String
representation of the argument
*/
public static String toHexString(int i)
{
return toUnsignedString(i, 4);
}
/**
* Converts the int
to a String
assuming it is
* unsigned in base 8.
*
* @param i the int
to convert to String
* @return the String
representation of the argument
*/
public static String toOctalString(int i)
{
return toUnsignedString(i, 3);
}
/**
* Converts the int
to a String
assuming it is
* unsigned in base 2.
*
* @param i the int
to convert to String
* @return the String
representation of the argument
*/
public static String toBinaryString(int i)
{
return toUnsignedString(i, 1);
}
/**
* Converts the int
to a String
and assumes
* a radix of 10.
*
* @param i the int
to convert to String
* @return the String
representation of the argument
* @see #toString(int, int)
*/
public static String toString(int i)
{
// This is tricky: in libgcj, String.valueOf(int) is a fast native
// implementation. In Classpath it just calls back to
// Integer.toString(int, int).
return String.valueOf(i);
}
/**
* Converts the specified String
into an int
* using the specified radix (base). The string must not be null
* or empty. It may begin with an optional '-', which will negate the answer,
* provided that there are also valid digits. Each digit is parsed as if by
* Character.digit(d, radix)
, and must be in the range
* 0
to radix - 1
. Finally, the result must be
* within MIN_VALUE
to MAX_VALUE
, inclusive.
* Unlike Double.parseDouble, you may not have a leading '+'.
*
* @param str the String
to convert
* @param radix the radix (base) to use in the conversion
* @return the String
argument converted to int
* @throws NumberFormatException if s
cannot be parsed as an
* int
*/
public static int parseInt(String str, int radix)
{
return parseInt(str, radix, false);
}
/**
* Converts the specified String
into an int
.
* This function assumes a radix of 10.
*
* @param s the String
to convert
* @return the int
value of s
* @throws NumberFormatException if s
cannot be parsed as an
* int
* @see #parseInt(String, int)
*/
public static int parseInt(String s)
{
return parseInt(s, 10, false);
}
/**
* Creates a new Integer
object using the String
* and specified radix (base).
*
* @param s the String
to convert
* @param radix the radix (base) to convert with
* @return the new Integer
* @throws NumberFormatException if s
cannot be parsed as an
* int
* @see #parseInt(String, int)
*/
public static Integer valueOf(String s, int radix)
{
return valueOf(parseInt(s, radix, false));
}
/**
* Creates a new Integer
object using the String
,
* assuming a radix of 10.
*
* @param s the String
to convert
* @return the new Integer
* @throws NumberFormatException if s
cannot be parsed as an
* int
* @see #Integer(String)
* @see #parseInt(String)
*/
public static Integer valueOf(String s)
{
return valueOf(parseInt(s, 10, false));
}
/**
* Returns an Integer
object wrapping the value.
* In contrast to the Integer
constructor, this method
* will cache some values. It is used by boxing conversion.
*
* @param val the value to wrap
* @return the Integer
*/
public static Integer valueOf(int val)
{
if (val < MIN_CACHE || val > MAX_CACHE)
return new Integer(val);
else
return intCache[val - MIN_CACHE];
}
/**
* Return the value of this Integer
as a byte
.
*
* @return the byte value
*/
public byte byteValue()
{
return (byte) value;
}
/**
* Return the value of this Integer
as a short
.
*
* @return the short value
*/
public short shortValue()
{
return (short) value;
}
/**
* Return the value of this Integer
.
* @return the int value
*/
public int intValue()
{
return value;
}
/**
* Return the value of this Integer
as a long
.
*
* @return the long value
*/
public long longValue()
{
return value;
}
/**
* Return the value of this Integer
as a float
.
*
* @return the float value
*/
public float floatValue()
{
return value;
}
/**
* Return the value of this Integer
as a double
.
*
* @return the double value
*/
public double doubleValue()
{
return value;
}
/**
* Converts the Integer
value to a String
and
* assumes a radix of 10.
*
* @return the String
representation
*/
public String toString()
{
return String.valueOf(value);
}
/**
* Return a hashcode representing this Object. Integer
's hash
* code is simply its value.
*
* @return this Object's hash code
*/
public int hashCode()
{
return value;
}
/**
* Returns true
if obj
is an instance of
* Integer
and represents the same int value.
*
* @param obj the object to compare
* @return whether these Objects are semantically equal
*/
public boolean equals(Object obj)
{
return obj instanceof Integer && value == ((Integer) obj).value;
}
/**
* Get the specified system property as an Integer
. The
* decode()
method will be used to interpret the value of
* the property.
*
* @param nm the name of the system property
* @return the system property as an Integer
, or null if the
* property is not found or cannot be decoded
* @throws SecurityException if accessing the system property is forbidden
* @see System#getProperty(String)
* @see #decode(String)
*/
public static Integer getInteger(String nm)
{
return getInteger(nm, null);
}
/**
* Get the specified system property as an Integer
, or use a
* default int
value if the property is not found or is not
* decodable. The decode()
method will be used to interpret
* the value of the property.
*
* @param nm the name of the system property
* @param val the default value
* @return the value of the system property, or the default
* @throws SecurityException if accessing the system property is forbidden
* @see System#getProperty(String)
* @see #decode(String)
*/
public static Integer getInteger(String nm, int val)
{
Integer result = getInteger(nm, null);
return result == null ? valueOf(val) : result;
}
/**
* Get the specified system property as an Integer
, or use a
* default Integer
value if the property is not found or is
* not decodable. The decode()
method will be used to
* interpret the value of the property.
*
* @param nm the name of the system property
* @param def the default value
* @return the value of the system property, or the default
* @throws SecurityException if accessing the system property is forbidden
* @see System#getProperty(String)
* @see #decode(String)
*/
public static Integer getInteger(String nm, Integer def)
{
if (nm == null || "".equals(nm))
return def;
nm = System.getProperty(nm);
if (nm == null)
return def;
try
{
return decode(nm);
}
catch (NumberFormatException e)
{
return def;
}
}
/**
* Convert the specified String
into an Integer
.
* The String
may represent decimal, hexadecimal, or
* octal numbers.
*
* The extended BNF grammar is as follows:
*
* DecodableString: * ( [* Finally, the value must be in the range-
] DecimalNumber ) * | ( [-
] (0x
|0X
* |#
) HexDigit { HexDigit } ) * | ( [-
]0
{ OctalDigit } ) * DecimalNumber: * DecimalDigit except '0' { DecimalDigit } * DecimalDigit: * Character.digit(d, 10) has value 0 to 9 * OctalDigit: * Character.digit(d, 8) has value 0 to 7 * DecimalDigit: * Character.digit(d, 16) has value 0 to 15 *
MIN_VALUE
to
* MAX_VALUE
, or an exception is thrown.
*
* @param str the String
to interpret
* @return the value of the String as an Integer
* @throws NumberFormatException if s
cannot be parsed as a
* int
* @throws NullPointerException if s
is null
* @since 1.2
*/
public static Integer decode(String str)
{
return valueOf(parseInt(str, 10, true));
}
/**
* Compare two Integers numerically by comparing their int
* values. The result is positive if the first is greater, negative if the
* second is greater, and 0 if the two are equal.
*
* @param i the Integer to compare
* @return the comparison
* @since 1.2
*/
public int compareTo(Integer i)
{
if (value == i.value)
return 0;
// Returns just -1 or 1 on inequality; doing math might overflow.
return value > i.value ? 1 : -1;
}
/**
* Return the number of bits set in x.
* @param x value to examine
* @since 1.5
*/
public static int bitCount(int x)
{
// Successively collapse alternating bit groups into a sum.
x = ((x >> 1) & 0x55555555) + (x & 0x55555555);
x = ((x >> 2) & 0x33333333) + (x & 0x33333333);
x = ((x >> 4) & 0x0f0f0f0f) + (x & 0x0f0f0f0f);
x = ((x >> 8) & 0x00ff00ff) + (x & 0x00ff00ff);
return ((x >> 16) & 0x0000ffff) + (x & 0x0000ffff);
}
/**
* Rotate x to the left by distance bits.
* @param x the value to rotate
* @param distance the number of bits by which to rotate
* @since 1.5
*/
public static int rotateLeft(int x, int distance)
{
// This trick works because the shift operators implicitly mask
// the shift count.
return (x << distance) | (x >>> - distance);
}
/**
* Rotate x to the right by distance bits.
* @param x the value to rotate
* @param distance the number of bits by which to rotate
* @since 1.5
*/
public static int rotateRight(int x, int distance)
{
// This trick works because the shift operators implicitly mask
// the shift count.
return (x << - distance) | (x >>> distance);
}
/**
* Find the highest set bit in value, and return a new value
* with only that bit set.
* @param value the value to examine
* @since 1.5
*/
public static int highestOneBit(int value)
{
value |= value >>> 1;
value |= value >>> 2;
value |= value >>> 4;
value |= value >>> 8;
value |= value >>> 16;
return value ^ (value >>> 1);
}
/**
* Return the number of leading zeros in value.
* @param value the value to examine
* @since 1.5
*/
public static int numberOfLeadingZeros(int value)
{
value |= value >>> 1;
value |= value >>> 2;
value |= value >>> 4;
value |= value >>> 8;
value |= value >>> 16;
return bitCount(~value);
}
/**
* Find the lowest set bit in value, and return a new value
* with only that bit set.
* @param value the value to examine
* @since 1.5
*/
public static int lowestOneBit(int value)
{
// Classic assembly trick.
return value & - value;
}
/**
* Find the number of trailing zeros in value.
* @param value the value to examine
* @since 1.5
*/
public static int numberOfTrailingZeros(int value)
{
return bitCount((value & -value) - 1);
}
/**
* Return 1 if x is positive, -1 if it is negative, and 0 if it is
* zero.
* @param x the value to examine
* @since 1.5
*/
public static int signum(int x)
{
return (x >> 31) | (-x >>> 31);
// The LHS propagates the sign bit through every bit in the word;
// if X < 0, every bit is set to 1, else 0. if X > 0, the RHS
// negates x and shifts the resulting 1 in the sign bit to the
// LSB, leaving every other bit 0.
// Hacker's Delight, Section 2-7
}
/**
* Reverse the bytes in val.
* @since 1.5
*/
public static int reverseBytes(int val)
{
return ( ((val >> 24) & 0xff)
| ((val >> 8) & 0xff00)
| ((val << 8) & 0xff0000)
| ((val << 24) & 0xff000000));
}
/**
* Reverse the bits in val.
* @since 1.5
*/
public static int reverse(int val)
{
// Successively swap alternating bit groups.
val = ((val >> 1) & 0x55555555) + ((val << 1) & ~0x55555555);
val = ((val >> 2) & 0x33333333) + ((val << 2) & ~0x33333333);
val = ((val >> 4) & 0x0f0f0f0f) + ((val << 4) & ~0x0f0f0f0f);
val = ((val >> 8) & 0x00ff00ff) + ((val << 8) & ~0x00ff00ff);
return ((val >> 16) & 0x0000ffff) + ((val << 16) & ~0x0000ffff);
}
/**
* Helper for converting unsigned numbers to String.
*
* @param num the number
* @param exp log2(digit) (ie. 1, 3, or 4 for binary, oct, hex)
*/
// Package visible for use by Long.
static String toUnsignedString(int num, int exp)
{
// Compute string length
int size = 1;
int copy = num >>> exp;
while (copy != 0)
{
size++;
copy >>>= exp;
}
// Quick path for single character strings
if (size == 1)
return new String(digits, num, 1, true);
// Encode into buffer
int mask = (1 << exp) - 1;
char[] buffer = new char[size];
int i = size;
do
{
buffer[--i] = digits[num & mask];
num >>>= exp;
}
while (num != 0);
// Package constructor avoids an array copy.
return new String(buffer, i, size - i, true);
}
/**
* Helper for parsing ints, used by Integer, Short, and Byte.
*
* @param str the string to parse
* @param radix the radix to use, must be 10 if decode is true
* @param decode if called from decode
* @return the parsed int value
* @throws NumberFormatException if there is an error
* @throws NullPointerException if decode is true and str if null
* @see #parseInt(String, int)
* @see #decode(String)
* @see Byte#parseByte(String, int)
* @see Short#parseShort(String, int)
*/
static int parseInt(String str, int radix, boolean decode)
{
if (! decode && str == null)
throw new NumberFormatException();
int index = 0;
int len = str.length();
boolean isNeg = false;
if (len == 0)
throw new NumberFormatException("string length is null");
int ch = str.charAt(index);
if (ch == '-')
{
if (len == 1)
throw new NumberFormatException("pure '-'");
isNeg = true;
ch = str.charAt(++index);
}
else if (ch == '+')
{
if (len == 1)
throw new NumberFormatException("pure '+'");
ch = str.charAt(++index);
}
if (decode)
{
if (ch == '0')
{
if (++index == len)
return 0;
if ((str.charAt(index) & ~('x' ^ 'X')) == 'X')
{
radix = 16;
index++;
}
else
radix = 8;
}
else if (ch == '#')
{
radix = 16;
index++;
}
}
if (index == len)
throw new NumberFormatException("non terminated number: " + str);
int max = MAX_VALUE / radix;
// We can't directly write `max = (MAX_VALUE + 1) / radix'.
// So instead we fake it.
if (isNeg && MAX_VALUE % radix == radix - 1)
++max;
int val = 0;
while (index < len)
{
if (val < 0 || val > max)
throw new NumberFormatException("number overflow (pos=" + index + ") : " + str);
ch = Character.digit(str.charAt(index++), radix);
val = val * radix + ch;
if (ch < 0 || (val < 0 && (! isNeg || val != MIN_VALUE)))
throw new NumberFormatException("invalid character at position " + index + " in " + str);
}
return isNeg ? -val : val;
}
}