かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

java.util.Scannerを使ってみる

JavaSE5から追加されたjava.util.Scannerというクラスを今まで一度も使ったことが無かった。
ただの食わず嫌いだったので、ちょいと使い方を勉強!!

お試し!!

package okazuki;

import java.util.Scanner;

import junit.framework.TestCase;

public class ScannerTest extends TestCase {
	public void test普通にスペース区切りで読んでみる() throws Exception {
		Scanner scanner = new Scanner("Hello world");
		assertEquals("最初がHelloで", "Hello", scanner.next());
		assertEquals("次がworld", "world", scanner.next());		
	}
	
	public void test数字を読み込んでみる() throws Exception {
		Scanner scanner = new Scanner("123 456");
		assertEquals("最初は123で", 123, scanner.nextInt());
		assertEquals("次が456", 456, scanner.nextInt());
	}
	
	public void test数字と文字列の組み合わせ() throws Exception {
		Scanner scanner = new Scanner("Hello 123 world");
		assertFalse("最初のトークンは数字じゃないのでfalse", scanner.hasNextInt());
		assertEquals("最初のトークンはHello", "Hello", scanner.next());
		
		assertTrue("Helloの次は数字なのでtrue", scanner.hasNextInt());
		assertEquals("次のトークンは123", 123, scanner.nextInt());
		
		assertTrue("次のトークンが、まだあるのでtrue", scanner.hasNext());
		assertEquals("次のトークンはworld", "world", scanner.next());
		
		assertFalse("最後のトークンまで読んでしまったのでfalse", scanner.hasNext());
	}
}


成る程。
hasNext*****で次があるかどうか確認できて、next****系のメソッドで実際に値をゲットできるって寸法。
今まで自力でやってたのを考えると楽チンが出来るように作られてる。

区切り文字

デフォルトだと区切り文字としてCharacter.isWhitespaceがtrueを返すものを使うことになってます。
それだけじゃ不便なんで、この区切り文字を任意の文字(パターン)に変えることが出来ます。
たとえば下のコードは、カンマ区切りでデータを読むようにしています。

package okazuki;

import java.util.Scanner;

import junit.framework.TestCase;

public class ScannerCSVTest extends TestCase {
	public void testカンマ区切りで読み込む() throws Exception {
		Scanner scanner = new Scanner("1,2,3");
		scanner.useDelimiter(","); // カンマ区切り!!
		
		assertTrue("最初は数字の1だからtrue", scanner.hasNextInt());
		assertEquals("最初は数字の1のはず", 1, scanner.nextInt());
		
		assertTrue("次は数字の2だからtrue", scanner.hasNextInt());
		assertEquals("最初は数字の2のはず", 2, scanner.nextInt());
		
		assertTrue("最後は数字の3だからtrue", scanner.hasNextInt());
		assertEquals("最後は数字の3のはず", 3, scanner.nextInt());
		
		assertFalse("最後まで読んだのでfalse!", scanner.hasNext());
	}
}

useDelimiterメソッドが名前のとおり区切り文字を指定するメソッドです。
ここには、正規表現を指定することが出来ます。

hasNextメソッドやnextメソッドにも、正規表現やPatternクラスを受け取るものがある。
これを使うと、もうちょっとだけ請った読み取りが出来る。
でも、大体基本型のnext***メソッドとかは用意されてるので使用することは少ないだろう。


最後に、Scannerクラスのコンストラクタには、文字列以外もいろいろ指定できるのでJavadocで確認しておくとよさげ。