FileDocCategorySizeDatePackage
Scanner.javaAPI DocAndroid 1.5 API85006Wed May 06 22:41:04 BST 2009java.util

Scanner

public final class Scanner extends Object implements Iterator
A parser that parses a text string of primitive types and strings with the help of regular expressions. It supports localized numbers and various radixes. The input is broken into tokens by the delimiter pattern, which is whitespace by default. The primitive types can be obtained via corresponding next* methods. If the token is not in a valid format, an {@code InputMismatchException} is thrown.

For example:

Scanner s = new Scanner("1A true");
System.out.println(s.nextInt(16));
System.out.println(s.nextBoolean());

Yields the result: {@code 26 true}

A {@code Scanner} can also find or skip specific patterns without regard for the delimiter. All these methods and the various next* and hasNext* methods may block.

The {@code Scanner} class is not thread-safe.
since
Android 1.0

Fields Summary
private static final Pattern
DEFAULT_DELIMITER
private static final Pattern
BOOLEAN_PATTERN
private static final Pattern
LINE_TERMINATOR
private static final Pattern
MULTI_LINE_TERMINATOR
private static final Pattern
LINE_PATTERN
private static final Pattern
ANY_PATTERN
private static final int
DIPLOID
private static final int
DEFAULT_RADIX
private static final int
DEFAULT_TRUNK_SIZE
private Readable
input
private CharBuffer
buffer
private Pattern
delimiter
private Matcher
matcher
private int
integerRadix
private Locale
locale
private int
findStartIndex
private int
preStartIndex
private int
bufferLength
private boolean
closed
private IOException
lastIOException
private boolean
matchSuccessful
private DecimalFormat
decimalFormat
private boolean
inputExhausted
private Object
cacheHasNextValue
private int
cachehasNextIndex
Constructors Summary
public Scanner(File src)
Creates a {@code Scanner} with the specified {@code File} as input. The default charset is applied when reading the file.

param
src the file to be scanned.
throws
FileNotFoundException if the specified file does not exist.
since
Android 1.0

    
      
        /*
         * Stands for Integer
         */
        
        /*
         * Stands for Float
         */
        
    

                                                                        
         
        this(src, Charset.defaultCharset().name());
    
public Scanner(File src, String charsetName)
Creates a {@code Scanner} with the specified {@code File} as input. The specified charset is applied when reading the file.

param
src the file to be scanned.
param
charsetName the name of the encoding type of the file.
throws
FileNotFoundException if the specified file does not exist.
throws
IllegalArgumentException if the specified coding does not exist.
since
Android 1.0

        if (null == src) {
            throw new NullPointerException(org.apache.harmony.luni.util.Msg
                    .getString("KA00a")); //$NON-NLS-1$
        }
        FileInputStream fis = new FileInputStream(src);
        if (null == charsetName) {
            throw new IllegalArgumentException(org.apache.harmony.luni.util.Msg
                    .getString("KA009")); //$NON-NLS-1$
        }
        try {
            input = new InputStreamReader(fis, charsetName);
        } catch (UnsupportedEncodingException e) {
            try {
                fis.close();
            } catch (IOException ioException) {
                // ignore
            }
            throw new IllegalArgumentException(e.getMessage());
        }
        initialization();
    
public Scanner(String src)
Creates a {@code Scanner} on the specified string.

param
src the string to be scanned.
since
Android 1.0

        input = new StringReader(src);
        initialization();
    
public Scanner(InputStream src)
Creates a {@code Scanner} on the specified {@code InputStream}. The default charset is applied when decoding the input.

param
src the {@code InputStream} to be scanned.
since
Android 1.0

        this(src, Charset.defaultCharset().name());
    
public Scanner(InputStream src, String charsetName)
Creates a {@code Scanner} on the specified {@code InputStream}. The specified charset is applied when decoding the input.

param
src the {@code InputStream} to be scanned.
param
charsetName the encoding type of the {@code InputStream}.
throws
IllegalArgumentException if the specified character set is not found.
since
Android 1.0

        if (null == src) {
            throw new NullPointerException(org.apache.harmony.luni.util.Msg
                    .getString("KA00b")); //$NON-NLS-1$
        }
        try {
            input = new InputStreamReader(src, charsetName);
        } catch (UnsupportedEncodingException e) {
            throw new IllegalArgumentException(e.getMessage());
        }
        initialization();
    
public Scanner(Readable src)
Creates a {@code Scanner} with the specified {@code Readable} as input.

param
src the {@code Readable} to be scanned.
since
Android 1.0

        if (null == src) {
            throw new NullPointerException();
        }
        input = src;
        initialization();
    
public Scanner(ReadableByteChannel src)
Creates a {@code Scanner} with the specified {@code ReadableByteChannel} as input. The default charset is applied when decoding the input.

param
src the {@code ReadableByteChannel} to be scanned.
since
Android 1.0

        this(src, Charset.defaultCharset().name());
    
public Scanner(ReadableByteChannel src, String charsetName)
Creates a {@code Scanner} with the specified {@code ReadableByteChannel} as input. The specified charset is applied when decoding the input.

param
src the {@code ReadableByteChannel} to be scanned.
param
charsetName the encoding type of the content.
throws
IllegalArgumentException if the specified character set is not found.
since
Android 1.0

        if (null == src) {
            throw new NullPointerException(org.apache.harmony.luni.util.Msg
                    .getString("KA00d")); //$NON-NLS-1$
        }
        if (null == charsetName) {
            throw new IllegalArgumentException(org.apache.harmony.luni.util.Msg
                    .getString("KA009")); //$NON-NLS-1$
        }
        input = Channels.newReader(src, charsetName);
        initialization();
    
Methods Summary
private java.lang.StringBuilderaddNegativeSign(java.lang.StringBuilder unSignNumeral)

        String negativePrefix = ""; //$NON-NLS-1$
        String negativeSuffix = ""; //$NON-NLS-1$
        if (!decimalFormat.getNegativePrefix().equals("")) { //$NON-NLS-1$
            negativePrefix = "\\Q" + decimalFormat.getNegativePrefix()+"\\E"; //$NON-NLS-1$//$NON-NLS-2$
        }
        if (!decimalFormat.getNegativeSuffix().equals("")) { //$NON-NLS-1$
            negativeSuffix = "\\Q" + decimalFormat.getNegativeSuffix()+"\\E"; //$NON-NLS-1$//$NON-NLS-2$
        }
        StringBuilder signedNumeral = new StringBuilder()
                .append(negativePrefix).append(unSignNumeral).append(
                        negativeSuffix);
        return signedNumeral;
    
private java.lang.StringBuilderaddPositiveSign(java.lang.StringBuilder unSignNumeral)

        String positivePrefix = ""; //$NON-NLS-1$
        String positiveSuffix = ""; //$NON-NLS-1$
        if (!decimalFormat.getPositivePrefix().equals("")) { //$NON-NLS-1$
            positivePrefix = "\\Q" + decimalFormat.getPositivePrefix()+"\\E"; //$NON-NLS-1$ //$NON-NLS-2$
        }
        if (!decimalFormat.getPositiveSuffix().equals("")) { //$NON-NLS-1$
            positiveSuffix = "\\Q" + decimalFormat.getPositiveSuffix()+"\\E"; //$NON-NLS-1$ //$NON-NLS-2$
        }
        StringBuilder signedNumeral = new StringBuilder()
                .append(positivePrefix).append(unSignNumeral).append(
                        positiveSuffix);
        return signedNumeral;
    
private voidcheckClosed()

        if (closed) {
            throw new IllegalStateException();
        }
    
private voidcheckNull(java.util.regex.Pattern pattern)

        if (null == pattern) {
            throw new NullPointerException();
        }
    
public voidclose()
Closes this {@code Scanner} and the underlying input if the input implements {@code Closeable}. If the {@code Scanner} has been closed, this method will have no effect. Any scanning operation called after calling this method will throw an {@code IllegalStateException}.

