HashMapに値を追加したいのですが。これは同じクラス。 2つの解決策があります:

  1. static
  2. ですべての値を追加する

  3. 最初のメソッドが呼び出されたら、値を追加します

ソリューション#1:

private static Map<Character, String> codes = new HashMap<>(); static { codes.put("A", ".-"); codes.put("B", "-..."); codes.put("C", "-.-."); codes.put("D", "-.."); codes.put("E", "."); codes.put("F", "..-."); // ... } 

ソリューション#2:

boolean methodIsCalled = false; public static char decode(String s) { if(!methodIsCalled) { addValues(); methodIsCalled = true; } // ... } private static void addValues() { codes.put("A", ".-"); codes.put("B", "-..."); codes.put("C", "-.-."); codes.put("D", "-.."); codes.put("E", "."); codes.put("F", "..-."); // ... } 

どれが最も効率的ですか?ベストプラクティスはどれですか?

コメント

  • そもそもなぜそれをHashMapに入れるのですか? 26文字列の配列ではないのはなぜですか?
  • 26文字列の配列はこの問題をどのように解決しますか?特に、どのようにマッピングを行いますか? A- > 0、B- > 0、…からの暗黙的な変換を念頭に置いていますか?
  • @Ali最終配列は、不変性と初期化を処理します。 A- > 0、B- > 1は、必要な他のライブラリ、追加の静的ブロック、またはビルダー。 'は明確で合理的です。
  • @MichaelTユーザーがモールス信号、文字列の配列のマッピングを希望している場合、この特定の例ではおそらくサイズ26の場合は問題ありませんが、一般的な解決策ではありません。私の答えは、この特定の解決策ではなく、一般的な解決策に向けられました。多くの場合、ドメインが非常に大きいため、整数への直接マッピングを使用できず、ハッシュマップを使用する必要があります。
  • @MichaelTところで、配列はサイズ的に不変ですが、変更できます。その要素の1つ。 a [0] = " new val "。

回答

ハッシュマップは静的であり、一度だけ初期化され、クラスのすべてのインスタンスで共有されるため、ソリューション1に問題がある可能性があります。これは意図した動作ですか、それとも各インスタンスに独自のマップを持たせたいですか?マップが1つしかない場合は、静的なマップを使用する代わりに、セットをコンストラクターに渡すことをお勧めします。例:

public class Data { private final Map<Character, String> codes; public Data(Map<Character, String> codes) { this.codes = codes} } 

ソリューション2は次のように追加します。セットの遅延初期化のオーバーヘッドは、必要になるたびに、醜いチェックmethodIsCalledをプログラムのロジックに追加します。コンストラクターでマップを初期化する方が良いオプションだと思います。

public class Data { private final Map<Character, String> codes; public Data() { this.codes = new HashMap<>(); codes.put("A", ".-"); codes.put("B", "-..."); codes.put("C", "-.-."); codes.put("D", "-.."); codes.put("E", "."); codes.put("F", "..-."); } } 

このハッシュマップの値を後で変更した場合、答える必要があるもう1つの質問です。か否か。変更しない場合は、不変のハッシュマップを探す方がよいでしょう。1つのオプションは、Collections.unmodizableMap(map)を使用することです。

Google Guavaライブラリを使用して、マップを初期化することもできます。 1行で不変のマップを取得します:

ImmutableMap.<Character, String>builder() .put("A", ".-") .put("B", "-...") .put("C", "-.-.") .put("D", "-..") .put("E", ".") .put("F", "..-.") .build(); 

回答

他に勝るものはありません最適化されたメモリ消費を備えたGuavaのImmutableMapですが、純粋なソリューションのペアは次のとおりです。

/* Name of the class has to be "Main" only if the class is public. */ class Ideone { private static final Map<Character, String> codes1; static { Map<Character, String> temp= new HashMap<Character, String>(); temp.put("A", ".-"); temp.put("B", "-..."); temp.put("C", "-.-."); temp.put("D", "-.."); temp.put("E", "."); temp.put("F", "..-."); // ... codes1 = Collections.unmodifiableMap(temp); } private static final Map<Character, String> codes2 = Collections.unmodifiableMap(new HashMap<Character, String>() { { put("A", ".-"); put("B", "-..."); put("C", "-.-."); put("D", "-.."); put("E", "."); put("F", "..-."); // ... } }); } 

回答

怠惰な初期化を主張しない場合(そして、26項目の小さくて成長しないマップの場合は、そうすべきではありません)、代わりに読みやすさを最適化してみませんか?私はいつも

private static Map<Character, String> codes = newMap( "A", ".-", "B", "-...", "C", "-.-.", ... ); 

(適切に定義されたヘルパー関数newMap)のようなものを使用します。

コメント

  • パラメータパックを使用してnewMapを作成することもできますか?
  • @ VF1 varargsを使用して汎用関数として定義すると、作成できます。 。

回答

このような場合、質問は効率的な方法ではなく、いつ行うのかということだと思います。実際には、マップを初期化して準備ができている必要があります。

静的初期化の場合-クラスが読み込まれるまでに

「huge」を設定する必要がある場合は、遅延読み込みアプローチが必要になることがあります。 “マップし、これらの値は高価なソース(つまり、ネットワーク全体)からのものであることが多いと言いますが、それでも外部フラグは必要ない場合があります。

Collection.isEmpty()は、それがすでに初期化されているかどうかを示します。またはそうでない(もちろん、少なくとも1つの値が初期化される場合)

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です