次の地図があります。
Map<Double, List<SoundEvent>> soundEventCells = new HashMap<Double, List<SoundEvent>>();
このHashMap
はdouble
値(時点)を対応するSoundEvent
'セル'にマップします。各 'セル'には多数のSoundEvent
sを含めることができます。それがまさにList<SoundEvent>
として実装されている理由です。
コードを読みやすくするために、次のように非常に単純な静的内部クラスを実装することを考えました。
private static class SoundEventCell {
private List<SoundEvent> soundEvents = new ArrayList<SoundEvent>();
public void addEvent(SoundEvent event){
soundEvents.add(event);
}
public int getSize(){
return soundEvents.size();
}
public SoundEvent getEvent(int index){
return soundEvents.get(index);
}
// .. remove() method unneeded
}
そして、マップ宣言(および他の多くのコード)の方が見栄えがよくなるよりも、例えば:
Map<Double, SoundEventCell> soundEventCells = new HashMap<Double, SoundEventCell>();
これはやりすぎですか?プロジェクトでこれを行いますか?
やり過ぎではありません。 「HashMapを使用できます」ではなく、必要な操作から始めます。 HashMapが必要な場合もあります。
あなたの場合、そうではないと思います。あなたがおそらくやりたいことは次のようなものです:
public class EventsByTime {
public EventsByTime addEvent(double time, SoundEvent e);
public List<SoundEvent> getEvents(double time);
// ... more methods specific to your use ...
}
あなたは間違いなくこれを言っているコードの束を持ちたくない:
List<SoundEvent> events = eventMap.get(time);
if (events == null) {
events = new ArrayList<SoundEvent>();
eventMap.put(time, events);
}
あるいは、 Guava Multimap 実装の1つを使用することもできます。
一部の領域では読みやすさを向上させる可能性がありますが、物事を複雑にする可能性もあります。私は個人的に、流暢さのためにコレクションをラップまたは拡張することを避けています。新しいラッパーは、最初に読んだとき、私が知っておく必要がある動作があるかもしれないことを示唆しています。それを最小サプライズの原則の色合いと考えてください。
インターフェースの実装に固執するということは、インターフェースについて心配するだけでよいことを意味します。もちろん、具体的な実装には追加の動作が含まれますが、心配する必要はありません。ですから、誰かのコードから自分の道を見つけようとしているとき、私は読みやすさのためにプレーンなインターフェースを好みます。
一方、doesが追加された動作から利益を得るユースケースを見つけた場合は、完全なクラスを作成してコードを改善するための引数があります。
ラップすると、機能を制限して、作成することにしたメソッドのみに限定し、基本的にはコードを増やしてメリットがなくなります。少なくとも、私は次のことを試します。
private static class SoundEventCell : List<SoundEvent>
{
}
あなたはまだあなたの例からコードを書くことができます。
Map<Double, SoundEventCell> soundEventCells = new HashMap<Double, SoundEventCell>();
とはいえ、リスト自体に必要な機能がある場合にのみ、これを行ったことがあります。しかし、私はあなたの方法はこれには行き過ぎだと思います。リストのほとんどのメソッドへのアクセスを制限したい理由がない限り。