###導入###
| Java Enum は非常に便利な機能ですが、一部のライブラリがこの機能を優先していないため、多くの人は通常それを最大限に活用していません。通常、Java 列挙関数も正しく使用できますが、多くのコード ベースでこのような問題がよくあるため、この記事を作成しました。質問は単純です。名前または値で列挙型を取得し、存在しない値を無視するにはどうすればよいでしょうか?
|
列挙
これは、例で使用する列挙型です。ルックアップ列挙を他のフィールドでも表すことができるように、より複雑な列挙が選択されます。
リーリー
GitHub で表示します。
###質問###
入力が有効であることがわかっている場合は、Enum.valueOf の使用が最適です。ただし、無効な名前が渡されると、例外がスローされます。場合によっては、これで問題ありません。ただし、一般的には、例外を無視して null を返します。
リーリー
リーリー
不十分な実装
残念ながら、次の 2 つのメソッドはコード ベースに頻繁に現れます。否定的な例から学ばないでください。
Enum.valueOf With Try Catch (悪い)
この不適切な習慣は初心者の間で最も一般的です。例外は制御フローに使用しないでください。パフォーマンスに多少の影響が出る可能性があります。怠惰にならないでください。正しい方法で行う必要があります。
リーリー
リーリー
リーリー
反復による検索 (悪い)
このメソッドも非常に一般的です (ここを参照) が、少なくともプログラマは、try/catch を使用して例外をキャッチできないことを知っています。では、このアプローチの何が問題なのでしょうか?そうです。一致する列挙が見つかるまで、または最悪の場合は n 回 (n は列挙値の数)、null が返されるまで、すべての列挙を反復処理します。これは取るに足らない、時期尚早な最適化にすぎないと考える人もいるかもしれません。ただし、データ構造とアルゴリズムは CS の基礎です。コレクションを反復処理する代わりに Map を使用する方がはるかに手間がかかりません。これによりパフォーマンスが大幅に向上しますか?いいえ、しかし、それは良い習慣です。候補者に面接するとき、線形複雑度検索アルゴリズムを使用することに抵抗はありませんか?現時点では、そのようなコードレビューを通過させるべきではありません。
リーリー
リーリー
リーリー
より良い実装
以下はすべて、マップ形式でインデックスを使用することで機能します。ただし、それらの間には微妙な違いがいくつかあります。
静的マップインデックス (より良い)
固定サイズの高速ルックアップのための正しいデータ構造は何ですか?それがハッシュマップです。追加の定型文を使用すると、適切なハッシュ関数があれば、より効率的な検索を行うことができます。もう少し冗長ですが、定型文を減らす方法があれば素晴らしいと思います。
リーリー
リーリー
リーリー
Guava Enums.getIfPresent (推奨)
これは一般的な使用例であり、Google の友人たちは、これに対する非常にクリーンで定型的なソリューションを用意しています。内部を見ると、WeakReferences と WeakHashMaps も使用されています。基本的に、このコードは Enum クラス名に型指定されたグローバル静的マップを作成し、それを検索に使用します。
リーリー
リーリー
リーリー
フィールドによるさらなるインデックス作成
これとまったく同じメソッドを列挙の他のフィールドにも使用できます。表示名またはその他のプロパティによって列挙型を検索したい場合は、珍しいことではありません。
フィールドインデックスによる静的マップ (より良い)
上記と同じ方法ですが、列挙名ではなく表示名にインデックスを付けます。
リーリー
リーリー
リーリー
フィールドインデックスによる静的マップ (より良い)
静的インデックス用の一意のグローバル キーを作成するのは難しいため、ここでは Guava を利用できません。しかし、だからといって私たちに助けがないわけではありません。
リーリー
これで、ボイラープレートとはほとんど関係のない一般的な解決策が得られました。
リーリー
リーリー
リーリー
###結論は###
同じ問題を解決するために使用できる方法がいくつかあります。悪いものもあれば、良いものもあります。
英語原文: Java Enum Lookup by Name or Field Without Throwing Exceptions
翻訳著者: MaNong.com – Xiaofeng