متسقة تساوي () النتائج ، ولكن نتيجة treemap.containskey () غير متناسقة

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

سؤال

لدي الكائن التالي Node:

    private class Node implements Comparable<Node>(){
         private String guid();

         ...

         public boolean equals(Node o){
             return (this == o);
         }

         public int hashCode(){
              return guid.hashCode();
         }

         public int compareTo(Node o){
            return (this.hashCode() - o.hashCode());
         }

         ...

    }

وأنا أستخدمه في ما يلي TreeMap:

TreeMap<Node, TreeSet<Edge>> nodes = new TreeMap<Node, TreeSet<Edge>>();

الآن ، يتم استخدام خريطة الشجرة في فصل يسمى Graph لتخزين العقد حاليًا في الرسم البياني ، إلى جانب مجموعة من حوافها (من الفصل Edge). مشكلتي هي عندما أحاول التنفيذ:

   public containsNode(n){
        for (Node x : nodes.keySet()) {
            System.out.println("HASH CODE: ");
            System.out.print(x.hashCode() == n.hashCode());
            System.out.println("EQUALS: ");
            System.out.print(x.equals(n));
            System.out.println("CONTAINS: ");
            System.out.print(nodes.containsKey(n));
            System.out.println("N: " + n);
            System.out.println("X: " + x);
            System.out.println("COMPARES: ");
            System.out.println(n.compareTo(x));
            }
        }

أحيانًا أحصل على ما يلي:

Hashcode: True Equals: True يحتوي على: خاطئة N: Foo X: Foo مقارنة: 0

أي شخص لديه فكرة عما أفعله خطأ؟ ما زلت جديدًا على كل هذا ، لذلك أعتذر مقدمًا إذا كنت أطل على شيء بسيط (أعرف hashCode() لا يهم حقًا TreeMap, ، لكنني اعتقدت أنني سأشمله).

EDIT1: أضيف compareTo() معلومات الطريقة.

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

المحلول

هناك بعض الأشياء خاطئة هنا.

  • أنت لم تخترق Object.equals. يستخدم @Override public boolean equals(Object obj).
  • هناك خطأ فائض في الفائض في عدد صحيح محتمل في compareTo. ربما هذا هو سبب هذا الخطأ بالذات. سوف يزعج الفرز ، وبالتالي قد لا ينجح البحث.
  • ال compareTo المطالبة بالطريقة التي تدعي وجود حالتين متساوية في حالة تطابق رمز التجزئة (قد يكون خطأ صعبًا في التقاطه ، دون مراجعة التعليمات البرمجية).

للاطلاع على مشكلة الفائض الصحيح ، انظر السؤال لماذا تم كسر المقارنة البسيطة الخاصة بي؟

نصائح أخرى

Treeset لا تستخدم متساوين () لتحديد المساواة. يستخدم المقارنة (أو قابلة للمقارنة) بدلاً من ذلك. من أجل جعلها تعمل بشكل صحيح ، يجب عليك اتباع الاتساق مع متساوين قاعدة:

"يُقال إن الطلب الذي يفرضه المقارن C على مجموعة من العناصر S يتماشى مع متساوٍ إذا وفقط إذا كان C.C.Pare (E1 ، E2) == 0 لديه نفس القيمة المنطقية مثل E1.equals (E2) لكل E1 و E2 في S ".

أعتقد أنك لا تتبع هذه القاعدة (لم تقدم تنفيذ طريقة المقارنة). عندما لا يتم اتباع القاعدة ، لن يكون لمجموعة الأشجار سلوكًا طبيعيًا للمجموعة.

لمزيد من التفاصيل انظر http://eyalsch.wordpress.com/2009/11/23/comparators/.

--تعديل--

الآن بعد أن قدمت تنفيذ المقارنة الخاص بك ، من الواضح أنه يحتوي على عيب. قد يعود 0 لعقدتين غير متساوين (ولها نفس رمز hashcode). كنتيجة لهذا ، لا يمكنك إضافة عنصرين بنفس رمز التجزئة في Treeset الخاص بك!

تحقق من المقارن الخاص بك.

ال containsKey() المكالمات getEntry() والتي قد تعتمد على المقارنة. إذا تم كسره ، يمكنك توقع نتائج غير متناسقة.

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