see
Closeable
since
Android 1.0

        if (closed) {
            return;
        }
        if (input instanceof Closeable) {
            try {
                ((Closeable) input).close();
            } catch (IOException e) {
                lastIOException = e;
            }
        }
        closed = true;
    
public java.util.regex.Patterndelimiter()
Returns the delimiter {@code Pattern} in use by this {@code Scanner}.

return
the delimiter {@code Pattern} in use by this {@code Scanner}.
since
Android 1.0

        return delimiter;
    
private voidexpandBuffer()

        int oldPosition = buffer.position();
        int oldCapacity = buffer.capacity();
        int oldLimit = buffer.limit();
        int newCapacity = oldCapacity * DIPLOID;
        char[] newBuffer = new char[newCapacity];
        System.arraycopy(buffer.array(), 0, newBuffer, 0, oldLimit);
        buffer = CharBuffer.wrap(newBuffer, 0, newCapacity);
        buffer.position(oldPosition);
        buffer.limit(oldLimit);
    
public java.lang.StringfindInLine(java.util.regex.Pattern pattern)
Tries to find the pattern in the input. Delimiters are ignored. If the pattern is found before line terminator, the matched string will be returned, and the {@code Scanner} will advance to the end of the matched string. Otherwise, {@code null} will be returned and the {@code Scanner} will not advance. When waiting for input, the {@code Scanner} may be blocked. All the input may be cached if no line terminator exists in the buffer.

param
pattern the pattern to find in the input.
return
the matched string or {@code null} if the pattern is not found before the next line terminator.
throws
IllegalStateException if the {@code Scanner} is closed.
since
Android 1.0

        checkClosed();
        checkNull(pattern);
        int horizonLineSeparator = 0;

        matcher.usePattern(MULTI_LINE_TERMINATOR);
        matcher.region(findStartIndex, bufferLength);

        boolean findComplete = false;
        int terminatorLength = 0;
        while (!findComplete) {
            if (matcher.find()) {
                horizonLineSeparator = matcher.start();
                terminatorLength = matcher.end() - matcher.start();
                findComplete = true;
            } else {
                if (!inputExhausted) {
                    readMore();
                    resetMatcher();
                } else {
                    horizonLineSeparator = bufferLength;
                    findComplete = true;
                }
            }
        }

        matcher.usePattern(pattern);

        /*
         * TODO The following 2 statements are used to deal with regex's bug.
         * java.util.regex.Matcher.region(int start, int end) implementation
         * does not have any effects when called. They will be removed once the
         * bug is fixed.
         */
        int oldLimit = buffer.limit();
        buffer.limit(horizonLineSeparator);
        // ========== To deal with regex bug ====================

        matcher.region(findStartIndex, horizonLineSeparator);
        if (matcher.find()) {
            // The scanner advances past the input that matched
            findStartIndex = matcher.end();
            // If the matched pattern is immediately followed by line terminator. 
            if(horizonLineSeparator == matcher.end()) {
                findStartIndex += terminatorLength;
            }
            matchSuccessful = true;

            // ========== To deal with regex bug ====================
            buffer.limit(oldLimit);
            // ========== To deal with regex bug ====================

            return matcher.group();
        }

        // ========== To deal with regex bug ====================
        buffer.limit(oldLimit);
        // ========== To deal with regex bug ====================

        matchSuccessful = false;
        return null;
    
public java.lang.StringfindInLine(java.lang.String pattern)
Compiles the pattern string and tries to find a substing matching it in the input data. The delimiter will be ignored. This is the same as invoking {@code findInLine(Pattern.compile(pattern))}.

param
pattern a string used to construct a pattern which is in turn used to match a substring of the input data.
return
the matched string or {@code null} if the pattern is not found before the next line terminator.
throws
IllegalStateException if the {@code Scanner} is closed.
see
#findInLine(Pattern)
since
Android 1.0

        return findInLine(Pattern.compile(pattern));
    
private intfindPostDelimiter()

        int tokenEndIndex = 0;
        boolean findComplete = false;
        while (!findComplete) {
            if (matcher.find()) {
                findComplete = true;
                if (matcher.start() == findStartIndex
                        && matcher.start() == matcher.end()) {
                    findComplete = false;
                }
            } else {
                if (!inputExhausted) {
                    readMore();
                    resetMatcher();
                } else {
                    return -1;
                }
            }
        }
        tokenEndIndex = matcher.start();
        findStartIndex = matcher.start();
        return tokenEndIndex;
    
private intfindPreDelimiter()

        int tokenStartIndex;
        boolean findComplete = false;
        while (!findComplete) {
            if (matcher.find()) {
                findComplete = true;
                // If just delimiter remains
                if (matcher.start() == findStartIndex
                        && matcher.end() == bufferLength) {
                    // If more input resource exists
                    if (!inputExhausted) {
                        readMore();
                        resetMatcher();
                        findComplete = false;
                    }
                }
            } else {
                if (!inputExhausted) {
                    readMore();
                    resetMatcher();
                } else {
                    return -1;
                }
            }
        }
        tokenStartIndex = matcher.end();
        findStartIndex = matcher.end();
        return tokenStartIndex;
    
public java.lang.StringfindWithinHorizon(java.util.regex.Pattern pattern, int horizon)
Tries to find the pattern in the input between the current position and the specified horizon. Delimiters are ignored. If the pattern is found, the matched string will be returned, and the {@code Scanner} will advance to the end of the matched string. Otherwise, null will be returned and {@code Scanner} will not advance. When waiting for input, the {@code Scanner} may be blocked.

The {@code Scanner}'s search will never go more than {@code horizon} code points from current position. The position of {@code horizon} does have an effect on the result of the match. For example, when the input is "123" and current position is at zero, {@code findWithinHorizon(Pattern.compile("\\p{Digit}{3}"), 2)} will return {@code null}. While {@code findWithinHorizon(Pattern.compile("\\p{Digit}{3}"), 3)} will return {@code "123"}. {@code horizon} is treated as a transparent, non-anchoring bound. (refer to {@link Matcher#useTransparentBounds(boolean)} and {@link Matcher#useAnchoringBounds(boolean)})

A {@code horizon} whose value is zero will be ignored and the whole input will be used for search. In this situation, all the input may be cached.

param
pattern the pattern used to scan.
param
horizon the search limit.
return
the matched string or {@code null} if the pattern is not found within the specified {@code horizon}.
throws
IllegalStateException if the {@code Scanner} is closed.
throws
IllegalArgumentException if {@code horizon} is less than zero.
since
Android 1.0

        checkClosed();
        checkNull(pattern);
        if (horizon < 0) {
            throw new IllegalArgumentException(org.apache.harmony.luni.util.Msg
                    .getString("KA00e")); //$NON-NLS-1$
        }
        matcher.usePattern(pattern);

        String result = null;
        int findEndIndex = 0;
        int horizonEndIndex = 0;
        if (horizon == 0) {
            horizonEndIndex = Integer.MAX_VALUE;
        } else {
            horizonEndIndex = findStartIndex + horizon;
        }
        while (true) {
            findEndIndex = bufferLength;

            // If horizon > 0, then search up to
            // min( bufferLength, findStartIndex + horizon).
            // Otherwise search until readable is exhausted.
            findEndIndex = Math.min(horizonEndIndex, bufferLength);
            // If horizon == 0, consider horizon as always outside buffer.
            boolean isHorizonInBuffer = (horizonEndIndex <= bufferLength);
            // First, try to find pattern within buffer. If pattern can not be
            // found in buffer, then expand the buffer and try again,
            // util horizonEndIndex is exceeded or no more input left.
            matcher.region(findStartIndex, findEndIndex);
            if (matcher.find()) {
                if (isHorizonInBuffer || inputExhausted) {
                    result = matcher.group();
                    break;
                }
            } else {
                // Pattern is not found in buffer while horizonEndIndex is
                // within buffer, or input is exhausted. Under this situation,
                // it can be judged that find fails.
                if (isHorizonInBuffer || inputExhausted) {
                    break;
                }
            }

            // Expand buffer and reset matcher if needed.
            if (!inputExhausted) {
                readMore();
                resetMatcher();
            }
        }
        if (null != result) {
            findStartIndex = matcher.end();
            matchSuccessful = true;
        } else {
            matchSuccessful = false;
        }
        return result;
    
