Итератор Java TreeMap неправильно работает для строковых ключей

У меня есть TreeMap, который сопоставляет ключи String с пользовательским классом City. Вот как это создается:

TreeMap<String, City> nameDictionary = new TreeMap<String, City>(new CityNameComparator());

Реализация CityNameComparator:

    public class CityNameComparator implements Comparator<String>
{
    public int compare (String c1, String c2) {
        return c1.compareTo(c2);
    }
}

У меня есть метод, который возвращает итератор, который должен перебирать карту в порядке key-ascii:

    public Iterator<City> getNameIterator(){
    return nameDictionary.values().iterator();
}

По какой-то причине значения возвращаются в том порядке, в котором они были добавлены в TreeMap. Есть идеи?


person Jared    schedule 04.10.2009    source источник
comment
Можете ли вы опубликовать рабочий код, который воспроизводит проблему? Я не вижу никаких очевидных ошибок, хотя иметь собственный компаратор, который просто использует естественный порядок строк, в любом случае бессмысленно.   -  person Michael Borgwardt    schedule 04.10.2009
comment
Я не вижу причин, почему это не должно работать. Это всегда работало для меня.   -  person Paul Tomblin    schedule 04.10.2009


Ответы (3)


Он отлично работает:

import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeMap;


public class test2 {

    public static class City {
        public final String m_name;

        public City(String aName) {
            m_name = aName;
        }
    }

    public static class CityNameComparator implements Comparator<String>
    {
        public int compare (String c1, String c2) {
            return c1.compareTo(c2);
        }
    }

    public static class CityMap {
        TreeMap<String, City> nameDictionary = new TreeMap<String, City>(new CityNameComparator());

        public Iterator<City> getNameIterator(){
            return nameDictionary.values().iterator();
        }

        public City put(String aName) {
            return nameDictionary.put(aName, new City(aName));
        }
    }

    public static void main(String[] args) {
        CityMap cityMap = new CityMap();
        cityMap.put("d");
        cityMap.put("b");
        cityMap.put("c");
        cityMap.put("a");

        for (Iterator<City> cities = cityMap.getNameIterator(); cities.hasNext(); ) {
            City city = cities.next();
            System.out.println(city.m_name);
        }
    }
}

Выход:

a

b

c

d

person Kolibri    schedule 04.10.2009

Вы уверены, что LinkedHashMap не было присвоено ссылке Map по ошибке? Это сохранит порядок добавления записей на карту.

Или, возможно, в коде есть ошибка, которая добавляет записи, вводя неправильное значение с ключом.

Переберите записи и посмотрите, что находится на карте:

for (Map.Entry<String, City> e : dictionary.entrySet()) 
  System.out.println(e.getKey() + " --> " + e.getValue());
person erickson    schedule 04.10.2009

Извините, тупой баг. Я назначал другой итератор на основе ошибки где-то еще. Теперь он работает нормально.

person Jared    schedule 04.10.2009