[Java] 15. 列挙型(バイナリデータビット演算子の使用例)


Study / Java    作成日付 : 2019/08/23 19:46:10   修正日付 : 2021/01/15 09:40:43

こんにちは。明月です。


この投稿はJavaの列挙型(バイナリデータビット演算子の使用例)に関する説明です。


データを格納する時には値を格納し、修正ができる一般変数とfianlキーワードを使って値を変更できない定数型で使うことができます。

link - [Java] 2. 変数と定数の宣言方法、そして原始データタイプとクラスデータタイプの差異


定数型で使う場合はプログラム上で基準になるキー値で使うか比較をしなければならない値でよく使います。

// 人クラス
class People {
  // 状態変数
  private int state;
  // 行動状態を追加する関数
  public void addState(int state) {
    // 状態変数に追加
    this.state |= state;
  }
  // 出力関数
  public void print() {
    // 掃除したかをチェック
    if ((this.state & 0x01) != 0) {
      // コンソール出力
      System.out.println("clean");
    }
    // 勉強したかをチェック
    if ((this.state & 0x2) != 0) {
      // コンソール出力
      System.out.println("study");
    }
    // 遊んだかをチェック
    if ((this.state & 0x4) != 0) {
      // コンソール出力
      System.out.println("play");
    }
    // 寝たかをチェック
    if ((this.state & 0x8) != 0) {
      // コンソール出力
      System.out.println("sleep");
    }
  }
}
public class Example {
  // 定数宣言
  // 掃除 0001
  public static final int clean = 0x1;
  // 勉強 0010
  public static final int study = 0x2;
  // 遊び 0100
  public static final int play = 0x4;
  // 寝る 1000
  public static final int sleep = 0x8;
  // 実行関数
  public static void main(String... args) {
    // 人のインスタンスを生成
    People p1 = new People();
    // 掃除して遊んだ。
    p1.addState(clean);
    p1.addState(study);
    // 出力
    p1.print();
  }
}


上のソースはPeopleというクラスを人に設定してどの行動をしたかを追加するソースです。

ここで行動の基準を作るためにintタイプの定数を四つを作成しました。そしてaddState関数で行動を追加してPeopleクラス中でバイナリビット演算子を利用して行動を追加することになりました。そしてprint関数で内訳を出力します。


こんなに作成しても何も問題ありません。オブジェクト指向の特性をため、行動をClassで分類して抽象化、継承しなければならないですが、簡単にこんなに作成しても構いません。

実際に実務でこんなに作成する場合も多いです。ルールに従ってプログラムを作成することも重要ですが、そのルールがあることが可読性や管理しやすくためなので、簡単に作成する方法と見やすい方法があればその方が良いです。


上の比較データによって定数を使いました。プロジェクトサイズが大きくなって、行動データが増える場合、定数が増えることになります。

定数のデータもデータタイプがintタイプなので、state変数だけみれば何のデータがあるかを確認することが大変です。上のソースは変数名も理解しやすいし、コメントもちゃんとあるので別に問題なさそうですが、データが多く、変数名も迷いやすいことで決めると後でプログラム管理が簡単ではないと思います。


それを解決するためには列挙型があります。

import java.util.ArrayList;
import java.util.List;
// 列挙型
enum PeopleState {
  clean, study, play, sleep
}
// 人のクラス
class People {
  // 状態リスト
  private List<PeopleState> states = new ArrayList<>();
  // 行動状態を追加する関数
  public void addState(PeopleState state) {
    // 重複は入力しない。
    if(!states.contains(state)) {
      // リストに追加
      states.add(state);
    }
  }
  // 出力関数
  public void print() {	
    // 状態リストの値を取得
    for (int i = 0; i < states.size(); i++) {	
      // 列挙型はそのまま出力するとタイプ名が出力する。
      System.out.println(states.get(i));	
    }	
  }	
}
// 実行クラス
public class Example {
  // 実行関数
  public static void main(String... args) {
    // 人のインスタンス生成
    People p1 = new People();
    // 掃除して遊んだ。
    p1.addState(PeopleState.clean);
    p1.addState(PeopleState.study);
    // 出力
    p1.print();
  }
}


結果は同じです。でも列挙型ではパラメータを渡すから誰が見てもaddStateにどの値が格納するかを見やすいです。


始めのソース例はintタイプでバイナリデータ比較をしました。普通はバイナリデータではなく、Stringなどを使って定数を宣言する時が多いです。

でもバイナリデータ比較はプラグが多いときにずいぶん早いパフォーマンスで処理することができます。実際の業務でもそんなバイナリデータコードが多いです。

列挙型を使うことでもパフォーマンスが遅くなることではないけど、Listを使って比較処理があればビッド演算子処理ではなくequals関数を使う場合が多いのでバイナリデータをビット演算子を使うことよりはパフォーマンスが落ちるではないかと思います。

なので、パフォーマンスよって使えばよいと思います。


ここまでJavaの列挙型(バイナリデータビット演算子の使用例)に関する説明でした。


ご不明なところや間違いところがあればコメントしてください。

最新投稿