public java.lang.StringfindWithinHorizon(java.lang.String pattern, int horizon)
Tries to find the pattern in the input between the current position and the specified {@code horizon}. Delimiters are ignored. This call is the same as invoking {@code findWithinHorizon(Pattern.compile(pattern))}.

param
pattern the pattern used to scan.
param
horizon the search limit.
return
the matched string, or {@code null} if the pattern is not found within the specified horizon.
throws
IllegalStateException if the {@code Scanner} is closed.
throws
IllegalArgumentException if {@code horizon} is less than zero.
see
#findWithinHorizon(Pattern, int)
since
Android 1.0

        return findWithinHorizon(Pattern.compile(pattern), horizon);
    
private java.util.regex.PatterngetFloatPattern()

        decimalFormat = (DecimalFormat) NumberFormat.getInstance(locale);

        StringBuilder digit = new StringBuilder("([0-9]|(\\p{javaDigit}))"); //$NON-NLS-1$
        StringBuilder nonZeroDigit = new StringBuilder("[\\p{javaDigit}&&[^0]]"); //$NON-NLS-1$
        StringBuilder numeral = getNumeral(digit, nonZeroDigit);

        String decimalSeparator = "\\" + decimalFormat.getDecimalFormatSymbols()//$NON-NLS-1$
                        .getDecimalSeparator();
        StringBuilder decimalNumeral = new StringBuilder("(").append(numeral) //$NON-NLS-1$
                .append("|").append(numeral) //$NON-NLS-1$
                .append(decimalSeparator).append(digit).append("*+|").append( //$NON-NLS-1$
                        decimalSeparator).append(digit).append("++)"); //$NON-NLS-1$
        StringBuilder exponent = new StringBuilder("([eE][+-]?").append(digit) //$NON-NLS-1$
                .append("+)?"); //$NON-NLS-1$

        StringBuilder decimal = new StringBuilder("(([-+]?").append( //$NON-NLS-1$
                decimalNumeral).append("(").append(exponent).append("?)") //$NON-NLS-1$ //$NON-NLS-2$
                .append(")|(").append(addPositiveSign(decimalNumeral)).append( //$NON-NLS-1$
                        "(").append(exponent).append("?)").append(")|(") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                .append(addNegativeSign(decimalNumeral)).append("(").append( //$NON-NLS-1$
                        exponent).append("?)").append("))"); //$NON-NLS-1$ //$NON-NLS-2$

        StringBuilder hexFloat = new StringBuilder("([-+]?0[xX][0-9a-fA-F]*") //$NON-NLS-1$
                .append("\\.").append(//$NON-NLS-1$
                        "[0-9a-fA-F]+([pP][-+]?[0-9]+)?)"); //$NON-NLS-1$
        String localNaN = decimalFormat.getDecimalFormatSymbols().getNaN();
        String localeInfinity = decimalFormat.getDecimalFormatSymbols()
                .getInfinity();
        StringBuilder nonNumber = new StringBuilder("(NaN|\\Q").append(localNaN) //$NON-NLS-1$
                .append("\\E|Infinity|\\Q").append(localeInfinity).append("\\E)"); //$NON-NLS-1$ //$NON-NLS-2$
        StringBuilder singedNonNumber = new StringBuilder("((([-+]?(").append( //$NON-NLS-1$
                nonNumber).append(")))|(").append(addPositiveSign(nonNumber)) //$NON-NLS-1$
                .append(")|(").append(addNegativeSign(nonNumber)).append("))"); //$NON-NLS-1$ //$NON-NLS-2$

        StringBuilder floatString = new StringBuilder().append(decimal).append(
                "|").append(hexFloat).append("|").append(singedNonNumber); //$NON-NLS-1$ //$NON-NLS-2$
        Pattern floatPattern = Pattern.compile(floatString.toString());
        return floatPattern;
    
private java.util.regex.PatterngetIntegerPattern(int radix)

        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
            throw new IllegalArgumentException(org.apache.harmony.luni.util.Msg
                    .getString("KA00e", radix)); //$NON-NLS-1$
        }
        decimalFormat = (DecimalFormat) NumberFormat.getInstance(locale);
        
        String allAvailableDigits="0123456789abcdefghijklmnopqrstuvwxyz"; //$NON-NLS-1$ 
        String ASCIIDigit=allAvailableDigits.substring(0, radix);
        String nonZeroASCIIDigit=allAvailableDigits.substring(1, radix);

        StringBuilder digit = new StringBuilder("((?i)[").append(ASCIIDigit) //$NON-NLS-1$ 
                .append("]|\\p{javaDigit})"); //$NON-NLS-1$
        StringBuilder nonZeroDigit = new StringBuilder("((?i)[").append( //$NON-NLS-1$
                nonZeroASCIIDigit).append("]|([\\p{javaDigit}&&[^0]]))"); //$NON-NLS-1$
        StringBuilder numeral = getNumeral(digit, nonZeroDigit);

        StringBuilder integer = new StringBuilder("(([-+]?(").append(numeral) //$NON-NLS-1$
                .append(")))|(").append(addPositiveSign(numeral)).append(")|(") //$NON-NLS-1$ //$NON-NLS-2$
                .append(addNegativeSign(numeral)).append(")"); //$NON-NLS-1$

        Pattern integerPattern = Pattern.compile(integer.toString());
        return integerPattern;
    
private java.lang.StringBuildergetNumeral(java.lang.StringBuilder digit, java.lang.StringBuilder nonZeroDigit)

        String groupSeparator = "\\"//$NON-NLS-1$
                + decimalFormat.getDecimalFormatSymbols()
                        .getGroupingSeparator();
        StringBuilder groupedNumeral = new StringBuilder("(").append( //$NON-NLS-1$
                nonZeroDigit).append(digit).append("?").append(digit).append( //$NON-NLS-1$
                "?(").append(groupSeparator).append(digit).append(digit) //$NON-NLS-1$
                .append(digit).append(")+)"); //$NON-NLS-1$
        StringBuilder numeral = new StringBuilder("((").append(digit).append( //$NON-NLS-1$
                "++)|").append(groupedNumeral).append(")"); //$NON-NLS-1$ //$NON-NLS-2$
        return numeral;
    
public booleanhasNext()
Returns whether this {@code Scanner} has one or more tokens remaining to parse. This method will block if the data is still being read.

return
{@code true} if this {@code Scanner} has one or more tokens remaining, otherwise {@code false}.
throws
IllegalStateException if the {@code Scanner} has been closed.
since
Android 1.0

        return hasNext(ANY_PATTERN);
    
public booleanhasNext(java.util.regex.Pattern pattern)
Returns whether this {@code Scanner} has one or more tokens remaining to parse and the next token matches the given pattern. This method will block if the data is still being read.

param
pattern the pattern to check for.
return
{@code true} if this {@code Scanner} has more tokens and the next token matches the pattern, {@code false} otherwise.
throws
IllegalStateException if the {@code Scanner} has been closed.
since
Android 1.0

        checkClosed();
        checkNull(pattern);
        matchSuccessful = false;
        saveCurrentStatus();
        //if the next token exists, set the match region, otherwise return false
        if (!setTokenRegion()) {
            recoverPreviousStatus();
            return false;
        }
        matcher.usePattern(pattern);
        boolean hasNext = false;
        //check whether next token matches the specified pattern
        if (matcher.matches()) {
            cachehasNextIndex = findStartIndex;
            matchSuccessful = true;
            hasNext = true;
        }
        recoverPreviousStatus();
        return hasNext;
    
public booleanhasNext(java.lang.String pattern)
Returns {@code true} if this {@code Scanner} has one or more tokens remaining to parse and the next token matches a pattern compiled from the given string. This method will block if the data is still being read. This call is equivalent to {@code hasNext(Pattern.compile(pattern))}.

