Integer.java revision adc854b798c1cfe3bfd4c27d68d5cee38ca617da
1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package java.lang;
19
20/**
21 * The wrapper for the primitive type {@code int}.
22 * <p>
23 * As with the specification, this implementation relies on code laid out in <a
24 * href="http://www.hackersdelight.org/">Henry S. Warren, Jr.'s Hacker's
25 * Delight, (Addison Wesley, 2002)</a> as well as <a
26 * href="http://aggregate.org/MAGIC/">The Aggregate's Magic Algorithms</a>.
27 * </p>
28 *
29 * @see java.lang.Number
30 * @since Android 1.0
31 */
32public final class Integer extends Number implements Comparable<Integer> {
33
34    private static final long serialVersionUID = 1360826667806852920L;
35
36    /**
37     * The value which the receiver represents.
38     */
39    private final int value;
40
41    /**
42     * Constant for the maximum {@code int} value, 2<sup>31</sup>-1.
43     *
44     * @since Android 1.0
45     */
46    public static final int MAX_VALUE = 0x7FFFFFFF;
47
48    /**
49     * Constant for the minimum {@code int} value, -2<sup>31</sup>.
50     *
51     * @since Android 1.0
52     */
53    public static final int MIN_VALUE = 0x80000000;
54
55    /**
56     * Constant for the number of bits needed to represent an {@code int} in
57     * two's complement form.
58     *
59     * @since Android 1.0
60     */
61    public static final int SIZE = 32;
62
63    /**
64     * The {@link Class} object that represents the primitive type {@code int}.
65     *
66     * @since Android 1.0
67     */
68    @SuppressWarnings("unchecked")
69    public static final Class<Integer> TYPE = (Class<Integer>) new int[0]
70            .getClass().getComponentType();
71
72    // Note: This can't be set to "int.class", since *that* is
73    // defined to be "java.lang.Integer.TYPE";
74
75    /**
76     * Constructs a new {@code Integer} with the specified primitive integer
77     * value.
78     *
79     * @param value
80     *            the primitive integer value to store in the new instance.
81     * @since Android 1.0
82     */
83    public Integer(int value) {
84        this.value = value;
85    }
86
87    /**
88     * Constructs a new {@code Integer} from the specified string.
89     *
90     * @param string
91     *            the string representation of an integer value.
92     * @throws NumberFormatException
93     *             if {@code string} can not be decoded into an integer value.
94     * @see #parseInt(String)
95     * @since Android 1.0
96     */
97    public Integer(String string) throws NumberFormatException {
98        this(parseInt(string));
99    }
100
101    @Override
102    public byte byteValue() {
103        return (byte) value;
104    }
105
106    /**
107     * Compares this object to the specified integer object to determine their
108     * relative order.
109     *
110     * @param object
111     *            the integer object to compare this object to.
112     * @return a negative value if the value of this integer is less than the
113     *         value of {@code object}; 0 if the value of this integer and the
114     *         value of {@code object} are equal; a positive value if the value
115     *         of this integer is greater than the value of {@code object}.
116     * @see java.lang.Comparable
117     * @since Android 1.0
118     */
119    public int compareTo(Integer object) {
120        return value > object.value ? 1 : (value < object.value ? -1 : 0);
121    }
122
123    /**
124     * Parses the specified string and returns a {@code Integer} instance if the
125     * string can be decoded into an integer value. The string may be an
126     * optional minus sign "-" followed by a hexadecimal ("0x..." or "#..."),
127     * octal ("0..."), or decimal ("...") representation of an integer.
128     *
129     * @param string
130     *            a string representation of an integer value.
131     * @return an {@code Integer} containing the value represented by
132     *         {@code string}.
133     * @throws NumberFormatException
134     *             if {@code string} can not be parsed as an integer value.
135     * @since Android 1.0
136     */
137    public static Integer decode(String string) throws NumberFormatException {
138        int length = string.length(), i = 0;
139        if (length == 0) {
140            // BEGIN android-changed
141            throw new NumberFormatException("unable to parse '"+string+"' as integer");
142            // END android-changed
143        }
144        char firstDigit = string.charAt(i);
145        boolean negative = firstDigit == '-';
146        if (negative) {
147            if (length == 1) {
148                // BEGIN android-changed
149                throw new NumberFormatException("unable to parse '"+string+"' as integer");
150                // END android-changed
151            }
152            firstDigit = string.charAt(++i);
153        }
154
155        int base = 10;
156        if (firstDigit == '0') {
157            if (++i == length) {
158                return valueOf(0);
159            }
160            if ((firstDigit = string.charAt(i)) == 'x' || firstDigit == 'X') {
161                if (i == length) {
162                    // BEGIN android-changed
163                    throw new NumberFormatException("unable to parse '"+string+"' as integer");
164                    // END android-changed
165                }
166                i++;
167                base = 16;
168            } else {
169                base = 8;
170            }
171        } else if (firstDigit == '#') {
172            if (i == length) {
173                // BEGIN android-changed
174                throw new NumberFormatException("unable to parse '"+string+"' as integer");
175                // END android-changed
176            }
177            i++;
178            base = 16;
179        }
180
181        int result = parse(string, i, base, negative);
182        return valueOf(result);
183    }
184
185    @Override
186    public double doubleValue() {
187        return value;
188    }
189
190    /**
191     * Compares this instance with the specified object and indicates if they
192     * are equal. In order to be equal, {@code o} must be an instance of
193     * {@code Integer} and have the same integer value as this object.
194     *
195     * @param o
196     *            the object to compare this integer with.
197     * @return {@code true} if the specified object is equal to this
198     *         {@code Integer}; {@code false} otherwise.
199     * @since Android 1.0
200     */
201    @Override
202    public boolean equals(Object o) {
203        return (o instanceof Integer)
204                && (value == ((Integer) o).value);
205    }
206
207    @Override
208    public float floatValue() {
209        return value;
210    }
211
212    /**
213     * Returns the {@code Integer} value of the system property identified by
214     * {@code string}. Returns {@code null} if {@code string} is {@code null}
215     * or empty, if the property can not be found or if its value can not be
216     * parsed as an integer.
217     *
218     * @param string
219     *            the name of the requested system property.
220     * @return the requested property's value as an {@code Integer} or
221     *         {@code null}.
222     * @since Android 1.0
223     */
224    public static Integer getInteger(String string) {
225        if (string == null || string.length() == 0) {
226            return null;
227        }
228        String prop = System.getProperty(string);
229        if (prop == null) {
230            return null;
231        }
232        try {
233            return decode(prop);
234        } catch (NumberFormatException ex) {
235            return null;
236        }
237    }
238
239    /**
240     * Returns the {@code Integer} value of the system property identified by
241     * {@code string}. Returns the specified default value if {@code string} is
242     * {@code null} or empty, if the property can not be found or if its value
243     * can not be parsed as an integer.
244     *
245     * @param string
246     *            the name of the requested system property.
247     * @param defaultValue
248     *            the default value that is returned if there is no integer
249     *            system property with the requested name.
250     * @return the requested property's value as an {@code Integer} or the
251     *         default value.
252     * @since Android 1.0
253     */
254    public static Integer getInteger(String string, int defaultValue) {
255        if (string == null || string.length() == 0) {
256            return valueOf(defaultValue);
257        }
258        String prop = System.getProperty(string);
259        if (prop == null) {
260            return valueOf(defaultValue);
261        }
262        try {
263            return decode(prop);
264        } catch (NumberFormatException ex) {
265            return valueOf(defaultValue);
266        }
267    }
268
269    /**
270     * Returns the {@code Integer} value of the system property identified by
271     * {@code string}. Returns the specified default value if {@code string} is
272     * {@code null} or empty, if the property can not be found or if its value
273     * can not be parsed as an integer.
274     *
275     * @param string
276     *            the name of the requested system property.
277     * @param defaultValue
278     *            the default value that is returned if there is no integer
279     *            system property with the requested name.
280     * @return the requested property's value as an {@code Integer} or the
281     *         default value.
282     * @since Android 1.0
283     */
284    public static Integer getInteger(String string, Integer defaultValue) {
285        if (string == null || string.length() == 0) {
286            return defaultValue;
287        }
288        String prop = System.getProperty(string);
289        if (prop == null) {
290            return defaultValue;
291        }
292        try {
293            return decode(prop);
294        } catch (NumberFormatException ex) {
295            return defaultValue;
296        }
297    }
298
299    @Override
300    public int hashCode() {
301        return value;
302    }
303
304    /**
305     * Gets the primitive value of this int.
306     *
307     * @return this object's primitive value.
308     * @since Android 1.0
309     */
310    @Override
311    public int intValue() {
312        return value;
313    }
314
315    @Override
316    public long longValue() {
317        return value;
318    }
319
320    /**
321     * Parses the specified string as a signed decimal integer value. The ASCII
322     * character \u002d ('-') is recognized as the minus sign.
323     *
324     * @param string
325     *            the string representation of an integer value.
326     * @return the primitive integer value represented by {@code string}.
327     * @throws NumberFormatException
328     *             if {@code string} is {@code null}, has a length of zero or
329     *             can not be parsed as an integer value.
330     * @since Android 1.0
331     */
332    public static int parseInt(String string) throws NumberFormatException {
333        return parseInt(string, 10);
334    }
335
336    /**
337     * Parses the specified string as a signed integer value using the specified
338     * radix. The ASCII character \u002d ('-') is recognized as the minus sign.
339     *
340     * @param string
341     *            the string representation of an integer value.
342     * @param radix
343     *            the radix to use when parsing.
344     * @return the primitive integer value represented by {@code string} using
345     *         {@code radix}.
346     * @throws NumberFormatException
347     *             if {@code string} is {@code null} or has a length of zero,
348     *             {@code radix < Character.MIN_RADIX},
349     *             {@code radix > Character.MAX_RADIX}, or if {@code string}
350     *             can not be parsed as an integer value.
351     * @since Android 1.0
352     */
353    public static int parseInt(String string, int radix)
354            throws NumberFormatException {
355        if (string == null || radix < Character.MIN_RADIX
356                || radix > Character.MAX_RADIX) {
357            // BEGIN android-changed
358            throw new NumberFormatException("unable to parse '"+string+"' as integer");
359            // END android-changed
360        }
361        int length = string.length(), i = 0;
362        if (length == 0) {
363            // BEGIN android-changed
364            throw new NumberFormatException("unable to parse '"+string+"' as integer");
365            // END android-changed
366        }
367        boolean negative = string.charAt(i) == '-';
368        if (negative && ++i == length) {
369            // BEGIN android-changed
370            throw new NumberFormatException("unable to parse '"+string+"' as integer");
371            // END android-changed
372        }
373
374        return parse(string, i, radix, negative);
375    }
376
377    private static int parse(String string, int offset, int radix,
378            boolean negative) throws NumberFormatException {
379        int max = Integer.MIN_VALUE / radix;
380        int result = 0, length = string.length();
381        while (offset < length) {
382            int digit = Character.digit(string.charAt(offset++), radix);
383            if (digit == -1) {
384                // BEGIN android-changed
385                throw new NumberFormatException("unable to parse '"+string+"' as integer");
386                // END android-changed
387            }
388            if (max > result) {
389                // BEGIN android-changed
390                throw new NumberFormatException("unable to parse '"+string+"' as integer");
391                // END android-changed
392            }
393            int next = result * radix - digit;
394            if (next > result) {
395                // BEGIN android-changed
396                throw new NumberFormatException("unable to parse '"+string+"' as integer");
397                // END android-changed
398            }
399            result = next;
400        }
401        if (!negative) {
402            result = -result;
403            if (result < 0) {
404                // BEGIN android-changed
405                throw new NumberFormatException("unable to parse '"+string+"' as integer");
406                // END android-changed
407            }
408        }
409        return result;
410    }
411
412    @Override
413    public short shortValue() {
414        return (short) value;
415    }
416
417    /**
418     * Converts the specified integer into its binary string representation. The
419     * returned string is a concatenation of '0' and '1' characters.
420     *
421     * @param i
422     *            the integer to convert.
423     * @return the binary string representation of {@code i}.
424     * @since Android 1.0
425     */
426    public static String toBinaryString(int i) {
427        int count = 1, j = i;
428
429        if (i < 0) {
430            count = 32;
431        } else {
432            while ((j >>>= 1) != 0) {
433                count++;
434            }
435        }
436
437        char[] buffer = new char[count];
438        do {
439            buffer[--count] = (char) ((i & 1) + '0');
440            i >>>= 1;
441        } while (count > 0);
442        return new String(0, buffer.length, buffer);
443    }
444
445    /**
446     * Converts the specified integer into its hexadecimal string
447     * representation. The returned string is a concatenation of characters from
448     * '0' to '9' and 'a' to 'f'.
449     *
450     * @param i
451     *            the integer to convert.
452     * @return the hexadecimal string representation of {@code i}.
453     * @since Android 1.0
454     */
455    public static String toHexString(int i) {
456        int count = 1, j = i;
457
458        if (i < 0) {
459            count = 8;
460        } else {
461            while ((j >>>= 4) != 0) {
462                count++;
463            }
464        }
465
466        char[] buffer = new char[count];
467        do {
468            int t = i & 15;
469            if (t > 9) {
470                t = t - 10 + 'a';
471            } else {
472                t += '0';
473            }
474            buffer[--count] = (char) t;
475            i >>>= 4;
476        } while (count > 0);
477        return new String(0, buffer.length, buffer);
478    }
479
480    /**
481     * Converts the specified integer into its octal string representation. The
482     * returned string is a concatenation of characters from '0' to '7'.
483     *
484     * @param i
485     *            the integer to convert.
486     * @return the octal string representation of {@code i}.
487     * @since Android 1.0
488     */
489    public static String toOctalString(int i) {
490        int count = 1, j = i;
491
492        if (i < 0) {
493            count = 11;
494        } else {
495            while ((j >>>= 3) != 0) {
496                count++;
497            }
498        }
499
500        char[] buffer = new char[count];
501        do {
502            buffer[--count] = (char) ((i & 7) + '0');
503            i >>>= 3;
504        } while (count > 0);
505        return new String(0, buffer.length, buffer);
506    }
507
508    @Override
509    public String toString() {
510        return Integer.toString(value);
511    }
512
513    /**
514     * Converts the specified integer into its decimal string representation.
515     * The returned string is a concatenation of a minus sign if the number is
516     * negative and characters from '0' to '9'.
517     *
518     * @param i
519     *            the integer to convert.
520     * @return the decimal string representation of {@code i}.
521     * @since Android 1.0
522     */
523    public static String toString(int i) {
524        return toString(i, 10);
525    }
526
527    /**
528     * Converts the specified integer into a string representation based on the
529     * specified radix. The returned string is a concatenation of a minus sign
530     * if the number is negative and characters from '0' to '9' and 'a' to 'z',
531     * depending on the radix. If {@code radix} is not in the interval defined
532     * by {@code Character.MIN_RADIX} and {@code Character.MAX_RADIX} then 10 is
533     * used as the base for the conversion.
534     *
535     * @param i
536     *            the integer to convert.
537     * @param radix
538     *            the base to use for the conversion.
539     * @return the string representation of {@code i}.
540     * @since Android 1.0
541     */
542    public static String toString(int i, int radix) {
543        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
544            radix = 10;
545        }
546        if (i == 0) {
547            return "0"; //$NON-NLS-1$
548        }
549
550        int count = 2, j = i;
551        boolean negative = i < 0;
552        if (!negative) {
553            count = 1;
554            j = -i;
555        }
556        while ((i /= radix) != 0) {
557            count++;
558        }
559
560        char[] buffer = new char[count];
561        do {
562            int ch = 0 - (j % radix);
563            if (ch > 9) {
564                ch = ch - 10 + 'a';
565            } else {
566                ch += '0';
567            }
568            buffer[--count] = (char) ch;
569        } while ((j /= radix) != 0);
570        if (negative) {
571            buffer[0] = '-';
572        }
573        return new String(0, buffer.length, buffer);
574    }
575
576    /**
577     * Parses the specified string as a signed decimal integer value.
578     *
579     * @param string
580     *            the string representation of an integer value.
581     * @return an {@code Integer} instance containing the integer value
582     *         represented by {@code string}.
583     * @throws NumberFormatException
584     *             if {@code string} is {@code null}, has a length of zero or
585     *             can not be parsed as an integer value.
586     * @see #parseInt(String)
587     * @since Android 1.0
588     */
589    public static Integer valueOf(String string) throws NumberFormatException {
590        return valueOf(parseInt(string));
591    }
592
593    /**
594     * Parses the specified string as a signed integer value using the specified
595     * radix.
596     *
597     * @param string
598     *            the string representation of an integer value.
599     * @param radix
600     *            the radix to use when parsing.
601     * @return an {@code Integer} instance containing the integer value
602     *         represented by {@code string} using {@code radix}.
603     * @throws NumberFormatException
604     *             if {@code string} is {@code null} or has a length of zero,
605     *             {@code radix < Character.MIN_RADIX},
606     *             {@code radix > Character.MAX_RADIX}, or if {@code string}
607     *             can not be parsed as an integer value.
608     * @see #parseInt(String, int)
609     * @since Android 1.0
610     */
611    public static Integer valueOf(String string, int radix)
612            throws NumberFormatException {
613        return valueOf(parseInt(string, radix));
614    }
615
616    /**
617     * Determines the highest (leftmost) bit of the specified integer that is 1
618     * and returns the bit mask value for that bit. This is also referred to as
619     * the Most Significant 1 Bit. Returns zero if the specified integer is
620     * zero.
621     *
622     * @param i
623     *            the integer to examine.
624     * @return the bit mask indicating the highest 1 bit in {@code i}.
625     * @since Android 1.0
626     */
627    public static int highestOneBit(int i) {
628        i |= (i >> 1);
629        i |= (i >> 2);
630        i |= (i >> 4);
631        i |= (i >> 8);
632        i |= (i >> 16);
633        return (i & ~(i >>> 1));
634    }
635
636    /**
637     * Determines the lowest (rightmost) bit of the specified integer that is 1
638     * and returns the bit mask value for that bit. This is also referred
639     * to as the Least Significant 1 Bit. Returns zero if the specified integer
640     * is zero.
641     *
642     * @param i
643     *            the integer to examine.
644     * @return the bit mask indicating the lowest 1 bit in {@code i}.
645     * @since Android 1.0
646     */
647    public static int lowestOneBit(int i) {
648        return (i & (-i));
649    }
650
651    /**
652     * Determines the number of leading zeros in the specified integer prior to
653     * the {@link #highestOneBit(int) highest one bit}.
654     *
655     * @param i
656     *            the integer to examine.
657     * @return the number of leading zeros in {@code i}.
658     * @since Android 1.0
659     */
660    public static int numberOfLeadingZeros(int i) {
661        i |= i >> 1;
662        i |= i >> 2;
663        i |= i >> 4;
664        i |= i >> 8;
665        i |= i >> 16;
666        return bitCount(~i);
667    }
668
669    /**
670     * Determines the number of trailing zeros in the specified integer after
671     * the {@link #lowestOneBit(int) lowest one bit}.
672     *
673     * @param i
674     *            the integer to examine.
675     * @return the number of trailing zeros in {@code i}.
676     * @since Android 1.0
677     */
678    public static int numberOfTrailingZeros(int i) {
679        return bitCount((i & -i) - 1);
680    }
681
682    /**
683     * Counts the number of 1 bits in the specified integer; this is also
684     * referred to as population count.
685     *
686     * @param i
687     *            the integer to examine.
688     * @return the number of 1 bits in {@code i}.
689     * @since Android 1.0
690     */
691    public static int bitCount(int i) {
692        i -= ((i >> 1) & 0x55555555);
693        i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
694        i = (((i >> 4) + i) & 0x0F0F0F0F);
695        i += (i >> 8);
696        i += (i >> 16);
697        return (i & 0x0000003F);
698    }
699
700    /**
701     * Rotates the bits of the specified integer to the left by the specified
702     * number of bits.
703     *
704     * @param i
705     *            the integer value to rotate left.
706     * @param distance
707     *            the number of bits to rotate.
708     * @return the rotated value.
709     * @since Android 1.0
710     */
711    public static int rotateLeft(int i, int distance) {
712        if (distance == 0) {
713            return i;
714        }
715        /*
716         * According to JLS3, 15.19, the right operand of a shift is always
717         * implicitly masked with 0x1F, which the negation of 'distance' is
718         * taking advantage of.
719         */
720        return ((i << distance) | (i >>> (-distance)));
721    }
722
723    /**
724     * Rotates the bits of the specified integer to the right by the specified
725     * number of bits.
726     *
727     * @param i
728     *            the integer value to rotate right.
729     * @param distance
730     *            the number of bits to rotate.
731     * @return the rotated value.
732     * @since Android 1.0
733     */
734    public static int rotateRight(int i, int distance) {
735        if (distance == 0) {
736            return i;
737        }
738        /*
739         * According to JLS3, 15.19, the right operand of a shift is always
740         * implicitly masked with 0x1F, which the negation of 'distance' is
741         * taking advantage of.
742         */
743        return ((i >>> distance) | (i << (-distance)));
744    }
745
746    /**
747     * Reverses the order of the bytes of the specified integer.
748     *
749     * @param i
750     *            the integer value for which to reverse the byte order.
751     * @return the reversed value.
752     * @since Android 1.0
753     */
754    public static int reverseBytes(int i) {
755        int b3 = i >>> 24;
756        int b2 = (i >>> 8) & 0xFF00;
757        int b1 = (i & 0xFF00) << 8;
758        int b0 = i << 24;
759        return (b0 | b1 | b2 | b3);
760    }
761
762    /**
763     * Reverses the order of the bits of the specified integer.
764     *
765     * @param i
766     *            the integer value for which to reverse the bit order.
767     * @return the reversed value.
768     * @since Android 1.0
769     */
770    public static int reverse(int i) {
771        // From Hacker's Delight, 7-1, Figure 7-1
772        i = (i & 0x55555555) << 1 | (i >> 1) & 0x55555555;
773        i = (i & 0x33333333) << 2 | (i >> 2) & 0x33333333;
774        i = (i & 0x0F0F0F0F) << 4 | (i >> 4) & 0x0F0F0F0F;
775        return reverseBytes(i);
776    }
777
778    /**
779     * Returns the value of the {@code signum} function for the specified
780     * integer.
781     *
782     * @param i
783     *            the integer value to check.
784     * @return -1 if {@code i} is negative, 1 if {@code i} is positive, 0 if
785     *         {@code i} is zero.
786     * @since Android 1.0
787     */
788    public static int signum(int i) {
789        return (i == 0 ? 0 : (i < 0 ? -1 : 1));
790    }
791
792    /**
793     * Returns a {@code Integer} instance for the specified integer value.
794     * <p>
795     * If it is not necessary to get a new {@code Integer} instance, it is
796     * recommended to use this method instead of the constructor, since it
797     * maintains a cache of instances which may result in better performance.
798     * </p>
799     *
800     * @param i
801     *            the integer value to store in the instance.
802     * @return a {@code Integer} instance containing {@code i}.
803     * @since Android 1.0
804     */
805    public static Integer valueOf(int i) {
806        if (i < -128 || i > 127) {
807            return new Integer(i);
808        }
809        return valueOfCache.CACHE [i+128];
810
811    }
812
813   static class valueOfCache {
814        /**
815         * <p>
816         * A cache of instances used by {@link Integer#valueOf(int)} and auto-boxing.
817         * </p>
818         */
819        static final Integer[] CACHE = new Integer[256];
820
821        static {
822            for(int i=-128; i<=127; i++) {
823                CACHE[i+128] = new Integer(i);
824            }
825        }
826    }
827}
828