String APIの罠
このレッスンを終えると、substring と indexOf と trim の結果を、実行する前に言い当てられるようになります。
まず予測してください
次のコードは何を返すでしょうか。
String s = "abcdef";
System.out.println(s.substring(1, 3));
System.out.println(s.indexOf("z"));答えは bc と -1 です。ここに Silver の頻出ポイントが2つ入っています。
substring の第2引数は「終わりの位置」ではなく「終わりの手前」
substring(begin, end) は begin 番目から end 番目の手前までを切り出します。切り出される文字数は end - begin です。substring(1, 3) は 1 番目と 2 番目、つまり bc の2文字になります。3 番目の d は入りません。
引数が1つの substring(begin) は、begin 番目から末尾までです。混ざりやすいので、引数の数で意味が変わることを覚えておいてください。
範囲の外を指すと StringIndexOutOfBoundsException が実行時に飛びます。これはコンパイルエラーではありません。s.substring(0, 100) は問題なくコンパイルが通り、動かした瞬間に落ちます。試験は「コンパイルエラー」と「実行時例外」を意図的に混ぜてくるので、区別してください。なお s.substring(3, 3) は例外ではなく空文字列を返します。ここも狙われます。
indexOf は見つからないと -1 を返す
indexOf は見つかった位置を返し、見つからないと -1 を返します。0 ではありません。先頭で見つかったときが 0 なので、if (s.indexOf("a") > 0) のような書き方は先頭一致を取りこぼします。-1 と比べるのが正しい判定です。
trim と strip は取れる範囲が違う
trim は文字コードが半角スペース以下の文字だけを削ります。全角スペースは文字コードがそれより大きいので、trim では取れません。Java 11 で入った strip は Unicode の空白判定を使うので、全角スペースも削ります。全角スペースを混ぜた文字列で trim と strip の結果を比べさせる問題が出ます。
どちらも元の文字列を書き換えません。String は不変なので、戻り値を受け取らないと何も起きない点も合わせて押さえてください。
要件
- 先頭3文字を substring で取り出す
- text の中の x の位置を indexOf で調べる。無ければその戻り値のまま使う
- text の前後に全角スペースを1つずつ足した文字列を作り、trim した長さと strip した長さを求める
- 先頭3文字、x の位置、trim 後の長さ、strip 後の長さをこの順にスラッシュでつないで返す
入出力例
report("abcdef") → "abc/-1/8/6"
report("xyz1") → "xyz/0/6/4"
report("xxabc") → "xxa/0/7/5"