ChoiceFormatクラス

広告

ChoiceFormatはDecimalFormatクラスと同様、NumberFormatクラスの実装クラスです。ただ使い方はかなり違っており、対象となる数値の大きさによって対応する文字列を選択するようなフォーマットを指定します。

まず下記のクラス図を見てください。

java.lang.Object
  java.text.Format
    java.text.NumberFormat
      java.text.ChoiceFormat

public class ChoiceFormat extends NumberFormat

コンストラクタは2つ用意されています。

コンストラクタ
ChoiceFormat(double[] limits, String[] formats)
指定されたリミットとそれに対応するフォーマットによりオブジェクトを構築します。
ChoiceFormat(String newPattern)
指定されたパターンに基づくリミットとそれに対応するフォーマットによりオブジェクトを構築します。

まず1番目のコンストラクタを見てください。

public ChoiceFormat(double[] limits, String[] formats)

指定されたリミットとそれに対応するフォーマットによりオブジェクトを構築
します。

基本的な考え方は次の通りです。まずdouble型の配列を用意します。これはフォーマットの対象となる数値を区分するための仕切りの値の配列です。例えば、下記のような配列だったとします。

double[] limits = {1,2,3,4,5,6,7};

このようにした場合、フォーマットの対象となる数値が2.5だった場合は2に、3.4だった場合は3に、となります。これは次のルールによります。

X matches j if and only if limit[j] <= X < limit[j+1]

これでフォーマットの対象となる数値が、limitの配列に記述した数値のどれかに所属することになります。次にlimitの配列と同じ数の対応する文字列の配列を用意します。

String[] formats = {"Sun","Mon","Tue","Wed","Thur","Fri","Sat"};

フォーマットの対象となる数値が2.5だった場合は、まずlimit内の配列の値から"2"になり、それに対応するfomatの配列から"Mon"がフォーマットされた結果となります。

1番目のコンストラクタを使った場合はこのような感じです。実際に簡単な例で試してみましょう。

import java.text.ChoiceFormat;

public class SwingTest{
  public static void main(String[] args){

    double[] limits = {1,1.5,2,2.5,3};
    String[] monthNames = {"Sun","Mon","Tue","Wed","Thur"};

    ChoiceFormat cf = new ChoiceFormat(limits, monthNames);

    for (double i = 0.0; i <= 4.5; i += 0.3){
      System.out.println(i + " -> " + cf.format(i));
    }
  }
}

実行結果は下記のようになります。

0.0 -> Sun
0.3 -> Sun
0.6 -> Sun
0.8999999999999999 -> Sun
1.2 -> Sun
1.5 -> Mon
1.8 -> Mon
2.1 -> Tue
2.4 -> Tue
2.6999999999999997 -> Wed
2.9999999999999996 -> Wed
3.2999999999999994 -> Thur
3.599999999999999 -> Thur
3.899999999999999 -> Thur
4.199999999999999 -> Thur
4.499999999999999 -> Thur

見ていただくと分かる通り、limitの配列で指定した区切りの数値と比較して、最小値よりも小さい値は最小値と同じに、最大値よりも大きい値は最大値と同じ結果となります。

では、最後の値よりも大きい値は別のフォーマットを指定したい場合はどうするかというと、ChoiceFormatクラスで用意されているnextDoubleメソッドを使います。

public static final double nextDouble(double d)

d より大きな最小の double を見つけます。NaN の場合は、同じ値を返します。
一方が開いた間隔を作るのに使用します。

staticなメソッドですので、下記のような使い方をします。

double[] limits = {1,1.5,2,2.5,3,ChoiceFormat.nextDouble(3)};
String[] monthNames = {"Sun","Mon","Tue","Wed","Thur","Fri"};

これで3までの値は"Wed"ですが、3より大きい値は"Fri"となります。ChoiceFormat.nextDouble(3)の代わりに3より大きい適当な値を入れても結果は同じとなりますが(対象の数値がその値よりも大きくても最後の値に対応するのは先ほどの例で見た通りです。その為適当な値が何であっても結果は同じとなります)、適当な値を入れるよりはこのように書いた方が意図が分かりやすいかと思います。

同じように小さい値のためにpreviousDoubleメソッドも用意されています。

