В чем разница между методами next() и nextLine() из класса Scanner?

В чем основное различие между next() и nextLine()?
Моя основная цель – прочитать весь текст с помощью Scanner, который может быть "подключен" к любому источнику (например, к файлу).

Какой из них я должен выбрать и почему?


person AnnieOK    schedule 17.03.2014    source источник
comment
Это может помочь вам [Использование scan.nextLine()][1]: stackoverflow.com /questions/5032356/using-scanner-nextline   -  person Milaci    schedule 17.03.2014


Ответы (15)


Я всегда предпочитаю читать ввод с помощью nextLine(), а затем анализировать строку.

Использование next() вернет только то, что стоит перед разделителем (по умолчанию пробел). nextLine() автоматически перемещает сканер вниз после возврата текущей строки.

Полезным инструментом для анализа данных из nextLine() будет str.split("\\s+").

String data = scanner.nextLine();
String[] pieces = data.split("\\s+");
// Parse the pieces

Дополнительные сведения о классе Scanner или классе String см. по следующим ссылкам.

Сканер: http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html

Строка: http://docs.oracle.com/javase/7/docs/api/java/lang/String.html

person Tristan    schedule 17.03.2014
comment
Итак, почему бы просто не использовать BufferedReader для построчного чтения? Я не понимаю, почему Scanner в такой моде. - person David Conrad; 17.03.2014
comment
@DavidConrad В чем разница между методами next() и nextLine() из класса Scanner? - person Tristan; 17.03.2014
comment
Да, я понимаю, об этом спрашивал ОП, мне просто интересно, так как вы говорите, что всегда предпочитаете использовать nextLine. - person David Conrad; 17.03.2014
comment
Вы можете безопасно выполнить nextLine(), а затем создать новый сканер только для этой строки. Класс Scanner может сканировать строки: new Scanner( new Scanner(System.in).nextLine() ). - person axell-brendow; 09.11.2019

next() может читать ввод только до пробела. Он не может прочитать два слова, разделенные пробелом. Кроме того, next() помещает курсор в ту же строку после чтения ввода.

nextLine() читает ввод, включая пробелы между словами (то есть читает до конца строки \n). Как только ввод будет прочитан, nextLine() помещает курсор на следующую строку.

Для чтения всей строки вы можете использовать nextLine().

person RKC    schedule 17.03.2014
comment
@LuiggiMendoza, ты имеешь в виду форматирование, а не формальное письмо? - person Det; 12.08.2019
comment
next() может читать ввод только до пробела. Он не может прочитать два слова, разделенные пробелом. пробел включает пробел, табуляцию и перевод строки - person Fred Hu; 13.09.2020

Из JavaDoc:

  • Scanner разбивает свой ввод на токены, используя шаблон разделителя, который по умолчанию соответствует пробелу.
  • next(): находит и возвращает следующий полный токен из этого сканера.
  • nextLine(): Продвигает этот сканер дальше текущей строки и возвращает пропущенный ввод.

Таким образом, в случае "small example<eol>text" next() должен возвращать "маленький", а nextLine() должен возвращать "небольшой пример"

person Oleg Sklyar    schedule 17.03.2014
comment
почему next() не включает \n в возвращаемый токен?? - person rimalroshan; 13.01.2019
comment
Это вопрос к разработчикам Java API или задайте вопрос на SO, и, возможно, кто-то знает, почему. - person Oleg Sklyar; 13.01.2019

Ключевой момент — найти, где метод остановится и где будет стоять курсор после вызова методов.

Все методы будут считывать информацию, которая не включает пробелы между позицией курсора и следующими разделителями по умолчанию (пробелы, табуляция, \n — создаются нажатием Enter). Курсор останавливается перед разделителями, за исключением nextLine(), который считывает информацию (включая пробелы, созданные разделителями) между позицией курсора и \n, а курсор останавливается за \n.


Например, рассмотрим следующую иллюстрацию:

|23_24_25_26_27\n

| -> текущая позиция курсора

_ -> пробел

stream -> Bold (информация, полученная вызывающим методом)

Посмотрите, что происходит, когда вы вызываете эти методы:

nextInt()    

прочитать 23|_24_25_26_27\n

nextDouble()

прочитать 23_24|_25_26_27\n

next()

прочитать 23_24_25|_26_27\n

nextLine()

читать 23_24_25_26_27\n|


После этого метод должен быть вызван в зависимости от вашего требования.

person Z. Zhang    schedule 15.02.2017
comment
такой недооцененный ответ. все остальное немного вводит в заблуждение - person csguy; 13.05.2019

Что я заметил, помимо next() сканирует только вверх до пробела, тогда как nextLine() сканирует всю строку, так это то, что next ждет, пока не получит полный токен, тогда как nextLine() не ждет для полного токена, когда когда-либо получается '\n' (т. е. когда вы нажимаете клавишу ввода), курсор сканера перемещается на следующую строку и возвращает пропущенную предыдущую строку. Он не проверяет, указали ли вы полный ввод или нет, даже он будет принимать пустую строку, тогда как next() не принимает пустую строку

