Java Scanner hasNext () vs. hasNextLine ()

1. Ikhtisar

Kelas Scanner adalah alat praktis yang dapat mengurai jenis dan string primitif menggunakan ekspresi reguler dan diperkenalkan ke dalam paket java.util di Java 5.

Dalam tutorial singkat ini, kita akan membicarakan tentang metode hasNext () dan hasNextLine () . Meskipun kedua metode ini mungkin terlihat sangat mirip pada awalnya, mereka sebenarnya melakukan pemeriksaan yang sangat berbeda.

Anda juga dapat membaca lebih lanjut tentang kelas Scanner serbaguna dalam panduan cepat di sini.

2. hasNext ()

2.1. Penggunaan Dasar

Metode hasNext () memeriksa apakah Pemindai memiliki token lain dalam masukannya. Sebuah Scanner istirahat masukan ke dalam token menggunakan pola pembatas, yang cocok spasi secara default. Artinya, hasNext () memeriksa input dan mengembalikan nilai true jika memiliki karakter non-spasi lain.

Kami juga harus mencatat beberapa detail tentang pembatas default:

  • Spasi putih tidak hanya mencakup karakter spasi, tetapi juga spasi tab ( \ t ), umpan baris ( \ n ), dan bahkan lebih banyak karakter
  • Karakter spasi kosong terus menerus diperlakukan sebagai pemisah tunggal
  • Baris kosong di akhir input tidak dicetak - yaitu, hasNext () mengembalikan false untuk baris kosong

Mari kita lihat contoh bagaimana hasNext () bekerja dengan pembatas default. Pertama, kita akan menyiapkan string input untuk membantu kita menjelajahi hasil parsing 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();

Selanjutnya, mari mengurai input dan mencetak hasilnya:

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

Jika kita menjalankan kode di atas, kita akan melihat keluaran konsol:

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

2.2. Dengan Pembatas Kustom

Sejauh ini, kita telah melihat hasNext () dengan pembatas default. The Scanner kelas menyediakan useDelimiter (pola String) metode yang memungkinkan kita untuk mengubah pembatas. Setelah pembatas diubah, metode hasNext () akan melakukan pemeriksaan dengan pembatas baru, bukan dengan yang default.

Mari kita lihat contoh lain tentang cara kerja hasNext () dan next () dengan pembatas kustom. Kami akan menggunakan kembali masukan dari contoh terakhir.

Setelah pemindai mem-parsing yang cocok token string “ dependensi: “, kami akan mengubah pembatas untuk usus ( :) sehingga kita dapat mengurai dan ekstrak setiap nilai dependensi:

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

Mari kita lihat hasil yang dihasilkan:

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

Bagus! Kami telah berhasil mengekstrak nilai dalam " dependensi ", namun, ada beberapa masalah jeda baris yang tidak terduga . Kita akan melihat bagaimana menghindarinya di bagian selanjutnya.

2.3. Dengan regex sebagai Pembatas

Mari kita tinjau hasilnya di bagian terakhir. Pertama, kami memperhatikan bahwa ada baris baru ( \ n ) sebelum " musim semi ". Kami telah mengubah pembatas menjadi " : " setelah token "dependencies:" diambil. Jeda baris setelah " dependensi: " sekarang menjadi bagian dari token berikutnya. Oleh karena itu, hasNext () mengembalikan nilai true dan hentian baris dicetak.

Untuk alasan yang sama, baris diumpankan setelah " hibernate " dan baris kosong terakhir menjadi bagian dari token terakhir, jadi dua baris kosong dicetak bersama dengan " hibernate ".

Jika kita dapat menjadikan titik dua dan spasi sebagai pembatas, maka nilai "dependensi" akan diuraikan dengan benar dan masalah kita akan terpecahkan. Untuk mencapai itu, mari kita ubah panggilan useDelimiter (“:”) :

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

" : | \\ s + " di sini adalah ekspresi reguler yang cocok dengan satu ":" atau satu atau lebih karakter spasi. Dengan perbaikan ini, hasilnya berubah menjadi:

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

3. hasNextLine ()

Metode hasNextLine () memeriksa untuk melihat apakah ada baris lain dalam input objek Scanner , tidak peduli apakah baris tersebut kosong atau tidak.

Mari kita ambil masukan yang sama lagi. Kali ini, kami akan menambahkan nomor baris di depan setiap baris dalam input menggunakan metode hasNextLine () dan nextLine () :

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

Sekarang, mari kita lihat keluaran kita:

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

Seperti yang kami harapkan, nomor baris dicetak, dan baris kosong terakhir juga ada.

4. Kesimpulan

Pada artikel ini, kita telah belajar bahwa Scanner 's hasNextLine () metode memeriksa apakah ada baris lain di input, tidak peduli apakah garis kosong atau tidak, sementara hasNext () menggunakan pembatas untuk memeriksa tanda lain.

Seperti biasa, kode sumber lengkap untuk contoh tersedia di GitHub.