Java Scanner hasNext () срещу hasNextLine ()

1. Общ преглед

Класът Scanner е удобен инструмент, който може да анализира примитивни типове и низове с помощта на регулярни изрази и е въведен в пакета java.util в Java 5.

В този кратък урок ще говорим за неговите методи hasNext () и hasNextLine () . Въпреки че тези два метода може да изглеждат доста сходни в началото, те всъщност правят доста различни проверки.

Можете също така да прочетете повече за универсалния клас скенери в краткото ръководство тук.

2. hasNext ()

2.1. Основна употреба

Методът hasNext () проверява дали скенерът има друг маркер във входа си. A Scanner разбива своя принос в жетони с помощта на модел разделител, който съвпада с празно пространство по подразбиране. Тоест hasNext () проверява входните данни и връща true, ако има друг небел интервал.

Трябва също да отбележим няколко подробности относно разделителя по подразбиране:

  • Пробелът включва не само интервалния знак, но и интервала на табулацията ( \ t ), подаването на редове ( \ n ) и дори повече символи
  • Непрекъснатите интервали се третират като единичен разделител
  • Празните редове в края на входа не се отпечатват - т.е. hasNext () връща false за празни редове

Нека да разгледаме пример за това как hasNext () работи с разделителя по подразбиране. Първо ще подготвим входен низ, който да ни помогне да проучим резултата от синтактичния анализ на S canner :

String INPUT = new StringBuilder() .append("magic\tproject\n") .append(" database: oracle\n") .append("dependencies:\n") .append("spring:foo:bar\n") .append("\n") // Note that the input ends with a blank line .toString();

След това нека анализираме входа и отпечатаме резултата:

Scanner scanner = new Scanner(INPUT); while (scanner.hasNext()) { log.info(scanner.next()); } log.info("--------OUTPUT--END---------") 

Ако стартираме горния код, ще видим изхода на конзолата:

[DEMO]magic [DEMO]project [DEMO]database: [DEMO]oracle [DEMO]dependencies: [DEMO]spring:foo:bar [DEMO]--------OUTPUT--END--------- 

2.2. С потребителски разделител

Досега разгледахме hasNext () с разделителя по подразбиране. Най- Scanner клас осигурява useDelimiter (String образец) метод , който ни позволява да промените разделител. След като разделителят бъде променен, методът hasNext () ще извърши проверката с новия разделител вместо този по подразбиране.

Нека видим друг пример за това как hasNext () и next () работят с персонализиран разделител. Ще използваме повторно входа от последния пример.

След скенера анализира знак съвпадение низ "на зависимости: ", ние ще се промени разделител за двоеточие ( :) , така че да може да анализира и да извлича всяка стойност на зависимостите:

while (scanner.hasNext()) { String token = scanner.next(); if ("dependencies:".equals(token)) { scanner.useDelimiter(":"); } log.info(token); } log.info("--------OUTPUT--END---------");

Нека да видим получения резултат:

[DEMO]magic [DEMO]project [DEMO]database: [DEMO]oracle [DEMO]dependencies: [DEMO] spring [DEMO]foo [DEMO]bar [DEMO]--------OUTPUT--END---------

Страхотен! Успешно извличаме стойностите в „ зависимости “, но има някои неочаквани проблеми с прекъсването на редове . Ще видим как да ги избегнем в следващия раздел.

2.3. С регулярно изражение като разделител

Нека да прегледаме резултата в последния раздел. Първо, забелязахме, че има прекъсване на ред ( \ n ) преди „ пролетта “. Променихме разделителя на „ : “ след извличането на маркера „зависимости:“ . Прекъсването на реда след „ зависимостите: “ сега става част от следващия маркер. Следователно hasNext () връща true и прекъсването на реда е отпечатано.

По същата причина подаването на редове след „ хибернация “ и последния празен ред стават част от последния маркер, така че два празни реда се отпечатват заедно с „ хибернация “.

Ако можем да направим едно и също двоеточие и интервал като разделител, тогава стойностите на „зависимости“ ще бъдат правилно анализирани и проблемът ни ще бъде решен. За да постигнем това, нека променим повикването useDelimiter (“:”) :

scanner.useDelimiter(":|\\s+"); 

: | \\ s + “ тук е регулярен израз, съответстващ на единичен „:“ или един или повече пробели. С тази корекция изходът се превръща в:

[DEMO]magic [DEMO]project [DEMO]database: [DEMO]oracle [DEMO]dependencies: [DEMO]spring [DEMO]foo [DEMO]bar [DEMO]--------OUTPUT--END---------

3. hasNextLine ()

Методът hasNextLine () проверява дали има друг ред във входа на обекта Scanner , без значение дали редът е празен или не.

Нека вземем същия вход отново. Този път ще добавим номера на редове пред всеки ред във входа, използвайки методите hasNextLine () и nextLine () :

int i = 0; while (scanner.hasNextLine())  log.info(String.format("%d log.info("--------OUTPUT--END---------");

Сега, нека да разгледаме нашите резултати:

[DEMO]1|magic project [DEMO]2| database: oracle [DEMO]3|dependencies: [DEMO]4|spring:foo:bar [DEMO]5| [DEMO]--------OUTPUT--END---------

Както очаквахме, номерата на редовете се отпечатват и последният празен ред също е там.

4. Заключение

В тази статия, ние научихме, че Scanner е hasNextLine () проверки метод, ако има друг ред във входа, без значение дали линията е празен или не, докато hasNext () използва разделител за да проверите за друг знак.

Както винаги, пълният изходен код за примерите е достъпен в GitHub.