public class ScannerTest {

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        int cases = sc.nextInt();
        String []str = new String[cases];
        for(int i=0;i<cases;i++){
            str[i]=sc.next();
        }
     }

}

Попробуйте эту программу, изменив next() и nextLine() в цикле for, продолжайте нажимать '\n', что является клавишей ввода без ввода, вы можете обнаружить, что с помощью метода nextLine() он завершается после нажатия заданного количества случаев, когда next() не завершается, пока вы не предоставите и не введете его для заданного количества случаев.

person murali krish    schedule 17.04.2015
comment
Очень интересный пример. Запустив код, я, наконец, увидел, как next() работает на практике, он игнорирует клавишу ввода, тогда как nexLine() принимает его как полный ввод и реплицирует его на консоль, если вы повторяете значение того, что было захвачено. Я только что добавил System.out.println(str[i]); в качестве новой строки под str[i]=sc.next(); или str[i]=sc.nextLine();. - person Pablo Adames; 30.09.2019
comment
@PabloAdames признателен, если вы можете проголосовать за ответ, если вам это нравится - person murali krish; 01.10.2019

Вкратце: если вы вводите массив строк длины t, тогда Scanner#nextLine() ожидает t строк, каждая запись в массиве строк отличается от другой клавишей ввода. И Scanner#next() будет продолжать принимать входные данные до тех пор, пока вы нажимаете ввод, но сохраняете строку (слово) внутри массива, разделенного пробелом.

Давайте посмотрим на следующий фрагмент кода

    Scanner in = new Scanner(System.in);
    int t = in.nextInt();
    String[] s = new String[t];

    for (int i = 0; i < t; i++) {
        s[i] = in.next();
    }

когда я запускаю приведенный выше фрагмент кода в своей среде IDE (скажем, для длины строки 2), не имеет значения, ввожу ли я свою строку как

Введите как: - abcd abcd или

Введите как: -

abcd

abcd

Вывод будет как abcd

abcd

Но если в том же коде мы заменим метод next() на nextLine()

    Scanner in = new Scanner(System.in);
    int t = in.nextInt();
    String[] s = new String[t];

    for (int i = 0; i < t; i++) {
        s[i] = in.nextLine();
    }

Затем, если вы введете ввод в приглашении как - abcd abcd

Выход: -

абвд абвд

и если вы введете ввод в приглашении как abcd (и если вы нажмете ввод, чтобы ввести следующий abcd в другой строке, приглашение ввода просто выйдет, и вы получите вывод)

Выход: -

abcd

person himani1349    schedule 24.09.2015

Из javadocs

next() Возвращает следующий токен, если он соответствует шаблону, построенному из указанной строки. nextLine() Продвигает этот сканер дальше текущей строки и возвращает пропущенный ввод.

Какой из них вы выберете, зависит от того, что лучше всего соответствует вашим потребностям. Если бы я читал весь файл, я бы использовал nextLine, пока не получил бы весь файл.

person onesixtyfourth    schedule 17.03.2014

Из документации по сканеру:

Сканер разбивает входные данные на токены, используя шаблон разделителя, который по умолчанию соответствует пробелу.

Из документации для next() :

Перед полным токеном и за ним следует ввод, соответствующий шаблону разделителя.

person Foobar    schedule 17.03.2014

Методы next() и nextLine() связаны со сканером и используются для получения строковых входных данных. Отличия их...

next() может читать ввод только до пробела. Он не может прочитать два слова, разделенные пробелом. Кроме того, next() помещает курсор в ту же строку после чтения ввода.

nextLine() считывает ввод, включая пробелы между словами (то есть читает до конца строки \n). Как только ввод прочитан, nextLine() помещает курсор на следующую строку.

import java.util.Scanner;

public class temp
{
    public static void main(String arg[])
    {
        Scanner sc=new Scanner(System.in);
        System.out.println("enter string for c");
        String c=sc.next();
        System.out.println("c is "+c);
        System.out.println("enter string for d");
        String d=sc.next();
        System.out.println("d is "+d);
    }
}

Выход:

введите строку для c abc def
c is abc

введите строку для d

д по определению

Если вы используете nextLine() вместо next(), тогда

Выход:

введите строку для c

ABC DEF
c это ABC DEF
введите строку для d

GHI
d есть GHI

person Musaddique    schedule 07.04.2015

  • Просто для другого примера Scanner.next() и nextLine(), как показано ниже: nextLine() не позволяет пользователю вводить текст, а next() заставляет сканер ждать и читать ввод.

     Scanner sc = new Scanner(System.in);
    
     do {
        System.out.println("The values on dice are :");
        for(int i = 0; i < n; i++) {
            System.out.println(ran.nextInt(6) + 1);
        }
        System.out.println("Continue : yes or no");
     } while(sc.next().equals("yes"));
    // while(sc.nextLine().equals("yes"));
    
person annoo9605    schedule 31.12.2015

Обе функции используются для перехода к следующему токену сканера.

Разница заключается в том, как генерируется токен сканера.

next() генерирует токены сканера, используя разделитель в качестве пробела.

