Странное поведение Java-метода TreeMap put () - PullRequest
2 голосов
/ 06 января 2009

У меня есть следующий код, который разбивает вектор на строковый вектор (для использования в качестве ключа) и целое число в конце (для использования в качестве значения).

payoffs.put(new Vector<String>(keyAndOutput.subList(0, keyAndOutput.size() - 1)), Integer.parseInt(keyAndOutput.lastElement()));

Рассматриваемая TreeMap построена с использованием Comparator со следующим методом, который налагает лексикографический, независимый от регистра порядок, который также учитывает длину (более длинные векторы всегда «больше», чем более короткие).

public int compare(Vector<String> arg0, Vector<String> arg1) {
        int sgn = 0;
        if (arg0.size() > arg1.size()) {
            return 1;
        } else if (arg0.size() < arg1.size()) {
            return -1;
        }
        for (int i = 0; i < arg0.size(); i++) {
            if (arg0.elementAt(i).compareToIgnoreCase(arg1.elementAt(i)) == 1) {
                sgn = 1;
                break;
            } else if (arg0.elementAt(i).compareToIgnoreCase(arg1.elementAt(i)) == -1) {
                sgn = -1;
                break;
            } else {
                continue;
            }
        }
        return sgn;
    }

Теперь, для проблемы ..., несмотря на то, что в текстовом файле, из которого она читается, 8 записей, на карте всегда может быть только 2 записи. Как только одна запись (ключ) введена, она ОСТАЕТСЯ, но ЗНАЧЕНИЕ изменяется с каждой итерацией процесса сканирования (каждый раз, когда она считывает новый вектор из строки в файле). Он выбрасывает все остальные ключи, кроме двух.

Это проблема с моим компаратором? Или TreeMap делает что-то, чего я не понимаю с помощью put ()?

Ответы [ 3 ]

3 голосов
/ 06 января 2009

Отвечая Не отвечая на вопрос, с , но пару небольших моментов, кроме того, о вашем коде:

  1. Вы не должны сравнивать дважды; сравните один раз и присвойте результат sgn; тогда сломайся если! = 0
  2. Ваше дальнейшее продолжение избыточно.
  3. Вы не должны сравнивать -1 или 1, но <0 или> 0; многие методы compareTo возвращаются на основе (x1-x2), которая может дать любое отрицательное или положительное число.

РЕДАКТИРОВАТЬ: Doh! И, конечно же, возврат для String.compareToIgnoreCase () является одним из этих (3) компараторов. Как указано в другом ответе, опубликованном в то же время, что и мой, это, вероятно, станет причиной вашей ошибки.

РЕДАКТИРОВАТЬ2: Исправленное вступительное заявление, отражающее вопрос, было фактически получено.

2 голосов
/ 06 января 2009

Я не знаю, является ли это причиной вашей проблемы, но сравниваемые функции в Java обычно возвращают отрицательный или положительный или 0, а не обязательно 1 или -1.

Я готов поспорить, что вы каким-то образом получаете ненулевое значение от compareToIgnoreCase, но поскольку это не 1 или -1, вы проваливаетесь и в итоге возвращаете 0, даже если массивы идентичны по длине и не содержат содержимого. Попробуйте проверить по> 0 и <0 </p>

Кроме того, вы можете лучше организовать этот код. Например, сделайте одно сравнение, сохраните результаты, затем включите результаты. Таким образом, вы можете делать два дорогих сравнения бесплатно.

0 голосов
/ 06 января 2009

На самом деле, уловка может заключаться в том, что я неправильно прочитал, что документация для CompareTo () на самом деле сказала ... сообщит после тестирования.

Ааа, вот и все. Спасибо людям.

...