Going my way

いいなと思ったことをメモしていきます。

Stringクラスの中の人はけっこう面白かった。


Advertisements


JavaコンパイラJVMという仮想マシン用のマシン語を出力する。

仮想マシンの実行速度は、本物のハードウェアが直接マシン語を実行する場合と比較すると遅くなる(と言われていた)

その後、ホットスポットコンパイルなどの改善を行った。
※ただし、ホットスポットコンパイルが全て良いわけではない。
http://www.atmarkit.co.jp/fjava/rensai3/devedge06/devedge06_1.html

今ではJavaはどちらかというと、実行速度の早い言語と言われている。


Stringクラスについて

よく使われるメソッドのサンプル

package string;

public class MethodOfString {
	public static void main(String[] args){
		//Stringオブジェクトを生成する。
		//Stringオブジェクトは「不変」である。
		String str = "abcdef";
		
		//charAtは指定した位置の文字を取得する。
		System.out.println("charAt(index):"+str.charAt(3));
		
		//lengthは長さを取得
		System.out.println("length:"+str.length());
		
		//indexOfは指定した文字を文字列から検索する
		System.out.println("indexOf:"+str.indexOf("d"));
		
		//substring文字列の一部を取得する。この場合は3文字目から5文字目
		System.out.println("substring(3,5):"+str.substring(3,5));
	}
}

実行結果は

charAt(index):d
length:6
indexOf:3
substring(3,5):de

次に上記のメソッドを使って、メールアドレスのアカウントとドメインを分割してみる。

package string;

public class PrintMailAddress {
	public static void main(String[] args){
		String mailAddress = "hogefugaboofuu@softbank.ne.jp";
		int atMarkIndex = mailAddress.indexOf("@");
		int lastMailAddressIndex = mailAddress.length();
		String account = mailAddress.substring(0,atMarkIndex);
		String domain = mailAddress.substring(atMarkIndex + 1,lastMailAddressIndex);
		
		System.out.println("アカウントは→"+account);
		System.out.println("ドメインは→"+domain);

	}
}

実行結果はこちら

アカウントは→hogefugaboofuu
ドメインは→softbank.ne.jp


文字列リテラルとは
ダブルクォート文字(")で文字の並びを囲んだ表記のこと。

なぜStringはnewしないのか。
Javaの文字列リテラルは暗黙にStringクラスのオブジェクトを生成する。

String str = "hoge";
だったら、
strは"hoge"という文字列リテラルを持つStringオブジェクトを参照する。

例えば、
System.out.println("hoge".getClass());
とすると、
class java.lang.String
が出力される。
"hoge"はStringクラスであるということである。


charAtメソッドの中身
Javaで公開されているコードを見て面白かったので紹介。

    public char charAt(int index) {
        if ((index < 0) || (index >= count)) {
            throw new StringIndexOutOfBoundsException(index);
        }
        return value[index + offset];
    }

charAtは、引数の数字で指定した場所にある文字を返すんだけど、
このメソッドの実装からわかるように、Stringクラスは1文字1文字を配列で持っている。
その中の引数で指定した数字の位置にある配列の文字を返すということ。
ちなみに、offsetは文字列の始まりで、普通は0になっている。


Stringクラスのequalsのメソッドの実装内容

    public boolean equals(Object anObject) {
	if (this == anObject) {
	    return true;
	}
	if (anObject instanceof String) {
	    String anotherString = (String)anObject;
	    int n = count;
	    if (n == anotherString.count) {
		char v1[] = value;
		char v2[] = anotherString.value;
		int i = offset;
		int j = anotherString.offset;
		while (n-- != 0) {
		    if (v1[i++] != v2[j++])
			return false;
		}
		return true;
	    }
	}
	return false;
    }
    

Stringはequalsで比較するって言われているけど、じゃあequalsの中で何をやっているのかと言うと、

①引数で指定したオブジェクトがStringクラスのオブジェクトであることを確認。
②Stringクラスが持つ1文字1文字が詰まった配列を順番にマッチングさせていって、一文字でも合わないと
return falseで返しているんだね。

こうやって、実際Stringクラスの中のソースを見ると、メソッドの意味がよくわかって面白い。
まぁ、実装を意識しないで使えるのがオブジェクト指向の良い所なんだけど。