TreeMap случайным образом перестает правильно возвращать значения - PullRequest
1 голос
/ 21 апреля 2010

У меня есть следующее TreeMap:

TreeMap<String, Integer> distances = new TreeMap<String, Integer>();

и содержит обе строки, "Face" и "Foo", с соответствующими значениями, такими как:

System.out.println(distances); 

Урожайность:

{Face=12, Foo=2}

Однако distances.get(Face) возвращает null, хотя distances.get(Foo) правильно возвращает 2. Ранее distances.get(Face) работал, но по какой-то причине он перестал работать. Примечание. Я печатаю карту вправо перед вызовом get () для обоих ключей, поэтому случайно не изменил значение Face на null. Кто-нибудь еще сталкивался с этой проблемой? Что я могу сделать? Я ужасно переживаю, пытаясь выяснить, как решить эту проблему.

ПРИМЕЧАНИЕ. В реальном коде я на самом деле не использую строки, а другой объект, поэтому это: TreeMap<Object, Integer>. Так что это не просто путаница имен переменных и буквенных строк.

ВТОРОЕ ПРИМЕЧАНИЕ: Я также чувствую себя довольно уверенно относительно моих реализаций hashcode() и equals() для объекта, который я использую. (Кроме того, если мои реализации не были правильными, разве это не сработало бы с самого начала? Вместо того, чтобы перестать работать случайным образом?)

Ответы [ 5 ]

5 голосов
/ 21 апреля 2010

В ответ на ваше замечание: все спрашивают, правильно ли вы переопределили equals() и hashcode() - что важно, да. Но это TreeMap, что означает, что вам также нужно заботиться о сравнениях - независимо от того, используете ли вы Comparable объекты или внешние Comparator, вы должны убедиться, что ваши сопоставления согласованы (являются ли ваши объекты изменяемыми ?) и что они соответствуют вашему equals() методу.

Между прочим, когда вы сказали в своем первоначальном вопросе, что используете String объекты, вы оказали себе плохую услугу - строки неизменны, и их методы сравнения здесь не рассматриваются, поэтому вопрос был принципиально другим; теперь, когда мы знаем, что задействован ваш собственный код, область возможных решений расширилась.

0 голосов
/ 21 апреля 2010

Если вы присваиваете Face другим справочным объектам / переменным, проверьте, становится ли это нулевым.

Если ваш объект face указывает на ссылку другого объекта, а другой объект устанавливает его в null, Face также становится нулевым.

0 голосов
/ 21 апреля 2010

Вы путаете строковый литерал "Face" с переменной Face?Если вы буквально используете distances.get(Face), это означает, что вы пытаетесь передать переменную Face, и неудивительно, что вы получаете null обратно (если это не переменная String, содержимое которой ) вы ранее добавили на карту).

Вместо этого попробуйте distances.get("Face").Если это работает, это означает, что "Face" - это строка, которую вы используете в качестве ключа, - это не то же самое, что переменная Face, которая может содержать строку.

0 голосов
/ 21 апреля 2010

@ smessing Вы правильно реализовали методы equals и hashcode в своем классе, к которому принадлежат объекты Foo и Face? Если вы хотите сохранить объект в List, Map или Set, тогда необходимо выполнить равные и hashCode, чтобы они подчинялись стандартному контракту, как указано в документации. Если это не сделано должным образом, операция get может привести к неожиданным результатам, как вы упомянули.

0 голосов
/ 21 апреля 2010

Вы уверены, что значения "Foo" и "Face" равны Strings?

У меня работает этот код:

        TreeMap<String, Integer> map = new TreeMap<String, Integer>();
        map.put("a", 1);
        map.put("b", 2);

        System.out.println(map);
        System.out.println(map.get("a"));
        System.out.println(map.get("b"));

Будет выводить {a = 1, b = 2} 1 2.

В вашем случае, если Foo и Face не оба String s, карта не может использовать их в качестве ключей для поиска. Может быть, вы используете get(Face), где вы должны использовать get("Face")?

...