param
pattern the string specifying the pattern to scan for
return
{@code true} if the specified pattern matches this {@code Scanner}'s next token, {@code false} otherwise.
throws
IllegalStateException if the {@code Scanner} has been closed.
since
Android 1.0

        return hasNext(Pattern.compile(pattern));
    
public booleanhasNextBigDecimal()
Returns whether the next token can be translated into a valid {@code BigDecimal}.

return
{@code true} if the next token can be translated into a valid {@code BigDecimal}, otherwise {@code false.}
throws
IllegalStateException if the {@code Scanner} has been closed.
since
Android 1.0

        Pattern floatPattern = getFloatPattern();
        boolean isBigDecimalValue = false;
        if (hasNext(floatPattern)) {
            String floatString = matcher.group();
            floatString = removeLocaleInfoFromFloat(floatString);
            try {
                cacheHasNextValue = new BigDecimal(floatString);
                isBigDecimalValue = true;
            } catch (NumberFormatException e) {
                matchSuccessful = false;
            }
        }
        return isBigDecimalValue;
    
public booleanhasNextBigInteger()
Returns whether the next token can be translated into a valid {@code BigInteger} in the default radix.

return
{@code true} if the next token can be translated into a valid {@code BigInteger}, otherwise {@code false}.
throws
IllegalStateException if the {@code Scanner} has been closed.
since
Android 1.0

        return hasNextBigInteger(integerRadix);
    
public booleanhasNextBigInteger(int radix)
Returns whether the next token can be translated into a valid {@code BigInteger} in the specified radix.

param
radix the radix used to translate the token into a {@code BigInteger}.
return
{@code true} if the next token can be translated into a valid {@code BigInteger}, otherwise {@code false}.
throws
IllegalStateException if the {@code Scanner} has been closed.
since
Android 1.0

        Pattern integerPattern = getIntegerPattern(radix);
        boolean isBigIntegerValue = false;
        if (hasNext(integerPattern)) {
            String intString = matcher.group();
            intString = removeLocaleInfo(intString, DataType.INT);
            try {
                cacheHasNextValue = new BigInteger(intString, radix);
                isBigIntegerValue = true;
            } catch (NumberFormatException e) {
                matchSuccessful = false;
            }
        }
        return isBigIntegerValue;
    
public booleanhasNextBoolean()
Returns whether the next token can be translated into a valid {@code boolean} value.

return
{@code true} if the next token can be translated into a valid {@code boolean} value, otherwise {@code false}.
throws
IllegalStateException if the {@code Scanner} has been closed.
since
Android 1.0

        return hasNext(BOOLEAN_PATTERN);
    
public booleanhasNextByte()
Returns whether the next token can be translated into a valid {@code byte} value in the default radix.

return
{@code true} if the next token can be translated into a valid {@code byte} value, otherwise {@code false}.
throws
IllegalStateException if the {@code Scanner} has been closed.
since
Android 1.0

        return hasNextByte(integerRadix);
    
public booleanhasNextByte(int radix)
Returns whether the next token can be translated into a valid {@code byte} value in the specified radix.

param
radix the radix used to translate the token into a {@code byte} value
return
{@code true} if the next token can be translated into a valid {@code byte} value, otherwise {@code false}.
throws
IllegalStateException if the {@code Scanner} has been closed.
since
Android 1.0

        Pattern integerPattern = getIntegerPattern(radix);
        boolean isByteValue = false;
        if (hasNext(integerPattern)) {
            String intString = matcher.group();
            intString = removeLocaleInfo(intString, DataType.INT);
            try {
                cacheHasNextValue = Byte.valueOf(intString, radix);
                isByteValue = true;
            } catch (NumberFormatException e) {
                matchSuccessful = false;
            }
        }
        return isByteValue;
    
public booleanhasNextDouble()
Returns whether the next token translated into a valid {@code double} value.

return
{@code true} if the next token can be translated into a valid {@code double} value, otherwise {@code false}.
throws
IllegalStateException if the {@code Scanner} has been closed.
since
Android 1.0

        Pattern floatPattern = getFloatPattern();
        boolean isDoubleValue = false;
        if (hasNext(floatPattern)) {
            String floatString = matcher.group();
            floatString = removeLocaleInfoFromFloat(floatString);
            try {
                cacheHasNextValue = Double.valueOf(floatString);
                isDoubleValue = true;
            } catch (NumberFormatException e) {
                matchSuccessful = false;
            }
        }
        return isDoubleValue;
    
public booleanhasNextFloat()
Returns whether the next token can be translated into a valid {@code float} value.

return
{@code true} if the next token can be translated into a valid {@code float} value, otherwise {@code false}.
throws
IllegalStateException if the {@code Scanner} has been closed.
since
Android 1.0

        Pattern floatPattern = getFloatPattern();
        boolean isFloatValue = false;
        if (hasNext(floatPattern)) {
            String floatString = matcher.group();
            floatString = removeLocaleInfoFromFloat(floatString);
            try {
                cacheHasNextValue = Float.valueOf(floatString);
                isFloatValue = true;
            } catch (NumberFormatException e) {
                matchSuccessful = false;
            }
        }
        return isFloatValue;
    
public booleanhasNextInt()
Returns whether the next token can be translated into a valid {@code int} value in the default radix.

return
{@code true} if the next token can be translated into a valid {@code int} value, otherwise {@code false}.
throws
IllegalStateException if the {@code Scanner} has been closed,
since
Android 1.0

        return hasNextInt(integerRadix);
    
public booleanhasNextInt(int radix)
Returns whether the next token can be translated into a valid {@code int} value in the specified radix.

param
radix the radix used to translate the token into an {@code int} value.
return
{@code true} if the next token in this {@code Scanner}'s input can be translated into a valid {@code int} value, otherwise {@code false}.
throws
IllegalStateException if the {@code Scanner} has been closed.
since
Android 1.0

        Pattern integerPattern = getIntegerPattern(radix);
        boolean isIntValue = false;
        if (hasNext(integerPattern)) {
            String intString = matcher.group();
            intString = removeLocaleInfo(intString, DataType.INT);
            try {
                cacheHasNextValue = Integer.valueOf(intString, radix);
                isIntValue = true;
            } catch (NumberFormatException e) {
                matchSuccessful = false;
            }
        }
        return isIntValue;
    
public booleanhasNextLine()
Returns whether there is a line terminator in the input. This method may block.

return
{@code true} if there is a line terminator in the input, otherwise, {@code false}.
throws
IllegalStateException if the {@code Scanner} is closed.
since
Android 1.0

        checkClosed();
        matcher.usePattern(LINE_PATTERN);
        matcher.region(findStartIndex, bufferLength);

        boolean hasNextLine = false;
        while (true) {
            if (matcher.find()) {
                if (inputExhausted || matcher.end() != bufferLength) {
                    matchSuccessful = true;
                    hasNextLine = true;
                    break;
                }
            } else {
                if (inputExhausted) {
                    matchSuccessful = false;
                    break;
                }
            }
            if (!inputExhausted) {
                readMore();
                resetMatcher();
            }
        }
        return hasNextLine;
    
public booleanhasNextLong()
Returns whether the next token can be translated into a valid {@code long} value in the default radix.

return
{@code true} if the next token can be translated into a valid {@code long} value, otherwise {@code false}.
throws
IllegalStateException if the {@code Scanner} has been closed.
since
Android 1.0

        return hasNextLong(integerRadix);
    
public booleanhasNextLong(int radix)
Returns whether the next token can be translated into a valid {@code long} value in the specified radix.

param
radix the radix used to translate the token into a {@code long} value.
return
{@code true} if the next token can be translated into a valid {@code long} value, otherwise {@code false}.
throws
IllegalStateException if the {@code Scanner} has been closed.
since
Android 1.0

        Pattern integerPattern = getIntegerPattern(radix);
        boolean isLongValue = false;
        if (hasNext(integerPattern)) {
            String intString = matcher.group();
            intString = removeLocaleInfo(intString, DataType.INT);
            try {
                cacheHasNextValue = Long.valueOf(intString, radix);
                isLongValue = true;
            } catch (NumberFormatException e) {
                matchSuccessful = false;
            }
        }
        return isLongValue;
    
