Java Scanner hasNext () berbanding hasNextLine ()

1. Gambaran keseluruhan

The Scanner kelas adalah alat yang berguna yang boleh menghuraikan jenis primitif dan tali menggunakan ungkapan biasa dan telah diperkenalkan ke dalam java.util pakej di Jawa 5.

Dalam tutorial ringkas ini, kita akan membincangkan kaedah hasNext () dan hasNextLine () . Walaupun pada awalnya kedua kaedah ini kelihatan serupa, mereka sebenarnya melakukan pemeriksaan yang berbeza.

Anda juga boleh membaca lebih lanjut mengenai kelas Pengimbas serba boleh dalam panduan ringkas di sini.

2. mempunyaiSeterusnya ()

2.1. Penggunaan Asas

Kaedah hasNext () memeriksa sama ada Pengimbas mempunyai token lain dalam inputnya. A Scanner memecah input ke dalam token menggunakan corak pembatas, yang sepadan dengan ruang kosong secara lalai. Maksudnya, hasNext () memeriksa input dan mengembalikan nilai benar jika mempunyai watak bukan ruang kosong yang lain.

Kami juga harus memperhatikan beberapa butiran mengenai pembatas lalai:

  • Ruang kosong tidak hanya merangkumi watak spasi, tetapi juga ruang tab ( \ t ), umpan baris ( \ n ), dan lebih banyak lagi aksara
  • Watak ruang kosong yang berterusan dianggap sebagai pembatas tunggal
  • Garis kosong pada akhir input tidak dicetak - iaitu, hasNext () mengembalikan false untuk baris kosong

Mari kita lihat contoh bagaimana hasNext () berfungsi dengan pembatas lalai. Pertama, kami akan menyediakan rentetan input untuk membantu kami meneroka hasil penguraian 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();

Seterusnya, mari kita menguraikan input dan mencetak hasilnya:

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

Sekiranya kita menjalankan kod di atas, kita akan melihat output konsol:

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

2.2. Dengan Pembatas Tersuai

Setakat ini, kami telah melihat hasNext () dengan pembatas lalai. The Scanner kelas menyediakan useDelimiter (corak String) kaedah yang membolehkan kita untuk menukar pembatas. Setelah pembatas diubah, kaedah hasNext () akan melakukan pemeriksaan dengan pembatas baru dan bukan yang lalai.

Mari kita lihat contoh lain bagaimana hasNext () dan next () berfungsi dengan pembatas tersuai. Kami akan menggunakan semula input dari contoh terakhir.

Selepas pengimbas yang mem-parsing yang sepadan token string " kebergantungan: ", kami akan menukar pembatas kepada kolon ( :) supaya kita dapat menghuraikan dan mengekstrak setiap nilai kebergantungan:

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

Mari lihat hasil yang dihasilkan:

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

Hebat! Kami berjaya mengekstrak nilai dalam " dependencies ", namun ada beberapa masalah break line yang tidak dijangka . Kami akan melihat bagaimana mengelakkannya di bahagian seterusnya.

2.3. Dengan regex sebagai Pembatas

Mari kita tinjau output di bahagian terakhir. Pertama, kita perhatikan bahawa terdapat pemutusan garis ( \ n ) sebelum " musim bunga ". Kami telah menukar pembatas menjadi " : " setelah token "dependencies:" diambil. Garis putus selepas " dependencies: " kini menjadi bahagian dari token seterusnya. Oleh itu, hasNext () kembali benar dan jeda baris dicetak.

Atas sebab yang sama, umpan baris setelah “ hibernate ” dan baris kosong terakhir menjadi bahagian token terakhir, jadi dua baris kosong dicetak bersama dengan “ hibernate ”.

Sekiranya kita dapat menjadikan ruang kosong dan ruang kosong sebagai pembatas, maka nilai "kebergantungan" akan dihuraikan dengan betul dan masalah kita akan diselesaikan. Untuk mencapainya, mari ubah panggilan useDelimiter (“:”) :

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

" : | \\ s + " di sini adalah ungkapan biasa yang sepadan dengan satu ":" atau satu atau lebih watak ruang kosong. Dengan pembaikan ini, output berubah menjadi:

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

3. mempunyaiNextLine ()

The hasNextLine() method checks to see if there's another line in the input of the Scanner object, no matter if the line is blank or not.

Let's take the same input again. This time, we'll add line numbers in front of each line in the input using hasNextLine() and nextLine() methods:

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

Now, let's take a look at our output:

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

As we expected, the line numbers are printed, and the last blank line is there, too.

4. Conclusion

In this article, we've learned that Scanner‘s hasNextLine() method checks if there is another line in the input, no matter if the line is blank or not, while hasNext() uses a delimiter to check for another token.

Seperti biasa, kod sumber lengkap untuk contoh boleh didapati di GitHub.