Java コレクションの型安全性の向上
-
22-09-2019 - |
質問
私の Java コーディングでは、多くの場合、いくつかのコードが作成されることになります。 Map<String,Map<String,foo>>
または Map<String,List<String>>
そして、どの文字列がどのキーであるかを思い出すのが困難になります。宣言を次のようにコメントします //Map<capabiltyId,Map<groupId,foo>>
または //Map<groupId,List<capabilityId>
, しかし、それは最大の解決策ではありません。String が最終的なものでなければ、新しいクラスを作成するでしょう CapabilityId extends String
そして GroupId extends String
, 、でも無理です。どのものがキーであるかを追跡し、コンパイラーにそれを強制させるためのより良い方法はありますか?
解決
代わりCapabilityId
はString
を拡張有すると、CapabilityId
は、「ID」と呼ばれるString
フィールドを含むことができます。その後、あなたのMap
はMap<CapabilityId, Map<GroupId, Foo>>
のように定義することができ、あなたの主要なクラスのgetId()
を通じて、個々のIDフィールドで得ることができます。
私は確かに、私はこれを自分で行うだろうないんだけど、私がやった場合、これは私がやるだろうおそらく何です。
あなたはidフィールドとabstract GenericId
方法でgetId()
クラスを持つことで混乱を制限し、そしてそれからCapabilityId
とGroupId
継承を持つことができます。
他のヒント
ラッパー・クラスでラップ文字列をしたい場合は:
class GroupId implements Comparable {
private String groupId;
public GroupId (String groupId) {
this.groupId = groupId;
}
...
}
Map<GroupId, List<CapabilityId>> m = ...
は、サブクラス化することができますID
クラスを作成し、String
フィールドとそのフィールドを使用equals()
とhashCode()
の実装で構成されます。
私はすべて単一のクラスに入れて賢明なフィールド/メソッド/引数名を使用するだろう。
public class GroupCapabilities {
private Map<String, Map<String, Group>> groupCapabilities;
public void addGroup(String capabilityId, Group group) {
Map<String, Group> groups = groupCapabilities.get(capabilityId);
if (groups = null) {
groups = new HashMap<String, Group>();
groupCapabilities.put(capabilityId, group);
}
groups.put(group.getId(), group);
}
public Map<String, Group> getGroups(String capabilityId) {
return groupCapabilities.get(capabilityId);
}
public Group getGroup(String capabilityId, String groupId) {
Map<String, Group> groups = groupCapabilities.get(capabilityId);
return (groups != null) ? groups.get(groupId) : null;
}
// Etc..
}
この方法であなたはそれが/リターン期待するものメソッド/引数名で参照することができます。
これにはいくつかの方法があります (いくつかはすでに述べました)。
- @Roman として、汎用型をより具体的な型でラップすると、より強力な型指定が可能になります。強い型付けは良いですね、IMO。
- @nanda として、より具体的なコレクション型を使用します。Java ライブラリはこの分野では少し不十分です。それは依存関係についてどう感じるかによって異なります。
- @BalusC として、すべての厄介なものを厄介なクラスに移動します。実際に問題を取り除くわけではありませんが、問題は含まれています(ゴーストバスターズのように)。
Map<String,Map<String,foo>>
複合キーを持っているように見えます。つまり、2 つの部分で構成されるキー。そこで、不変の複合キー クラス、つまり 2 つのコンポーネント値オブジェクトを表す値オブジェクトを導入します。
Map<String,List<String>>
のは、Googleグアバ/ Googleのコレクション
からMultimapはを使用する必要があります他の回答に追加します:
ラップそれ。
これは一般的な、すなわち回避のシンプルでちょうどあなたの問題を解決が、良いアイデアではありません パラメーター。あなたのコードは可読性、正気と保守性を得ることができます。 あなたは、例えば、それにすてきな性質のすべての種類を追加することができますそれは@Immutable宣言する。あなたがそれを見つけたように、この方法は、コントロールに覚えておくことをお勧めします。あなたは、クラスを所有し、それと同じように何でも行うことができます。