public booleanhasNextShort()
Returns whether the next token can be translated into a valid {@code short} value in the default radix.

return
{@code true} if the next token can be translated into a valid {@code short} value, otherwise {@code false}.
throws
IllegalStateException if the {@code Scanner} has been closed.
since
Android 1.0

        return hasNextShort(integerRadix);
    
public booleanhasNextShort(int radix)
Returns whether the next token can be translated into a valid {@code short} value in the specified radix.

param
radix the radix used to translate the token into a {@code short} value.
return
{@code true} if the next token can be translated into a valid {@code short} value, otherwise {@code false}.
throws
IllegalStateException if the {@code Scanner} has been closed.
since
Android 1.0

        Pattern integerPattern = getIntegerPattern(radix);
        boolean isShortValue = false;
        if (hasNext(integerPattern)) {
            String intString = matcher.group();
            intString = removeLocaleInfo(intString, DataType.INT);
            try {
                cacheHasNextValue = Short.valueOf(intString, radix);
                isShortValue = true;
            } catch (NumberFormatException e) {
                matchSuccessful = false;
            }
        }
        return isShortValue;
    
private voidinitialization()

        buffer = CharBuffer.allocate(DEFAULT_TRUNK_SIZE);
        buffer.limit(0);
        matcher = delimiter.matcher(buffer);
    
public java.io.IOExceptionioException()
Returns the last {@code IOException} that was raised while reading from the underlying input.

return
the last thrown {@code IOException}, or {@code null} if none was thrown.
since
Android 1.0

        return lastIOException;
    
public java.util.Localelocale()
Return the {@code Locale} of this {@code Scanner}.

return
the {@code Locale} of this {@code Scanner}.
since
Android 1.0

        return locale;
    
public java.util.regex.MatchResultmatch()
Returns the result of the last matching operation.

The next* and find* methods return the match result in the case of a successful match.

return
the match result of the last successful match operation
throws
IllegalStateException if the match result is not available, of if the last match was not successful.
since
Android 1.0

        if (!matchSuccessful) {
            throw new IllegalStateException();
        }
        return matcher.toMatchResult();
    
public java.lang.Stringnext()
Returns the next token. The token will be both prefixed and postfixed by the delimiter that is currently being used (or a string that matches the delimiter pattern). This method will block if input is being read.

return
the next complete token.
throws
IllegalStateException if this {@code Scanner} has been closed.
throws
NoSuchElementException if input has been exhausted.
since
Android 1.0

        return next(ANY_PATTERN);
    
public java.lang.Stringnext(java.util.regex.Pattern pattern)
Returns the next token if it matches the specified pattern. The token will be both prefixed and postfixed by the delimiter that is currently being used (or a string that matches the delimiter pattern). This method will block if input is being read.

param
pattern the specified pattern to scan.
return
the next token.
throws
IllegalStateException if this {@code Scanner} has been closed.
throws
NoSuchElementException if input has been exhausted.
throws
InputMismatchException if the next token does not match the pattern given.
since
Android 1.0

        checkClosed();
        checkNull(pattern);
        matchSuccessful = false;
        saveCurrentStatus();
        if (!setTokenRegion()) {
            recoverPreviousStatus();
            // if setting match region fails
            throw new NoSuchElementException();
        }
        matcher.usePattern(pattern);
        if (!matcher.matches()) {
            recoverPreviousStatus();
            throw new InputMismatchException();

        }
        matchSuccessful = true;
        return matcher.group();
    
public java.lang.Stringnext(java.lang.String pattern)
Returns the next token if it matches the specified pattern. The token will be both prefixed and postfixed by the delimiter that is currently being used (or a string that matches the delimiter pattern). This method will block if input is being read. Calling this methos is equivalent to {@code next(Pattern.compile(pattern))}.

param
pattern the string specifying the pattern to scan for.
return
the next token.
throws
IllegalStateException if this {@code Scanner} has been closed.
throws
NoSuchElementException if input has been exhausted.
throws
InputMismatchException if the next token does not match the pattern given.
since
Android 1.0

        return next(Pattern.compile(pattern));
    
