[Java] String クラスの indexOf や substring のインデックス | Archive Redo Blog

Archive Redo Blog

DBエンジニアのあれこれ備忘録

String クラスには、ある文字列の中から特定の文字(または文字列)の位置を返す indexOf メソッドや、文字列の中から特定の範囲の文字列を抽出する substring メソッドなどが用意されています。

これらの機能は文字データの処理でもよく使う機能で、どんな言語にも必ずといっていいほど備わっている機能なのだが、どうも使いづらいんですよね。

というのも、多くの言語ではこの種の機能で文字の位置を示す場合、"何文字目"という表現を使うのですが、Java の場合、"0から始まるインデックス"で表現するからなんです。

例えば、indexOf メソッドを使って

String str = new String( "ABCDEFGHIJKLMNOPQRSTUVWXYZ" );

という文字列から 'G' の位置を取得する場合、

int idx = str.indexOf( 'G' );

というように記述しますが、このとき 'G' は7文字目だから 7 が返ってくるのかと思いきや 6 が返ってきます。

"0から始まるインデックス"なので"何文字目-1"で考えなければいけないのです。

※文字が見つからなかった場合は、-1 が返ってきます。


substring メソッドの場合はさらにややこしくなります。

上記の文字列から 'JKL' を取得したい場合、indexOf メソッドでの挙動を踏まえて、

String str2 = new String( str.substring( 9, 11 ) );

というように記述するとなぜか 'JK' が返ってくるのです。

substring メソッドの場合、第一引数には文字列の"開始位置のインデックス"を指定すればいいのですが、第二引数にはなぜか"終了位置のインデックス+1"を指定しなければならないのです。

つまり、上記の例の場合、

String str2 = new String( str.substring( 9, 12 ) );

とすると 'JKL' が返ってきます。

もっとも、substring メソッドのような機能の場合、"何文字目から何文字目まで"と指定する言語もあれば、"何文字目から何文字"と指定する言語もあり、インデックスうんぬんを抜きにしても混乱するのですが...


この"インデックスが0から始まる"という仕様、全ての情報を0と1で表現するコンピュータ的には好都合なのでしょうが、人間工学的にはかなりイケてません。

なんとかならないものでしょうか...