HashMapを作成する代わりに「ペア」またはnサイズをリストコレクションに挿入する方法

StackOverflow https://stackoverflow.com/questions/835359

質問

つまり、3つの値をシリアルBlockingQueueキューに渡す必要がある状況があります:

(SelectableChannel, ComponentSocketBasis, Integer).

これらは実際にハッシュマップする必要はまったくありません。HashMapを使用するのは、各エントリに常に1つのキーしかないため、ばかげています。ある種の順序付けされたセットに含まれていれば問題ありません。ただし、既知の代替手段がないため、実装でHashMapを使用し、この難読化されたジェネリック構成を作成しました。

private LinkedBlockingQueue<HashMap<HashMap<SelectableChannel, ComponentSocketBasis>, Integer>> deferredPollQueue = new LinkedBlockingQueue<HashMap<HashMap<SelectableChannel, ComponentSocketBasis>, Integer>>();

これは本当にばかげているようです。私はひどいn00bでなければなりません。値を取得するときにキーを分解したり、(理論的には、実際にはJavaは常に肥大化しています)無駄なハッシュ計算のアルゴリズムの複雑さを無駄にする必要がない、これを行うためのより良い方法がありますキースペースが1であり、3つの参照をリレーショナルにマッピングしたくはありませんが、単にそれらをグループ化したいだけですか?この実装では、こうして値を引き出す必要があります:

while(deferredPollQueue.size() > 0) {
    System.out.println("*** Draining new socket channel from queue");
    HashMap<HashMap<SelectableChannel, ComponentSocketBasis>, Integer> p = deferredPollQueue.take();

    SelectableChannel chan = null;
    ComponentSocketBasis sock = null;
    int ops = 0;

    HashMap<SelectableChannel, ComponentSocketBasis> q = p.keySet().iterator().next();

    chan = q.keySet().iterator().next();
    sock = q.get(chan);

    ops = p.get(q).intValue();

    SelectionKey k = chan.register(selector, ops);  

    if(!channelSupervisorMap.containsKey(k))
        channelSupervisorMap.put(k, sock);
}

ここですべての衆生が理性的な理由を持っているのは、おそらくこれはばかげた方法だと思うので、質問は-正しい方法は何ですか? :) java.util.Pairまたはjava.util.Tripletの証拠はどこにも見つかりません。

Orthodox Way(TM)は、このトリプレットを収容するためだけにカスタムクラスまたはインターフェースを実行することになると思いますが、このような大規模システムでのこのような小さなタスクの場合、これは非常に冗長で不必要に思えますが、繰り返しますが、それはJavaそのものです。

同じトークンにより、おそらく値をArrayListまたはVectorまたはその派生物に置くことができますが、Javaでは、ここでこのHashMapから抜け出すよりも簡潔なアドレス指定方法は得られません。おそらくアルゴリズムの複雑さの問題を解決します。

Perlの土地に戻って、配列内の値として配列参照を使用することでこれを行います。

push(@$big_queue_array, [$elem1, \%elem2, \@elem3]);

Javaで最高の同等物は何ですか?

役に立ちましたか?

解決

独自の汎用ペアまたはトリプルクラスを作成するだけではどうですか?ほとんどすべてのJava 5+プロジェクトは、それらを独自のutilクラスに含めることになります!

他のヒント

あなたは、トリプレットを保持するカスタムクラスは肥大化して不要になると言いますが、これは本当にそれを行う方法です。それがオブジェクト指向モデリングの仕組みです。カスタムクラスは明示的で読み取り可能であり、汎用ホルダークラスよりも多くのランタイムリソースを消費しません。

Functional Java にはペアトリプレット、およびアリティ8までのタプル。 HList は任意のアリティです。したがって、タイプは次のようになります。

LinkedBlockingQueue<P3<SelectableChannel, ComponentSocketBasis, Integer>>

これは単なるライブラリですので、jarをクラスパスにドロップしてください。

どのオブジェクトがどの場所にあるかがわかっているため、ArrayListを使用してオブジェクトを保存するだけで済みます。おそらくSelectableChannelおよびComponentSocketBasisのメンバーを持つ新しいクラスを作成する方が良いでしょう。

この種のことをたくさん行うつもりなら、汎用のペアまたはタプルを作成することで時間を大幅に節約できますが、これがあなたがそれを使用する唯一の場所である場合、新しいクラスを作成すると、コードがはるかに読みやすくなります。

コードにクラス名が表示されるときはいつでも、それが何であるかを正確に知ることができます。 。

プログラミング時間と可読性のトレードオフです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top