/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 java.lang; /** * The wrapper for the primitive type {@code int}. * <p> * As with the specification, this implementation relies on code laid out in <a * href="http://www.hackersdelight.org/">Henry S. Warren, Jr.'s Hacker's Delight, (Addison Wesley, * 2002)</a> as well as <a href="http://aggregate.org/MAGIC/">The Aggregate's Magic Algorithms</a>. * * JUniversal REMOVED: * * getInteger since System.getProperty isn't supported * * TYPE since there are no Class objects currently * * longValue * * * @see java.lang.Number * @since 1.1 */ public final class Integer extends Number implements Comparable<Integer> { /** * The value which the receiver represents. */ private final int value; /** * Constant for the maximum {@code int} value, 2<sup>31</sup>-1. */ public static final int MAX_VALUE = 0x7FFFFFFF; /** * Constant for the minimum {@code int} value, -2<sup>31</sup>. */ public static final int MIN_VALUE = 0x80000000; /** * Constant for the number of bits needed to represent an {@code int} in * two's complement form. * * @since 1.5 */ public static final int SIZE = 32; /* * Progressively smaller decimal order of magnitude that can be represented * by an instance of Integer. Used to help compute the String * representation. */ //private static final int[] decimalScale = new int[] { 1000000000, 100000000, // 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1 }; private static int[] decimalScale = null; // Note: This can't be set to "int.class", since *that* is // defined to be "java.lang.Integer.TYPE"; /** * Constructs a new {@code Integer} with the specified primitive integer * value. * * @param value * the primitive integer value to store in the new instance. */ public Integer(int value) { this.value = value; } /** * Constructs a new {@code Integer} from the specified string. * * @param string * the string representation of an integer value. * @throws NumberFormatException * if {@code string} can not be decoded into an integer value. * @see #parseInt(String) */ public Integer(String string) throws NumberFormatException { this.value = parseInt(string); } @Override public byte byteValue() { return (byte) value; } /** * Compares this object to the specified integer object to determine their * relative order. * * @param object * the integer object to compare this object to. * @return a negative value if the value of this integer is less than the * value of {@code object}; 0 if the value of this integer and the * value of {@code object} are equal; a positive value if the value * of this integer is greater than the value of {@code object}. * @see java.lang.Comparable * @since 1.2 */ public int compareTo(Integer object) { return value > object.value ? 1 : (value < object.value ? -1 : 0); } /** * Parses the specified string and returns a {@code Integer} instance if the * string can be decoded into an integer value. The string may be an * optional minus sign "-" followed by a hexadecimal ("0x..." or "#..."), * octal ("0..."), or decimal ("...") representation of an integer. * * @param string * a string representation of an integer value. * @return an {@code Integer} containing the value represented by * {@code string}. * @throws NumberFormatException * if {@code string} can not be parsed as an integer value. */ public static Integer decode(String string) throws NumberFormatException { int length = string.length(), i = 0; if (length == 0) { throw new NumberFormatException(); } char firstDigit = string.charAt(i); boolean negative = firstDigit == '-'; if (negative) { if (length == 1) { throw new NumberFormatException(string); } firstDigit = string.charAt(++i); } int base = 10; if (firstDigit == '0') { if (++i == length) { return valueOf(0); } if ((firstDigit = string.charAt(i)) == 'x' || firstDigit == 'X') { if (++i == length) { throw new NumberFormatException(string); } base = 16; } else { base = 8; } } else if (firstDigit == '#') { if (++i == length) { throw new NumberFormatException(string); } base = 16; } int result = parse(string, i, base, negative); return valueOf(result); } @Override public double doubleValue() { return value; } /** * Compares this instance with the specified object and indicates if they * are equal. In order to be equal, {@code o} must be an instance of * {@code Integer} and have the same integer value as this object. * * @param o * the object to compare this integer with. * @return {@code true} if the specified object is equal to this * {@code Integer}; {@code false} otherwise. */ @Override public boolean equals(Object o) { return (o instanceof Integer) && (value == ((Integer) o).value); } @Override public float floatValue() { return value; } @Override public int hashCode() { return value; } /** * Gets the primitive value of this int. * * @return this object's primitive value. */ @Override public int intValue() { return value; } /** * Parses the specified string as a signed decimal integer value. The ASCII * character \u002d ('-') is recognized as the minus sign. * * @param string * the string representation of an integer value. * @return the primitive integer value represented by {@code string}. * @throws NumberFormatException * if {@code string} is {@code null}, has a length of zero or * can not be parsed as an integer value. */ public static int parseInt(String string) throws NumberFormatException { return parseInt(string, 10); } /** * Parses the specified string as a signed integer value using the specified * radix. The ASCII character \u002d ('-') is recognized as the minus sign. * * @param string * the string representation of an integer value. * @param radix * the radix to use when parsing. * @return the primitive integer value represented by {@code string} using * {@code radix}. * @throws NumberFormatException * if {@code string} is {@code null} or has a length of zero, * {@code radix < Character.MIN_RADIX}, * {@code radix > Character.MAX_RADIX}, or if {@code string} * can not be parsed as an integer value. */ public static int parseInt(String string, int radix) throws NumberFormatException { if (string == null || radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) { throw new NumberFormatException(); } int length = string.length(), i = 0; if (length == 0) { throw new NumberFormatException(string); } boolean negative = string.charAt(i) == '-'; if (negative && ++i == length) { throw new NumberFormatException(string); } return parse(string, i, radix, negative); } private static int parse(String string, int offset, int radix, boolean negative) throws NumberFormatException { int max = Integer.MIN_VALUE / radix; int result = 0, length = string.length(); while (offset < length) { int digit = Character.digit(string.charAt(offset++), radix); if (digit == -1) { throw new NumberFormatException(string); } if (max > result) { throw new NumberFormatException(string); } int next = result * radix - digit; if (next > result) { throw new NumberFormatException(string); } result = next; } if (!negative) { result = -result; if (result < 0) { throw new NumberFormatException(string); } } return result; } @Override public short shortValue() { return (short) value; } /** * Converts the specified integer into its binary string representation. The * returned string is a concatenation of '0' and '1' characters. * * @param i * the integer to convert. * @return the binary string representation of {@code i}. */ public static String toBinaryString(int i) { int count = 1, j = i; if (i < 0) { count = 32; } else { while ((j >>>= 1) != 0) { count++; } } String buffer = new String(count); char[] bufferValue = buffer.getValue(); do { bufferValue[--count] = (char) ((i & 1) + '0'); i >>>= 1; } while (count > 0); return buffer; } /** * Converts the specified integer into its hexadecimal string * representation. The returned string is a concatenation of characters from * '0' to '9' and 'a' to 'f'. * * @param i * the integer to convert. * @return the hexadecimal string representation of {@code i}. */ public static String toHexString(int i) { int count = 1, j = i; if (i < 0) { count = 8; } else { while ((j >>>= 4) != 0) { count++; } } String buffer = new String(count); char[] bufferValue = buffer.getValue(); do { int t = i & 15; if (t > 9) { t = t - 10 + 'a'; } else { t += '0'; } bufferValue[--count] = (char) t; i >>>= 4; } while (count > 0); return buffer; } /** * Converts the specified integer into its octal string representation. The * returned string is a concatenation of characters from '0' to '7'. * * @param i * the integer to convert. * @return the octal string representation of {@code i}. */ public static String toOctalString(int i) { int count = 1, j = i; if (i < 0) { count = 11; } else { while ((j >>>= 3) != 0) { count++; } } String buffer = new String(count); char[] bufferValue = buffer.getValue(); do { bufferValue[--count] = (char) ((i & 7) + '0'); i >>>= 3; } while (count > 0); return buffer; } @Override public String toString() { return Integer.toString(value); } /** * Converts the specified integer into its decimal string representation. * The returned string is a concatenation of a minus sign if the number is * negative and characters from '0' to '9'. * * @param value * the integer to convert. * @return the decimal string representation of {@code value}. */ public static String toString(int value) { // TODO: Switch back to array with initializer when it's supported if (decimalScale == null) { decimalScale[0] = 1000000000; decimalScale[1] = 100000000; decimalScale[2] = 10000000; decimalScale[3] = 1000000; decimalScale[4] = 100000; decimalScale[5] = 10000; decimalScale[6] = 1000; decimalScale[7] = 100; decimalScale[8] = 10; decimalScale[9] = 1; } if (value == 0) { return "0"; //$NON-NLS-1$ } // Faster algorithm for smaller Integers if (value < 1000 && value > -1000) { char[] buffer = new char[4]; int positive_value = value < 0 ? -value : value; int first_digit = 0; if (value < 0) { buffer[0] = '-'; first_digit++; } int last_digit = first_digit; int quot = positive_value; do { int res = quot / 10; int digit_value = quot - ((res << 3) + (res << 1)); digit_value += '0'; buffer[last_digit++] = (char) digit_value; quot = res; } while (quot != 0); int count = last_digit--; do { char tmp = buffer[last_digit]; buffer[last_digit--] = buffer[first_digit]; buffer[first_digit++] = tmp; } while (first_digit < last_digit); return new String(buffer, 0, count); } if (value == MIN_VALUE) { return "-2147483648";//$NON-NLS-1$ } char[] buffer = new char[11]; int positive_value = value < 0 ? -value : value; byte first_digit = 0; if (value < 0) { buffer[0] = '-'; first_digit++; } byte last_digit = first_digit; byte count; int number; boolean start = false; for (int i = 0; i < 9; i++) { count = 0; if (positive_value < (number = decimalScale[i])) { if (start) { buffer[last_digit++] = '0'; } continue; } if (i > 0) { number = (decimalScale[i] << 3); if (positive_value >= number) { positive_value -= number; count += 8; } number = (decimalScale[i] << 2); if (positive_value >= number) { positive_value -= number; count += 4; } } number = (decimalScale[i] << 1); if (positive_value >= number) { positive_value -= number; count += 2; } if (positive_value >= decimalScale[i]) { positive_value -= decimalScale[i]; count++; } if (count > 0 && !start) { start = true; } if (start) { buffer[last_digit++] = (char) (count + '0'); } } buffer[last_digit++] = (char) (positive_value + '0'); count = last_digit--; return new String(buffer, 0, count); } /** * Converts the specified integer into a string representation based on the * specified radix. The returned string is a concatenation of a minus sign * if the number is negative and characters from '0' to '9' and 'a' to 'z', * depending on the radix. If {@code radix} is not in the interval defined * by {@code Character.MIN_RADIX} and {@code Character.MAX_RADIX} then 10 is * used as the base for the conversion. * * @param i * the integer to convert. * @param radix * the base to use for the conversion. * @return the string representation of {@code i}. */ public static String toString(int i, int radix) { if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) { radix = 10; } if (i == 0) { return "0"; //$NON-NLS-1$ } int count = 2, j = i; boolean negative = i < 0; if (!negative) { count = 1; j = -i; } while ((i /= radix) != 0) { count++; } String buffer = new String(count); char[] bufferValue = buffer.getValue(); do { int ch = 0 - (j % radix); if (ch > 9) { ch = ch - 10 + 'a'; } else { ch += '0'; } bufferValue[--count] = (char) ch; } while ((j /= radix) != 0); if (negative) { bufferValue[0] = '-'; } return buffer; } /** * Parses the specified string as a signed decimal integer value. * * @param string * the string representation of an integer value. * @return an {@code Integer} instance containing the integer value * represented by {@code string}. * @throws NumberFormatException * if {@code string} is {@code null}, has a length of zero or * can not be parsed as an integer value. * @see #parseInt(String) */ public static Integer valueOf(String string) throws NumberFormatException { return valueOf(parseInt(string)); } /** * Parses the specified string as a signed integer value using the specified * radix. * * @param string * the string representation of an integer value. * @param radix * the radix to use when parsing. * @return an {@code Integer} instance containing the integer value * represented by {@code string} using {@code radix}. * @throws NumberFormatException * if {@code string} is {@code null} or has a length of zero, * {@code radix < Character.MIN_RADIX}, * {@code radix > Character.MAX_RADIX}, or if {@code string} * can not be parsed as an integer value. * @see #parseInt(String, int) */ public static Integer valueOf(String string, int radix) throws NumberFormatException { return valueOf(parseInt(string, radix)); } /** * Determines the highest (leftmost) bit of the specified integer that is 1 * and returns the bit mask value for that bit. This is also referred to as * the Most Significant 1 Bit. Returns zero if the specified integer is * zero. * * @param i * the integer to examine. * @return the bit mask indicating the highest 1 bit in {@code i}. * @since 1.5 */ public static int highestOneBit(int i) { i |= (i >> 1); i |= (i >> 2); i |= (i >> 4); i |= (i >> 8); i |= (i >> 16); return (i & ~(i >>> 1)); } /** * Determines the lowest (rightmost) bit of the specified integer that is 1 * and returns the bit mask value for that bit. This is also referred * to as the Least Significant 1 Bit. Returns zero if the specified integer * is zero. * * @param i * the integer to examine. * @return the bit mask indicating the lowest 1 bit in {@code i}. * @since 1.5 */ public static int lowestOneBit(int i) { return (i & (-i)); } /** * Determines the number of leading zeros in the specified integer prior to * the {@link #highestOneBit(int) highest one bit}. * * @param i * the integer to examine. * @return the number of leading zeros in {@code i}. * @since 1.5 */ public static int numberOfLeadingZeros(int i) { i |= i >> 1; i |= i >> 2; i |= i >> 4; i |= i >> 8; i |= i >> 16; return bitCount(~i); } /** * Determines the number of trailing zeros in the specified integer after * the {@link #lowestOneBit(int) lowest one bit}. * * @param i * the integer to examine. * @return the number of trailing zeros in {@code i}. * @since 1.5 */ public static int numberOfTrailingZeros(int i) { return bitCount((i & -i) - 1); } /** * Counts the number of 1 bits in the specified integer; this is also * referred to as population count. * * @param i * the integer to examine. * @return the number of 1 bits in {@code i}. * @since 1.5 */ public static int bitCount(int i) { i -= ((i >> 1) & 0x55555555); i = (i & 0x33333333) + ((i >> 2) & 0x33333333); i = (((i >> 4) + i) & 0x0F0F0F0F); i += (i >> 8); i += (i >> 16); return (i & 0x0000003F); } /** * Rotates the bits of the specified integer to the left by the specified * number of bits. * * @param i * the integer value to rotate left. * @param distance * the number of bits to rotate. * @return the rotated value. * @since 1.5 */ public static int rotateLeft(int i, int distance) { if (distance == 0) { return i; } /* * According to JLS3, 15.19, the right operand of a shift is always * implicitly masked with 0x1F, which the negation of 'distance' is * taking advantage of. */ return ((i << distance) | (i >>> (-distance))); } /** * Rotates the bits of the specified integer to the right by the specified * number of bits. * * @param i * the integer value to rotate right. * @param distance * the number of bits to rotate. * @return the rotated value. * @since 1.5 */ public static int rotateRight(int i, int distance) { if (distance == 0) { return i; } /* * According to JLS3, 15.19, the right operand of a shift is always * implicitly masked with 0x1F, which the negation of 'distance' is * taking advantage of. */ return ((i >>> distance) | (i << (-distance))); } /** * Reverses the order of the bytes of the specified integer. * * @param i * the integer value for which to reverse the byte order. * @return the reversed value. * @since 1.5 */ public static int reverseBytes(int i) { int b3 = i >>> 24; int b2 = (i >>> 8) & 0xFF00; int b1 = (i & 0xFF00) << 8; int b0 = i << 24; return (b0 | b1 | b2 | b3); } /** * Reverses the order of the bits of the specified integer. * * @param i * the integer value for which to reverse the bit order. * @return the reversed value. * @since 1.5 */ public static int reverse(int i) { // From Hacker's Delight, 7-1, Figure 7-1 i = (i & 0x55555555) << 1 | (i >> 1) & 0x55555555; i = (i & 0x33333333) << 2 | (i >> 2) & 0x33333333; i = (i & 0x0F0F0F0F) << 4 | (i >> 4) & 0x0F0F0F0F; return reverseBytes(i); } /** * Returns the value of the {@code signum} function for the specified * integer. * * @param i * the integer value to check. * @return -1 if {@code i} is negative, 1 if {@code i} is positive, 0 if * {@code i} is zero. * @since 1.5 */ public static int signum(int i) { return (i == 0 ? 0 : (i < 0 ? -1 : 1)); } /** * Returns a {@code Integer} instance for the specified integer value. * <p> * If it is not necessary to get a new {@code Integer} instance, it is * recommended to use this method instead of the constructor, since it * maintains a cache of instances which may result in better performance. * * JUniversal CHANGE: Removed the valueOfCache, which cached -128 to 127, in * order to make things a little simpler & since static initializers aren't * currently supported. * * @param i * the integer value to store in the instance. * @return a {@code Integer} instance containing {@code i}. * @since 1.5 */ public static Integer valueOf(int i) { return new Integer(i); } }