HOWTO · Java

Java で文字列を Int 配列に変換する

この記事では、Java で String を int 配列に変換する方法を紹介します。

このページの内容

Java プログラムで [1, 2, 3] のような角括弧付きのカンマ区切り整数テキストを扱う場合は、角括弧を取り除き、カンマで分割して、各トークンを int に解析します。結果はプリミティブ型の int[] です。以下の例はこの形式を前提としています。入力が JSON や別の文法に従う場合は、その形式に対応したパーサーを使用してください。

変換方法を選ぶ

短い変換には replaceAll() と split()、簡潔な処理の流れを好む場合は Java 8 のストリーム、区切り文字の集合でトークンを処理する場合は StringTokenizer を使います。いずれの方法でも、最終的には Integer.parseInt() を呼び出します。ストリームの例には Java 8 以降が必要です。他の例も標準の Java API を使用しています。いずれかの方法を選び、入力元が保証する内容に合わせて入力検証を調整してください。

replaceAll() と split() を使う

この例では、角括弧を取り除き、残ったテキストをカンマで分割し、各トークンの前後の空白を除いてから、解析した値を整数配列に格納します。

次の例を実行します。

このセクションのコードと表示されるラベルや出力は英語のままです。

import java.util.Arrays;

public class ConvertStringToIntArray {
  public static void main(String[] args) {
    String text = "[1,2,3]";
    String[] tokens = text.replaceAll("[\\[\\]]", "").split(",");
    int[] values = new int[tokens.length];

    for (int i = 0; i < tokens.length; i++) {
      values[i] = Integer.parseInt(tokens[i].trim());
    }

    System.out.println(Arrays.toString(values));
  }
}

replaceAll() は正規表現を受け取り、split() も区切り文字を正規表現として解釈します。各トークンの前後を空白除去するため、同じループで数値の前後に空白がある入力も処理できます。この基本的な変換は角括弧付きのカンマ区切り入力を前提としており、角括弧を取り除く前にその形式を検証しません。

Java 8 のストリームを使う

ストリームを使うと、同じ処理をパイプラインとして表せます。先頭と末尾の文字を取り除き、内容を分割し、各トークンの前後の空白を除去して解析した後、toArray() でプリミティブ型の値を配列にまとめます。このクラスは完成した例であり、Java 8 以降でコンパイルできます。

このセクションのコードと表示されるラベルや出力は英語のままです。

import java.util.Arrays;

public class StringToIntUsingJava8Stream {
  public static void main(String[] args) {
    String text = "[1, 2, 3]";
    int[] values = Arrays.stream(text.substring(1, text.length() - 1).split(","))
        .map(String::trim)
        .mapToInt(Integer::parseInt)
        .toArray();

    System.out.println(Arrays.toString(values));
  }
}

substring(1, text.length() - 1) は、先頭と末尾の文字が想定した角括弧であることを前提としています。信頼できない入力にこの簡略化した処理を使う場合は、先にその文字を検証してください。

StringTokenizer を使う

StringTokenizer は、区切り文字の引数を区切り文字の集合として扱います。この例では、カンマまたは角括弧のどちらかでトークンが区切られます。カンマの後に空白があっても処理できるよう、解析する前に各トークンの前後の空白を取り除いてください。

このセクションのコードと表示されるラベルや出力は英語のままです。

import java.util.Arrays;
import java.util.StringTokenizer;

public class StringToIntUsingStringTokenizer {
  public static void main(String[] args) {
    String text = "[1, 2, 3]";
    StringTokenizer tokenizer = new StringTokenizer(text, "[],");
    int[] values = new int[tokenizer.countTokens()];
    int index = 0;

    while (tokenizer.hasMoreTokens()) {
      values[index++] = Integer.parseInt(tokenizer.nextToken().trim());
    }

    System.out.println(Arrays.toString(values));
  }
}

split() と異なり、StringTokenizer は連続する区切り文字を読み飛ばし、空のフィールドに対するトークンを生成しません。この動作では値の欠落を見逃す可能性があります。カンマで区切られた各位置に値が必要な場合は、明示的に検証してください。

空白と無効な数値を処理する

Integer.parseInt() は符号と10進数字を任意で受け付けますが、前後の空白は無視しません。先に各トークンへ trim() を呼び出してください。空文字列、[1,,3] の中央の項目のような空フィールド、または x のようなテキストは解析できません。split() は既定の動作で末尾の空フィールドも取り除くため、split(",", -1) を使ってすべてのトークンを検証しない限り、[1,2,] の末尾に値がないことを検出できない場合があります。StringTokenizer も連続する区切り文字を読み飛ばすため、それだけでは空フィールドを報告できません。

不正なテキストや int の範囲外の値を渡すと、Integer.parseInt() は NumberFormatException をスローします。プログラムで復旧できる場合は、この例外を個別に捕捉し、失敗したトークンを報告するか、入力全体を拒否してください。あらかじめ確保した配列に値を代入した後、捕捉ブロックで単に処理を続けると、代入されなかった要素には Java の既定値である 0 が残ります。このゼロは解析に成功した値ではありません。信頼できる入力として受け入れる前に、角括弧の構造を確認し、必要なトークンがすべて存在することを検証してください。