# JAVA基础

# 输入输出

# next(),nextLine(), nextInt()

看源码 👀

// next()
/**
     * Finds and returns the next complete token from this scanner.
     * A complete token is preceded and followed by input that matches
     * the delimiter pattern. This method may block while waiting for input
     * to scan, even if a previous invocation of {@link #hasNext} returned
     * <code>true</code>.
     *
     * @return the next token
     * @throws NoSuchElementException if no more tokens are available
     * @throws IllegalStateException if this scanner is closed
     * @see java.util.Iterator
     */
public String next() {
    ensureOpen();
    clearCaches();

    while (true) {
        String token = getCompleteTokenInBuffer(null);
        if (token != null) {
            matchValid = true;
            skipped = false;
            return token;
        }
        if (needInput)
            readInput();
        else
            throwFor();
    }
}
// nextLine()
/**
     * Advances this scanner past the current line and returns the input
     * that was skipped.
     *
     * This method returns the rest of the current line, excluding any line
     * separator at the end. The position is set to the beginning of the next
     * line.
     *
     * <p>Since this method continues to search through the input looking
     * for a line separator, it may buffer all of the input searching for
     * the line to skip if no line separators are present.
     *
     * @return the line that was skipped
     * @throws NoSuchElementException if no line was found
     * @throws IllegalStateException if this scanner is closed
     */
public String nextLine() {
    if (hasNextPattern == linePattern())
        return getCachedResult();
    clearCaches();

    String result = findWithinHorizon(linePattern, 0);
    if (result == null)
        throw new NoSuchElementException("No line found");
    MatchResult mr = this.match();
    String lineSep = mr.group(1);
    if (lineSep != null)
        result = result.substring(0, result.length() - lineSep.length());
    if (result == null)
        throw new NoSuchElementException();
    else
        return result;
}
// nextInt()
/**
     * Scans the next token of the input as an <tt>int</tt>.
     *
     * <p> An invocation of this method of the form
     * <tt>nextInt()</tt> behaves in exactly the same way as the
     * invocation <tt>nextInt(radix)</tt>, where <code>radix</code>
     * is the default radix of this scanner.
     *
     * @return the <tt>int</tt> scanned from the input
     * @throws InputMismatchException
     *         if the next token does not match the <i>Integer</i>
     *         regular expression, or is out of range
     * @throws NoSuchElementException if input is exhausted
     * @throws IllegalStateException if this scanner is closed
     */
public int nextInt() {
    return nextInt(defaultRadix);
    //注: private int defaultRadix = 10;
}
/**
     * Scans the next token of the input as an <tt>int</tt>.
     * This method will throw <code>InputMismatchException</code>
     * if the next token cannot be translated into a valid int value as
     * described below. If the translation is successful, the scanner advances
     * past the input that matched.
     *
     * <p> If the next token matches the <a
     * href="#Integer-regex"><i>Integer</i></a> regular expression defined
     * above then the token is converted into an <tt>int</tt> value as if by
     * removing all locale specific prefixes, group separators, and locale
     * specific suffixes, then mapping non-ASCII digits into ASCII
     * digits via {@link Character#digit Character.digit}, prepending a
     * negative sign (-) if the locale specific negative prefixes and suffixes
     * were present, and passing the resulting string to
     * {@link Integer#parseInt(String, int) Integer.parseInt} with the
     * specified radix.
     *
     * @param radix the radix used to interpret the token as an int value
     * @return the <tt>int</tt> scanned from the input
     * @throws InputMismatchException
     *         if the next token does not match the <i>Integer</i>
     *         regular expression, or is out of range
     * @throws NoSuchElementException if input is exhausted
     * @throws IllegalStateException if this scanner is closed
     */
public int nextInt(int radix) {
    // Check cached result
    if ((typeCache != null) && (typeCache instanceof Integer)
        && this.radix == radix) {
        int val = ((Integer)typeCache).intValue();
        useTypeCache();
        return val;
    }
    setRadix(radix);
    clearCaches();
    // Search for next int
    try {
        String s = next(integerPattern());
        if (matcher.group(SIMPLE_GROUP_INDEX) == null)
            s = processIntegerToken(s);
        return Integer.parseInt(s, radix);
    } catch (NumberFormatException nfe) {
        position = matcher.start(); // don't skip bad token
        throw new InputMismatchException(nfe.getMessage());
    }
}

算了,源码写得太抽象,还写几个例子试试吧

//test1
Scanner scanner = new Scanner(System.in);
String a = scanner.next();
String b = scanner.next();
System.out.println(a);
System.out.println(b.length());
System.out.println(b);
System.out.println(b.length());
// 输入 {空格}{tab}{换行}abc{空格}def
// 输出 
// abc 
// 3
// def
// 3

可以看出 next() 从第一个非空字符(非空格、tab、Enter)开始,到空字符(空格、tab、Enter)结束

Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt();
String b = scanner.next();
System.out.println(a);
System.out.println(b);
System.out.println(b.length());
// 输入:{空格}{tab}{换行}123{空格}def
// 输出:
// 123
// def
// 3

可以看出 nextInt() 和 next() 一样 从第一个非空字符(非空格、tab、Enter)开始,到空字符(空格、tab、Enter)结束,但读取的是一个 int 数字

Scanner scanner = new Scanner(System.in);
String a = scanner.nextLine();
String b = scanner.next();
System.out.println(a);
System.out.println(a.length());
System.out.println(b);
System.out.println(b.length());
// 输入: {空格}{tab}{Enter}{空格}a{空格}
// 输出:
// 
// 2
// a
// 1

可以看出 nextLine() 读取下一个Enter之前的全部字符,包括空格和tab,一直到Enter结束

Scanner scanner = new Scanner(System.in);
String a = scanner.next();
String b = scanner.nextLine();
System.out.println(a);
System.out.println(a.length());
System.out.println(b);
System.out.println(b.length());
// 输入:{空格}{tab}abc{Enter}
// 输出:
// abc
// 3
//  (nextLine()读了个寂寞)
// 1

// 输入:{空格}{tab}abc{空格}{空格}{Enter}
// 输出:
// abc
// 3
//    (nextLine()读取到两个空格)
// 2

需要注意的是在 next() 或 nextInt() 等方法后执行 nextLint() 可能让 nextLine() 读取到错误的结果。

这是因为 next() 或 nextInt() 读到空字符结束(空格、tab、Enter),但不会吧空字符读进去,所以后面的空字符就会被紧接着的 nextLine() 读取到,如果这里面恰好有换行,那么 nextLine() 读取的内容就是这个换行符前的一些空字符

Last Updated: 1/16/2021, 9:27:12 AM