nextLine() генерирует токены сканера, используя разделитель как '\n' (т.е. нажатие клавиши Enter)

person Aditya Rewari    schedule 08.03.2020

Сканер разбивает входные данные на токены, используя шаблон разделителя, который по умолчанию известен как Пробелы.

Next() используется для чтения одного слова, и когда он получает пробел, чтение прекращается, а курсор возвращается в исходное положение. NextLine(), в то время как этот читает целое слово, даже если оно встречает пробел. Курсор останавливается, когда он заканчивает чтение, и курсор возвращается в конец строки. поэтому вам не нужно использовать разделитель, когда вы хотите прочитать полное слово как предложение. Вам просто нужно использовать NextLine().

 public static void main(String[] args) {
            // TODO code application logic here
           String str;
            Scanner input = new Scanner( System.in );
            str=input.nextLine();
            System.out.println(str);
       }
person Negash    schedule 06.04.2018

У меня также возникла проблема с разделителем. вопрос был все о вкладах

  1. введите ваше имя.
  2. введите свой возраст.
  3. введите адрес электронной почты.
  4. введите свой адрес.

Проблема

  1. Я успешно закончил с именем, возрастом и адресом электронной почты.
  2. Когда я придумал адрес из двух слов с пробелом (улица Харнет), я получил первое слово «харнет».

Решение

Я использовал разделитель для своего сканера и вышел успешным.

Пример

 public static void main (String args[]){
     //Initialize the Scanner this way so that it delimits input using a new line character.
    Scanner s = new Scanner(System.in).useDelimiter("\n");
    System.out.println("Enter Your Name: ");
    String name = s.next();
    System.out.println("Enter Your Age: ");
    int age = s.nextInt();
    System.out.println("Enter Your E-mail: ");
    String email = s.next();
    System.out.println("Enter Your Address: ");
    String address = s.next();

    System.out.println("Name: "+name);
    System.out.println("Age: "+age);
    System.out.println("E-mail: "+email);
    System.out.println("Address: "+address);
}
person Negash    schedule 06.04.2018

Основное отличие заключается в том, что next() используется для получения ввода до тех пор, пока не встретится разделитель (по умолчанию это пробел, но вы также можете изменить его) и вернуть введенный токен. Затем курсор остается на той же строке. В то время как в nextLine() он сканирует ввод, пока мы не нажмем кнопку ввода, вернем все это и поместим курсор в следующую строку. **

        Scanner sc=new Scanner(System.in);
        String s[]=new String[2];
        for(int i=0;i<2;i++){
            s[i]=sc.next();
        }
        for(int j=0;j<2;j++)
        {
            System.out.println("The string at position "+j+ " is "+s[j]);
        }

**

Попробуйте запустить этот код, задав ввод как «Hello World». Сканер считывает ввод до «o», а затем появляется разделитель. Таким образом, s[0] будет «Hello», а курсор будет указывать на следующую позицию после разделителя ( в нашем случае это «W»), и когда s[1] читается, он сканирует «Мир» и возвращает его s[1] в качестве следующего полного токена (по определению сканера). Если мы используем nextLine() вместо этого он будет читать «Hello World» полностью, а также больше, пока мы не нажмем кнопку ввода и не сохраним его в s[0]. Мы также можем передать другую строку, используя nextLine(). Я рекомендую вам попробовать использовать этот и другие примеры и попросить разъяснений.

person Simple Coder    schedule 04.08.2019

Разница может быть очень ясна с приведенным ниже кодом и его выводом.

    public static void main(String[] args) {
        List<String> arrayList = new ArrayList<>();
        List<String> arrayList2 = new ArrayList<>();
        Scanner input = new Scanner(System.in);

        String product = input.next();

        while(!product.equalsIgnoreCase("q")) {
            arrayList.add(product);
            product = input.next();
        }

        System.out.println("You wrote the following products \n");
        for (String naam : arrayList) {
            System.out.println(naam);
        }

        product = input.nextLine();
        System.out.println("Enter a product");
        while (!product.equalsIgnoreCase("q")) {
            arrayList2.add(product);
            System.out.println("Enter a product");
            product = input.nextLine();
        }

        System.out.println();
        System.out.println();
        System.out.println();
        System.out.println();

        System.out.println("You wrote the following products \n");
        for (String naam : arrayList2) {
            System.out.println(naam);
        }
    }

Вывод:

Enter a product
aaa aaa
Enter a product
Enter a product
bb
Enter a product
ccc cccc ccccc
Enter a product
Enter a product
Enter a product
q
You wrote the following products 

aaa
aaa
bb
ccc
cccc
ccccc
Enter a product
Enter a product
aaaa aaaa aaaa
Enter a product
bb
Enter a product
q




You wrote the following products 


aaaa aaaa aaaa
bb

Совершенно ясно, что пространство-разделитель по умолчанию добавляет продукты, разделенные пробелом, в список, когда используется следующий, поэтому каждый раз, когда строки, разделенные пробелами, вводятся в строку, это разные строки. В nextLine пробел не имеет значения, и вся строка представляет собой одну строку.

person KnockingHeads    schedule 24.05.2021