5

Java列挙型ドキュメントに通常のメソッドが記載されていることに気付きました。

この列挙定数の序数を返します(列挙宣言内の位置。初期定数にはゼロの序数が割り当てられます)。ほとんどのプログラマーは、この方法を使用できません。これは、EnumSetやEnumMapなどの高度な列挙型データ構造で使用するために設計されています。

ordinal配列にインデックスを付けるために使用するのではなく、EnumMap代わりに使用することを提案するオンラインのすべての例を理解しています。特に効果的なJavaの項目33 しかし、私の質問は、私のEnum定義内でそれを使用しても大丈夫ですか?たとえば、私のコードは次のとおりです。

public enum Direction {
   NORTH(0, 1), NORTH_EAST(1, 1), EAST(1, 0), SOUTH_EAST(1, -1),
   SOUTH(0, -1), SOUTH_WEST(-1, 1), WEST(-1, 0), NORTH_WEST(-1, 1);

   private final int xOffset;
   private final int yOffset;

   private final static int DEGREES = 360;

   private Direction(int xOffset, int yOffset) {
     this.xOffset = xOffset;
     this.yOffset = yOffset;
   }

  public Position move(Position position) {
     return new Position(position.getX() + xOffset, position.getY() + yOffset);
  }

  public Direction rotate(int degrees) {
     int length = Direction.values().length;
     int index = (ordinal() + (degrees / (DEGREES / length))) % length;
     return Direction.values()[index];
  } 
}

ご覧のとおり、ordinal()を使用して、方向を循環できるようにしています(そして次の関連する方向に戻ることができます)。たとえば、から90度回転するNORTHと戻りEASTます。

ただし、序数を使用するのは良い習慣ではないことを知っているので、コードサイズを抑えて読みやすさを維持しながら、これを行うためのより良い方法があるかどうか疑問に思いました。

アドバイスをいただければ幸いです。

4

3 に答える 3

4

これは完全に許容できるの使用法だと思いますordinal。実際、私の意見では、それは非常にきちんとしていて単純です。

ordinalコードで使用しないことについてのコメントは、ほとんどの場合、それ自体または代わりにenum使用できるため、使用を思いとどまらせるためのものです。enumEnumMap

配列へのオフセットとして使用する正しいものを選択するのは面倒であり、一般的に不要であるため、への参照EffectiveJavaはこれを行わないように警告しています。intあなたの場合、それは当てはまりません。なぜなら、a)あなたはそれを正しく行っている、そしてb)それはあなたが探している機能を達成するための最も簡単な方法です。

于 2013-02-08T09:51:42.990 に答える
2

将来誰かがWEST_FAR_AWAY(-10、0)のような列挙型の新しいメンバーを導入すると、コードが壊れます。アプリケーションの要件に応じて、これが「軽微で許容可能な欠陥」であるか「メンテナンスの悪夢」であるかを見積もる必要があります。

于 2013-02-08T10:28:29.473 に答える
1

列挙型定義内で使用しても大丈夫ですか?

使用しても大丈夫です。しかし、それを使用せず、EnumMapを使用する理由は、提供したリンクに詳しく記載されています(そのセクションで説明されている例を参照しているため、引用は変更されています)

このプログラムは機能し、エレガントに見えることさえありますが、見た目はだまされている可能性があります。コンパイラのように、序数と配列インデックスの関係を知る方法はありません。どこかで変更を加え、それに応じて更新するのを忘れると、プログラムは実行時に失敗します。

また、EnumMapをデザインの方向性に含めることができれば、非常に効率的です。

于 2013-02-08T09:55:35.353 に答える