public static final double previousDouble(double d)

d より小さな最大の double を見つけます。NaN の場合は、同じ値を返します。

これも簡単なサンプルで試してみましょう。

import java.text.ChoiceFormat;

public class SwingTest{
  public static void main(String[] args){

    double[] limits = 
        {ChoiceFormat.previousDouble(1),1,1.5,2,2.5,3,ChoiceFormat.nextDouble(3)};
    String[] monthNames = {"Sun","Mon","Tue","Wed","Thur", "Fri", "Sat"};

    ChoiceFormat cf = new ChoiceFormat(limits, monthNames);

    for (double i = 0.5; i <= 3.5; i += 0.5){
      System.out.println(i + " -> " + cf.format(i));
    }
  }
}

実行結果は下記のようになります。

0.5 -> Sun
1.0 -> Mon
1.5 -> Tue
2.0 -> Wed
2.5 -> Thur
3.0 -> Fri
3.5 -> Sat

パターンで指定する

次にパターンで指定する場合です。2番目のコンストラクタを見て下さい。

public ChoiceFormat(String newPattern)

指定されたパターンに基づくリミットとそれに対応するフォーマットにより
オブジェクトを構築します。

パターンは、先ほどのコンストラクタの引数で指定したlimitとformatをまとめて記載するような書き方となります。詳しい書き方が記載されていないのですが、推測すると下記のような記述方法となります。

(対象となる値) (識別子) (フォーマット形式) という書き方となる
識別子には"#"と"<"がある
仕切りには"|"を使って項目を列挙していく

例えば下記のようになります。

String pattern = "1# Sun |2# Mon|3# Tue |3< Wed";
ChoiceFormat cf = new ChoiceFormat(pattern);

実際に試してみます。

import java.text.ChoiceFormat;

public class SwingTest{
  public static void main(String[] args){

    String pattern = "1# Sun |2# Mon|3# Tue |3< Wed";
    ChoiceFormat cf = new ChoiceFormat(pattern);

    for (double i = 0.5; i <= 3.5; i += 0.5){
      System.out.println(i + " -> " + cf.format(i));
    }
  }
}

実行結果は下記のようになります。

0.5 ->  Sun
1.0 ->  Sun
1.5 ->  Sun
2.0 ->  Mon
2.5 ->  Mon
3.0 ->  Tue
3.5 ->  Wed

メソッドでの指定

コンストラクタで指定した値はメソッドでも設定が可能です。1番目のコンストラクタで使ったdoubleとStringの配列はsetChoicesメソッドで指定します。

public void setChoices(double[] limits, String[] formats)

フォーマットの際に使用する選択項目を設定します。 

パラメータ:
  limits - そのフォーマットで解析する 1 番大きい値。これは昇順でなけれ
    ばならない。X をフォーマットする場合、limit[i] <= X < limit[i+1] 
    であれば、選択項目は i になる。リミット配列が昇順でない場合、フォー
    マットの結果は正しくならない
  formats - それぞれのリミットに対して使用するフォーマット。これは、Format
    オブジェクトか文字列である。オブジェクト Y でフォーマットする場合、オ
    ブジェクトが NumberFormat であれば、((NumberFormat) Y).format(X) が呼
    び出される。そうでなければ、Y.toString() が呼び出される

2番目のコンストラクタで使ったパターンはapplyPatternメソッドで指定します。

public void applyPattern(String newPattern)

パターンを設定します。 

パラメータ:
  newPattern - クラスの説明を参照

ChoiceFormatクラスについては次のような注意書きがありました。「ChoiceFormat は、ほかの Format クラスとは次の点で異なります。ChoiceFormat オブジェクトは、getInstance スタイルファクトリメソッドではなく、コンストラクタで作成します。ChoiceFormat では、指定されたロケールに対して複雑なセットアップは必要ないので、ファクトリメソッドは不要です。実際、ChoiceFormat には、ロケール固有の動作は実装されません。」

よって、普通にコンストラクタで作成して利用すればいいようです。

( Written by Tatsuo Ikura )

プロフィール画像

著者 / TATSUO IKURA

これから IT 関連の知識を学ばれる方を対象に、色々な言語でのプログラミング方法や関連する技術、開発環境構築などに関する解説サイトを運営しています。