public java.math.BigDecimalnextBigDecimal()
Returns the next token as a {@code BigDecimal}. This method will block if input is being read. If the next token can be translated into a {@code BigDecimal} the following is done: All {@code Locale}-specific prefixes, group separators, and {@code Locale}-specific suffixes are removed. Then non-ASCII digits are mapped into ASCII digits via {@link Character#digit(char, int)}, and a negative sign (-) is added if the {@code Locale}-specific negative prefix or suffix was present. Finally the resulting string is passed to {@code BigDecimal(String) }.

return
the next token as a {@code BigDecimal}.
throws
IllegalStateException if this {@code Scanner} has been closed.
throws
NoSuchElementException if input has been exhausted.
throws
InputMismatchException if the next token can not be translated into a valid {@code BigDecimal}.
since
Android 1.0

        checkClosed();
        Object obj = cacheHasNextValue;
        cacheHasNextValue = null;
        if (obj instanceof BigDecimal) {
            findStartIndex = cachehasNextIndex;
            return (BigDecimal) obj;
        }
        Pattern floatPattern = getFloatPattern();
        String floatString = next(floatPattern);
        floatString = removeLocaleInfoFromFloat(floatString);
        BigDecimal bigDecimalValue;
        try {
            bigDecimalValue = new BigDecimal(floatString);
        } catch (NumberFormatException e) {
            matchSuccessful = false;
            recoverPreviousStatus();
            throw new InputMismatchException();
        }
        return bigDecimalValue;
    
public java.math.BigIntegernextBigInteger()
Returns the next token as a {@code BigInteger}. This method will block if input is being read. Equivalent to {@code nextBigInteger(DEFAULT_RADIX)}.

return
the next token as {@code BigInteger}.
throws
IllegalStateException if this {@code Scanner} has been closed.
throws
NoSuchElementException if input has been exhausted.
throws
InputMismatchException if the next token can not be translated into a valid {@code BigInteger}.
since
Android 1.0

        return nextBigInteger(integerRadix);
    
public java.math.BigIntegernextBigInteger(int radix)
Returns the next token as a {@code BigInteger} with the specified radix. This method will block if input is being read. If the next token can be translated into a {@code BigInteger} the following is done: All {@code Locale}-specific prefixes, group separators, and {@code Locale}-specific suffixes are removed. Then non-ASCII digits are mapped into ASCII digits via {@link Character#digit(char, int)}, and a negative sign (-) is added if the {@code Locale}-specific negative prefix or suffix was present. Finally the resulting String is passed to {@link BigInteger#BigInteger(String, int)}} with the specified radix.

param
radix the radix used to translate the token into a {@code BigInteger}.
return
the next token as a {@code BigInteger}
throws
IllegalStateException if this {@code Scanner} has been closed.
throws
NoSuchElementException if input has been exhausted.
throws
InputMismatchException if the next token can not be translated into a valid {@code BigInteger}.
since
Android 1.0

        checkClosed();
        Object obj = cacheHasNextValue;
        cacheHasNextValue = null;
        if (obj instanceof BigInteger) {
            findStartIndex = cachehasNextIndex;
            return (BigInteger) obj;
        }
        Pattern integerPattern = getIntegerPattern(radix);
        String intString = next(integerPattern);
        intString = removeLocaleInfo(intString, DataType.INT);
        BigInteger bigIntegerValue;
        try {
            bigIntegerValue = new BigInteger(intString, radix);
        } catch (NumberFormatException e) {
            matchSuccessful = false;
            recoverPreviousStatus();
            throw new InputMismatchException();
        }
        return bigIntegerValue;
    
public booleannextBoolean()
Returns the next token as a {@code boolean}. This method will block if input is being read.

return
the next token as a {@code boolean}.
throws
IllegalStateException if this {@code Scanner} has been closed.
throws
NoSuchElementException if input has been exhausted.
throws
InputMismatchException if the next token can not be translated into a valid {@code boolean} value.
since
Android 1.0

        return Boolean.parseBoolean(next(BOOLEAN_PATTERN));
    
public bytenextByte()
Returns the next token as a {@code byte}. This method will block if input is being read. Equivalent to {@code nextByte(DEFAULT_RADIX)}.

return
the next token as a {@code byte}.
throws
IllegalStateException if this {@code Scanner} has been closed.
throws
NoSuchElementException if input has been exhausted.
throws
InputMismatchException if the next token can not be translated into a valid {@code byte} value.
since
Android 1.0

        return nextByte(integerRadix);
    
public bytenextByte(int radix)
Returns the next token as a {@code byte} with the specified radix. Will block if input is being read. If the next token can be translated into a {@code byte} the following is done: All {@code Locale}-specific prefixes, group separators, and {@code Locale}-specific suffixes are removed. Then non-ASCII digits are mapped into ASCII digits via {@link Character#digit(char, int)}, and a negative sign (-) is added if the {@code Locale}-specific negative prefix or suffix was present. Finally the resulting String is passed to {@link Byte#parseByte(String, int)}} with the specified radix.

param
radix the radix used to translate the token into {@code byte} value.
return
the next token as a {@code byte}.
throws
IllegalStateException if this {@code Scanner} has been closed.
throws
NoSuchElementException if input has been exhausted.
throws
InputMismatchException if the next token can not be translated into a valid {@code byte} value.
since
Android 1.0

        checkClosed();
        Object obj = cacheHasNextValue;
        cacheHasNextValue = null;
        if (obj instanceof Byte) {
            findStartIndex = cachehasNextIndex;
            return (Byte) obj;
        }
        Pattern integerPattern = getIntegerPattern(radix);
        String intString = next(integerPattern);
        intString = removeLocaleInfo(intString, DataType.INT);
        byte byteValue = 0;
        try {
            byteValue = Byte.parseByte(intString, radix);
        } catch (NumberFormatException e) {
            matchSuccessful = false;
            recoverPreviousStatus();
            throw new InputMismatchException();
        }
        return byteValue;
    
public doublenextDouble()
Returns the next token as a {@code double}. This method will block if input is being read. If the next token can be translated into a {@code double} the following is done: All {@code Locale}-specific prefixes, group separators, and {@code Locale}-specific suffixes are removed. Then non-ASCII digits are mapped into ASCII digits via {@link Character#digit(char, int)}, and a negative sign (-) is added if the {@code Locale}-specific negative prefix or suffix was present. Finally the resulting String is passed to {@link Double#parseDouble(String)}}. If the token matches the localized NaN or infinity strings, it is also passed to {@link Double#parseDouble(String)}}.

return
the next token as a {@code double}.
throws
IllegalStateException if this {@code Scanner} has been closed.
throws
NoSuchElementException if input has been exhausted.
throws
InputMismatchException if the next token can not be translated into a valid {@code double} value.
since
Android 1.0

        checkClosed();
        Object obj = cacheHasNextValue;
        cacheHasNextValue = null;
        if (obj instanceof Double) {
            findStartIndex = cachehasNextIndex;
            return (Double) obj;
        }
        Pattern floatPattern = getFloatPattern();
        String floatString = next(floatPattern);
        floatString = removeLocaleInfoFromFloat(floatString);
        double doubleValue = 0;
        try {
            doubleValue = Double.parseDouble(floatString);
        } catch (NumberFormatException e) {
            matchSuccessful = false;
            recoverPreviousStatus();
            throw new InputMismatchException();
        }
        return doubleValue;
    
public floatnextFloat()
Returns the next token as a {@code float}. This method will block if input is being read. If the next token can be translated into a {@code float} the following is done: All {@code Locale}-specific prefixes, group separators, and {@code Locale}-specific suffixes are removed. Then non-ASCII digits are mapped into ASCII digits via {@link Character#digit(char, int)}, and a negative sign (-) is added if the {@code Locale}-specific negative prefix or suffix was present. Finally the resulting String is passed to {@link Float#parseFloat(String)}}.If the token matches the localized NaN or infinity strings, it is also passed to {@link Float#parseFloat(String)}}.

return
the next token as a {@code float}.
throws
IllegalStateException if this {@code Scanner} has been closed.
throws
NoSuchElementException if input has been exhausted.
throws
InputMismatchException if the next token can not be translated into a valid {@code float} value.
since
Android 1.0

        checkClosed();
        Object obj = cacheHasNextValue;
        cacheHasNextValue = null;
        if (obj instanceof Float) {
            findStartIndex = cachehasNextIndex;
            return (Float) obj;
        }
        Pattern floatPattern = getFloatPattern();
        String floatString = next(floatPattern);
        floatString = removeLocaleInfoFromFloat(floatString);
        float floatValue = 0;
        try {
            floatValue = Float.parseFloat(floatString);
        } catch (NumberFormatException e) {
            matchSuccessful = false;
            recoverPreviousStatus();
            throw new InputMismatchException();
        }
        return floatValue;
    
public intnextInt()
Returns the next token as an {@code int}. This method will block if input is being read. Equivalent to {@code nextInt(DEFAULT_RADIX)}.

return
the next token as an {@code int}
throws
IllegalStateException if this {@code Scanner} has been closed.
throws
NoSuchElementException if input has been exhausted.
throws
InputMismatchException if the next token can not be translated into a valid {@code int} value.
since
Android 1.0

        return nextInt(integerRadix);
    
public intnextInt(int radix)
Returns the next token as an {@code int} with the specified radix. This method will block if input is being read. If the next token can be translated into an {@code int} the following is done: All {@code Locale}-specific prefixes, group separators, and {@code Locale}-specific suffixes are removed. Then non-ASCII digits are mapped into ASCII digits via {@link Character#digit(char, int)}, and a negative sign (-) is added if the {@code Locale}-specific negative prefix or suffix was present. Finally the resulting String is passed to {@link Integer#parseInt(String, int)} with the specified radix.

param
radix the radix used to translate the token into an {@code int} value.
return
the next token as an {@code int}.
throws
IllegalStateException if this {@code Scanner} has been closed.
throws
NoSuchElementException if input has been exhausted.
throws
InputMismatchException if the next token can not be translated into a valid {@code int} value.
since
Android 1.0

        checkClosed();
        Object obj = cacheHasNextValue;
        cacheHasNextValue = null;
        if (obj instanceof Integer) {
            findStartIndex = cachehasNextIndex;
            return (Integer) obj;
        }
        Pattern integerPattern = getIntegerPattern(radix);
        String intString=next(integerPattern);
        intString = removeLocaleInfo(intString, DataType.INT);
        int intValue = 0;
        try {
            intValue = Integer.parseInt(intString, radix);
        } catch (NumberFormatException e) {
            matchSuccessful = false;
            recoverPreviousStatus();
            throw new InputMismatchException();
        }
        return intValue;
    
public java.lang.StringnextLine()
Returns the skipped input and advances the {@code Scanner} to the beginning of the next line. The returned result will exclude any line terminator. When searching, if no line terminator is found, then a large amount of input will be cached. If no line at all can be found, a {@code NoSuchElementException} will be thrown.

return
the skipped line.
throws
IllegalStateException if the {@code Scanner} is closed.
throws
NoSuchElementException if no line can be found, e.g. when input is an empty string.
since
Android 1.0

        checkClosed();

        matcher.usePattern(LINE_PATTERN);
        matcher.region(findStartIndex, bufferLength);
        String result = null;
        while (true) {
            if (matcher.find()) {
                if (inputExhausted || matcher.end() != bufferLength) {
                    matchSuccessful = true;
                    findStartIndex = matcher.end();
                    result = matcher.group();
                    break;
                }
            } else {
                if (inputExhausted) {
                    matchSuccessful = false;
                    throw new NoSuchElementException();
                }
            }
            if (!inputExhausted) {
                readMore();
                resetMatcher();
            } 
        }
        // Find text without line terminator here.
        if (null != result) {
            Matcher terminatorMatcher = LINE_TERMINATOR.matcher(result);
            if (terminatorMatcher.find()) {
                result = result.substring(0, terminatorMatcher.start());
            }
        }
        return result;
    
public longnextLong()
Returns the next token as a {@code long}. This method will block if input is being read. Equivalent to {@code nextLong(DEFAULT_RADIX)}.

return
the next token as a {@code long}.
throws
IllegalStateException if this {@code Scanner} has been closed.
throws
NoSuchElementException if input has been exhausted.
throws
InputMismatchException if the next token can not be translated into a valid {@code long} value.
since
Android 1.0

        return nextLong(integerRadix);
    
public longnextLong(int radix)
Returns the next token as a {@code long} with the specified radix. This method will block if input is being read. If the next token can be translated into a {@code long} the following is done: All {@code Locale}-specific prefixes, group separators, and {@code Locale}-specific suffixes are removed. Then non-ASCII digits are mapped into ASCII digits via {@link Character#digit(char, int)}, and a negative sign (-) is added if the {@code Locale}-specific negative prefix or suffix was present. Finally the resulting String is passed to {@link Long#parseLong(String, int)}} with the specified radix.

param
radix the radix used to translate the token into a {@code long} value.
return
the next token as a {@code long}.
throws
IllegalStateException if this {@code Scanner} has been closed.
throws
NoSuchElementException if input has been exhausted.
throws
InputMismatchException if the next token can not be translated into a valid {@code long} value.
since
Android 1.0

        checkClosed();
        Object obj = cacheHasNextValue;
        cacheHasNextValue = null;
        if (obj instanceof Long) {
            findStartIndex = cachehasNextIndex;
            return (Long) obj;
        }
        Pattern integerPattern = getIntegerPattern(radix);
        String intString = next(integerPattern);
        intString = removeLocaleInfo(intString, DataType.INT);
        long longValue = 0;
        try {
            longValue = Long.parseLong(intString, radix);
        } catch (NumberFormatException e) {
            matchSuccessful = false;
            recoverPreviousStatus();
            throw new InputMismatchException();
        }
        return longValue;
    
public shortnextShort()
Returns the next token as a {@code short}. This method will block if input is being read. Equivalent to {@code nextShort(DEFAULT_RADIX)}.

return
the next token as a {@code short}.
throws
IllegalStateException if this {@code Scanner} has been closed.
throws
NoSuchElementException if input has been exhausted.
throws
InputMismatchException if the next token can not be translated into a valid {@code short} value.
since
Android 1.0

        return nextShort(integerRadix);
    
public shortnextShort(int radix)
Returns the next token as a {@code short} with the specified radix. This method will block if input is being read. If the next token can be translated into a {@code short} the following is done: All {@code Locale}-specific prefixes, group separators, and {@code Locale}-specific suffixes are removed. Then non-ASCII digits are mapped into ASCII digits via {@link Character#digit(char, int)}, and a negative sign (-) is added if the {@code Locale}-specific negative prefix or suffix was present. Finally the resulting String is passed to {@link Short#parseShort(String, int)}} with the specified radix.

param
radix the radix used to translate the token into {@code short} value.
return
the next token as a {@code short}.
throws
IllegalStateException if this {@code Scanner} has been closed.
throws
NoSuchElementException if input has been exhausted.
throws
InputMismatchException if the next token can not be translated into a valid {@code short} value.
since
Android 1.0

        checkClosed();
        Object obj = cacheHasNextValue;
        cacheHasNextValue = null;
        if (obj instanceof Short) {
            findStartIndex = cachehasNextIndex;
            return (Short) obj;
        }
        Pattern integerPattern = getIntegerPattern(radix);
        String intString = next(integerPattern);
        intString = removeLocaleInfo(intString, DataType.INT);
        short shortValue = 0;
        try {
            shortValue = Short.parseShort(intString, radix);
        } catch (NumberFormatException e) {
            matchSuccessful = false;
            recoverPreviousStatus();
            throw new InputMismatchException();
        }
        return shortValue;
    
public intradix()
Return the radix of this {@code Scanner}.

return
the radix of this {@code Scanner}
since
Android 1.0

        return integerRadix;
    
private voidreadMore()

        int oldPosition = buffer.position();
        int oldBufferLength = bufferLength;
        // Increase capacity if empty space is not enough
        if (bufferLength >= buffer.capacity()) {
            expandBuffer();
        }

        // Read input resource
        int readCount = 0;
        try {
            buffer.limit(buffer.capacity());
            buffer.position(oldBufferLength);
            while ((readCount = input.read(buffer)) == 0) {
                // nothing to do here
            }
        } catch (IOException e) {
            // Consider the scenario: readable puts 4 chars into
            // buffer and then an IOException is thrown out. In this case, buffer is
            // actually grown, but readable.read() will never return.
            bufferLength = buffer.position();
            /*
             * Uses -1 to record IOException occurring, and no more input can be
             * read.
             */
            readCount = -1;
            lastIOException = e;
        }


        buffer.flip();
        buffer.position(oldPosition);
        if (-1 == readCount) {
            inputExhausted = true;
        } else {
            bufferLength = readCount + bufferLength;
        }
    
private voidrecoverPreviousStatus()

        findStartIndex = preStartIndex;
    
public voidremove()
Remove is not a supported operation on {@code Scanner}.

throws
UnsupportedOperationException if this method is invoked.
since
Android 1.0

        throw new UnsupportedOperationException();
    
private java.lang.StringremoveLocaleInfo(java.lang.String token, java.util.Scanner$DataType type)

        StringBuilder tokenBuilder = new StringBuilder(token);
        boolean negative = removeLocaleSign(tokenBuilder);
        // Remove group separator
        String groupSeparator = String.valueOf(decimalFormat
                .getDecimalFormatSymbols().getGroupingSeparator());
        int separatorIndex = -1;
        while (-1 != (separatorIndex = tokenBuilder.indexOf(groupSeparator))) {
            tokenBuilder.delete(separatorIndex, separatorIndex + 1);
        }
        // Remove decimal separator
        String decimalSeparator = String.valueOf(decimalFormat
                .getDecimalFormatSymbols().getDecimalSeparator());
        separatorIndex = tokenBuilder.indexOf(decimalSeparator);
        StringBuilder result = new StringBuilder(""); //$NON-NLS-1$
        if (DataType.INT == type) {
            for (int i = 0; i < tokenBuilder.length(); i++) {
                if (-1 != Character.digit(tokenBuilder.charAt(i),
                        Character.MAX_RADIX)) {
                    result.append(tokenBuilder.charAt(i));
                }
            }
        }
        if (DataType.FLOAT == type) {
            if (tokenBuilder.toString().equals(decimalFormat.getDecimalFormatSymbols()
                    .getNaN())) {
                result.append("NaN");//$NON-NLS-1$ 
            } else if (tokenBuilder.toString().equals(decimalFormat
                    .getDecimalFormatSymbols().getInfinity())) {
                result.append("Infinity");//$NON-NLS-1$ 
            } else {
                for (int i = 0; i < tokenBuilder.length(); i++) {
                    if (-1 != Character.digit(tokenBuilder.charAt(i), 10)) {
                        result.append(Character.digit(tokenBuilder.charAt(i),
                                10));
                    }
                }
            }
        }
        // Token is NaN or Infinity
        if (0 == result.length()) {
            result = tokenBuilder;
        }
        if (-1 != separatorIndex) {
            result.insert(separatorIndex, "."); //$NON-NLS-1$
        }
        // If input is negative
        if (negative) {
            result.insert(0, '-");
        }
        return result.toString();
    
private java.lang.StringremoveLocaleInfoFromFloat(java.lang.String floatString)

        // If the token is HexFloat
        if (-1 != floatString.indexOf('x")
                || -1 != floatString.indexOf('X")) {
            return floatString;
        }
        
        int exponentIndex;
        String decimalNumeralString;
        String exponentString;
        // If the token is scientific notation
        if (-1 != (exponentIndex = floatString.indexOf('e"))
                || -1 != (exponentIndex = floatString.indexOf('E"))) {
            decimalNumeralString = floatString.substring(0, exponentIndex);
            exponentString = floatString.substring(exponentIndex + 1,
                    floatString.length());
            decimalNumeralString = removeLocaleInfo(decimalNumeralString,
                    DataType.FLOAT);
            return decimalNumeralString + "e" + exponentString; //$NON-NLS-1$ 
        }
        return removeLocaleInfo(floatString, DataType.FLOAT);
    
private booleanremoveLocaleSign(java.lang.StringBuilder tokenBuilder)

        String positivePrefix = decimalFormat.getPositivePrefix();
        String positiveSuffix = decimalFormat.getPositiveSuffix();
        String negativePrefix = decimalFormat.getNegativePrefix();
        String negativeSuffix = decimalFormat.getNegativeSuffix();

        if (0 == tokenBuilder.indexOf("+")) { //$NON-NLS-1$
            tokenBuilder.delete(0, 1);
        }
        if (!positivePrefix.equals("") //$NON-NLS-1$
                && 0 == tokenBuilder.indexOf(positivePrefix)) {
            tokenBuilder.delete(0, positivePrefix.length());
        }
        if (!positiveSuffix.equals("") //$NON-NLS-1$
                && -1 != tokenBuilder.indexOf(positiveSuffix)) {
            tokenBuilder.delete(
                    tokenBuilder.length() - positiveSuffix.length(),
                    tokenBuilder.length());
        }
        boolean negative = false;
        if (0 == tokenBuilder.indexOf("-")) { //$NON-NLS-1$
            tokenBuilder.delete(0, 1);
            negative = true;
        }
        if (!negativePrefix.equals("") //$NON-NLS-1$
                && 0 == tokenBuilder.indexOf(negativePrefix)) {
            tokenBuilder.delete(0, negativePrefix.length());
            negative = true;
        }
        if (!negativeSuffix.equals("") //$NON-NLS-1$
                && -1 != tokenBuilder.indexOf(negativeSuffix)) {
            tokenBuilder.delete(
                    tokenBuilder.length() - negativeSuffix.length(),
                    tokenBuilder.length());
            negative = true;
        }
        return negative;
    
private voidresetMatcher()

        if (null == matcher) {
            matcher = delimiter.matcher(buffer);
        } else {
            matcher.reset(buffer);
        }
        matcher.region(findStartIndex, bufferLength);
    
private voidsaveCurrentStatus()

        preStartIndex = findStartIndex;
    
private booleansetHeadTokenRegion(int findIndex)

        int tokenStartIndex;
        int tokenEndIndex;
        boolean setSuccess = false;
        // If no delimiter exists, but something exites in this scanner
        if (-1 == findIndex && preStartIndex != bufferLength) {
            tokenStartIndex = preStartIndex;
            tokenEndIndex = bufferLength;
            findStartIndex = bufferLength;
            matcher.region(tokenStartIndex, tokenEndIndex);
            setSuccess = true;
        }
        // If the first delimiter of scanner is not at the find start position
        if (-1 != findIndex && preStartIndex != matcher.start()) {
            tokenStartIndex = preStartIndex;
            tokenEndIndex = matcher.start();
            findStartIndex = matcher.start();
            // set match region and return
            matcher.region(tokenStartIndex, tokenEndIndex);
            setSuccess = true;
        }
        return setSuccess;
    
private booleansetTokenRegion()

        // The position where token begins
        int tokenStartIndex = 0;
        // The position where token ends
        int tokenEndIndex = 0;
        // Use delimiter pattern
        matcher.usePattern(delimiter);
        matcher.region(findStartIndex, bufferLength);

        tokenStartIndex = findPreDelimiter();
        if (setHeadTokenRegion(tokenStartIndex)) {
            return true;
        }
        tokenEndIndex = findPostDelimiter();
        // If the second delimiter is not found
        if (-1 == tokenEndIndex) {
            // Just first Delimiter Exists
            if (findStartIndex == bufferLength) {
                return false;
            }
            tokenEndIndex = bufferLength;
            findStartIndex = bufferLength;
        }

        matcher.region(tokenStartIndex, tokenEndIndex);
        return true;
    
public java.util.Scannerskip(java.util.regex.Pattern pattern)
Tries to use specified pattern to match input starting from the current position. The delimiter will be ignored. If a match is found, the matched input will be skipped. If an anchored match of the specified pattern succeeds, the corresponding input will also be skipped. Otherwise, a {@code NoSuchElementException} will be thrown. Patterns that can match a lot of input may cause the {@code Scanner} to read in a large amount of input.

param
pattern used to skip over input.
return
the {@code Scanner} itself.
throws
IllegalStateException if the {@code Scanner} is closed.
throws
NoSuchElementException if the specified pattern match fails.
since
Android 1.0

        checkClosed();
        checkNull(pattern);
        matcher.usePattern(pattern);
        matcher.region(findStartIndex, bufferLength);
        while (true) {
            if (matcher.lookingAt()) {
                boolean matchInBuffer = matcher.end() < bufferLength
                        || (matcher.end() == bufferLength && inputExhausted);
                if (matchInBuffer) {
                    matchSuccessful = true;
                    findStartIndex = matcher.end();
                    break;
                }
            } else {
                if (inputExhausted) {
                    matchSuccessful = false;
                    throw new NoSuchElementException();
                }
            }
            if (!inputExhausted) {
                readMore();
                resetMatcher();
            }
        }
        return this;
    
public java.util.Scannerskip(java.lang.String pattern)
Tries to use the specified string to construct a pattern and then uses the constructed pattern to match input starting from the current position. The delimiter will be ignored. This call is the same as invoke {@code skip(Pattern.compile(pattern))}.

param
pattern the string used to construct a pattern which in turn is used to match input.
return
the {@code Scanner} itself.
throws
IllegalStateException if the {@code Scanner} is closed.
since
Android 1.0

        return skip(Pattern.compile(pattern));
    
public java.lang.StringtoString()
Returns a string representation of this {@code Scanner}. The information returned may be helpful for debugging. The format of the string is unspecified.

return
a string represendation of this {@code Scanner}.
since
Android 1.0

        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(this.getClass()).append(": ") //$NON-NLS-1$
                .append("{(delimiter:") //$NON-NLS-1$
                .append(delimiter).append(")(findStartIndex=") //$NON-NLS-1$
                .append(findStartIndex).append(")(match succeed=") //$NON-NLS-1$
                .append(matchSuccessful).append(")(closed=") //$NON-NLS-1$
                .append(closed).append(")}"); //$NON-NLS-1$
        return stringBuilder.toString();
    
public java.util.ScanneruseDelimiter(java.util.regex.Pattern pattern)
Sets the delimiting pattern of this {@code Scanner}.

param
pattern the delimiting pattern to use.
return
this {@code Scanner}.
since
Android 1.0

        delimiter = pattern;
        return this;
    
public java.util.ScanneruseDelimiter(java.lang.String pattern)
Sets the delimiting pattern of this {@code Scanner} with a pattern compiled from the supplied string value.

param
pattern a string from which a {@code Pattern} can be compiled.
return
this {@code Scanner}.
since
Android 1.0

        return useDelimiter(Pattern.compile(pattern));
    
public java.util.ScanneruseLocale(java.util.Locale l)
Sets the {@code Locale} of this {@code Scanner} to a specified {@code Locale}.

param
l the specified {@code Locale} to use.
return
this {@code Scanner}.
since
Android 1.0

        if (null == l) {
            throw new NullPointerException();
        }
        this.locale = l;
        return this;
    
public java.util.ScanneruseRadix(int radix)
Sets the radix of this {@code Scanner} to the specified radix.

param
radix the specified radix to use.
return
this {@code Scanner}.
since
Android 1.0

        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
            throw new IllegalArgumentException(org.apache.harmony.luni.util.Msg
                    .getString("KA008", radix)); //$NON-NLS-1$
        }
        this.integerRadix = radix;
        return this;