كيفية إدراج "زوج" أو حجم n في مجموعة قائمة بدلاً من إنشاء HashMaps؟

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

سؤال

لذا، لدي موقف حيث أحتاج إلى تمرير ثلاث قيم إلى قائمة انتظار BlockingQueue التسلسلية:

(SelectableChannel, ComponentSocketBasis, Integer).

لا يحتاجون في الواقع إلى تعيين تجزئة على الإطلاق، واستخدام HashMap أمر مثير للسخرية لأنه سيكون هناك دائمًا مفتاح واحد فقط لكل إدخال؛سيكون من الجيد لو كانوا في مجموعة مرتبة نوعًا ما.ومع ذلك، نظرًا لعدم وجود بديل معروف، استخدمت HashMap في تنفيذي وأنتجت هذه التركيبة العامة المبهمة:

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

هذا يبدو سخيفا حقا.يجب أن أكون n00b رهيب.بالتأكيد هناك طريقة أفضل للقيام بذلك لا تتطلب مني تحليل المفتاح عند استرداد القيم أو إضاعة (نظريًا - في الممارسة العملية، تعقيد خوارزمية Java دائمًا منتفخ :) في حساب تجزئة عديم الفائدة لا أحتاج إليه لأن لدي مساحة رئيسية قدرها 1 ولا أريد حتى تعيين المراجع الثلاثة بشكل علائقي، ولكن مجرد تجميعها؟مع هذا التنفيذ، لا بد لي من سحب القيم على النحو التالي:

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 في أي مكان.

أفترض أن الطريقة الأرثوذكسية (TM) ستكون إنشاء فئة أو واجهة مخصصة فقط بغرض إيواء هذا الثلاثي، ولكن بالنسبة لمثل هذه المهمة الصغيرة في مثل هذا النظام الكبير، يبدو هذا مطولًا وغير ضروري إلى حد غير معقول - على الرغم من ذلك، مرة أخرى، هذه هي جافا نفسها.

وعلى نفس المنوال، ربما يمكن وضع القيم على ArrayList أو Vector أو مشتق منها، ولكن في Java، لا يؤدي هذا إلى طريقة أكثر إيجازًا لمعالجتها مما سأخرجه من HashMap هنا، على الرغم من أنها تحل ربما تكون مشكلة التعقيد الخوارزمي.

بالعودة إلى لغة Perl Land، سنفعل ذلك باستخدام مرجع المصفوفة كقيمة داخل المصفوفة:

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

ما هو أفضل ما يعادله في جافا؟

هل كانت مفيدة؟

المحلول

لماذا لا تقوم فقط بإنشاء فصول زوجية أو ثلاثية عامة خاصة بك؟إلى حد كبير، ينتهي كل مشروع Java 5+ بوضعها في فئات الاستخدام الخاصة بها!

نصائح أخرى

أنت تقول أن فئة مخصصة للاحتفاظ بالثلاثية ستكون متضخمة وغير ضرورية، ولكن هذه هي الطريقة حقًا للقيام بذلك، وهذه هي الطريقة التي تعمل بها النمذجة الموجهة للكائنات.تكون الفئة المخصصة صريحة وقابلة للقراءة، ولا تستهلك موارد وقت تشغيل أكثر من فئة الحامل العامة.

جافا الوظيفية لديه أزواج, ثلاثة توائم, ، وصفوف تصل إلى arity 8.هناك أيضًا نوع يسمى HList للفن التعسفي.لذلك سيكون نوعك:

LinkedBlockingQueue<P3<SelectableChannel, ComponentSocketBasis, Integer>>

هذه مجرد مكتبة، لذا قم بإسقاط الجرة في مسار الفصل الدراسي الخاص بك وستكون جاهزًا للانطلاق.

يمكنك فقط استخدام ArrayList لتخزين الكائنات، لأنك تعرف الكائن الذي سيكون في أي موقع.من المحتمل أن يكون إنشاء فئة جديدة مع الأعضاء SelectableChannel و ComponentSocketBasis أفضل.

إذا كنت ستفعل هذا النوع من الأشياء كثيرًا، فإن إنشاء زوج أو مجموعة عامة الآن سيوفر لك الكثير من الوقت، ولكن إذا كان هذا هو المكان الوحيد الذي ستستخدمه فيه، فقم بإنشاء مجموعة جديدة سيؤدي الفصل إلى سهولة قراءة التعليمات البرمجية.

عندما ترى اسم الفصل الخاص بك في الكود، ستعرف بالضبط الغرض منه، بينما إذا رأيت فقط الدمج العام الخاص بك، فقد يكون من الصعب عليك (أو على أي شخص آخر) فهم الغرض الذي يتم استخدامه من أجله.

إنها مقايضة بين وقت البرمجة وسهولة القراءة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top