2009-11-23 3 views
8
public final Comparator<String> ID_IGN_CASE_COMP = new Comparator<String>() { 

     public int compare(String s1, String s2) { 
      return s1.compareToIgnoreCase(s2); 
     } 
    }; 

private Map< String, Animal > _animals = new TreeMap< String, Animal >(ID_IGN_CASE_COMP); 

Моя проблема в том, как использовать метод get (id), игнорируя данный компаратор. Я хочу, чтобы карта была упорядочена по шкале Нечувствительность, но я хочу, чтобы она была чувствительной к регистру, когда я извлекал значения по заданному ключу.Java TreeMap (компаратор) и метод get игнорирует компаратор

+1

Как это должно работать? TreeMap должен представлять два разных порядка. Он не может этого сделать. – jitter

+2

короткий комментарий: вам не нужно создавать этот компаратор , который уже существует в классе java.lang.String: String.CASE_INSENSITIVE_ORDER – Pierre

+0

Я не вижу проблемы. Он будет получать значение с помощью клавиши «Строковый ключ» чувствительно. – EJB

ответ

8

Я думаю, ответ прост. Внесите свой собственный компаратор, который делает регистр нечувствительным, но делает NOT return 0 для «A» и «a» ... сортируйте их тоже.

Проблема заключается в том, что ваш компаратор возвращает 0 для случая сравнения («A», «a»), что означает, что это тот же ключ, что и карта.

Используйте компаратор, как:

public final Comparator<String> ID_IGN_CASE_COMP = new Comparator<String>() { 

    public int compare(String s1, String s2) { 
     int result = s1.compareToIgnoreCase(s2); 
     if(result == 0) 
      result = s1.compareTo(s2); 
     return result; 
    } 
}; 

Тогда все ключи будут идти независимо от случая и «а» и «А» по-прежнему будет отсортирован вместе.

Другими словами, get ("a") даст вам другое значение от get ("A") ... и они будут отображаться в итераторах keySet(). Они будут просто отсортированы вместе.

+0

Звучит неплохо, спасибо. Я проверю его, так как понял, что мне также нужно учитывать это, когда я использую метод put. Так как мне нужно отличить «А» от «а». Я собираюсь проверить это и сообщить вам. – d0pe

+0

Спасибо большое, он решил обе мои проблемы. Это был только тот ответ, который я хотел. Еще раз спасибо :) – d0pe

+0

Рад, что это сработало. Иногда простой ответ правильный. :) – PSpeed

1

Для этого вам необходимо использовать два отдельных TreeMaps с тем же содержимым, но с различными компараторами.

+0

Thats просто занимает слишком много места ... Я бы предпочел получить набор ключей и сравнить их, но искал самый простой способ. – d0pe

1

может быть, он будет делать работу:

new Comparator<String>(){ 
    public int compare(String s1, String s2) 
    { 
     String s1n = s1.toLowerCase(); 
     String s2n = s2.toLowerCase(); 

     if(s1n.equals(s2n)) 
     { 
      return s1.compareTo(s2); 
     } 
     return s1n.compareTo(s2n); 
    } 
}; 
                } 
+0

+1 Вам нужно делать lowerCase для каждого символа, а не для всей строки. Но направление правильное. Он будет вести себя иначе, чем нечувствительный к регистру компаратор (клавиши «a», «A» равны для нечувствительного к регистру компаратора). –

-1

Использование floorEntry, а затем higherEntry в цикле, чтобы найти записи регистронезависимо; остановитесь, когда найдете точное совпадение клавиш.

+0

Как это действительно работает? Я получаю ту часть, где floorEntrry вернет мне искомый ключ, но если поиск ключа был «aa1», он мог бы найти «Aa1» или «AA1», более высокий вход дал мне один из других – d0pe

+0

. Вы правы - t, так как вам понадобится карта для использования чувствительного к регистру компаратора (не то, что вы хотите) и начиная с ключа.toLowerCase (Locale) не будет надежным для разных языков. Принятый ответ - это способ получить то, что вы хотите. –

6

В TreeMap добавление двух ключей a и b (в указанном порядке), чтобы сравнение (a, b) возвращало 0, приведет к тому, что последняя добавленная запись (b) перезапишет первый (a).

В вашем случае это означает, что никогда не будет использоваться для без учета регистра get (id).

процитировать http://java.sun.com/javase/6/docs/api/java/util/TreeMap.html

Обратите внимание, что порядок поддерживается отсортированными картами (предоставляются ли или нет явного сравнение) должен быть совместим с равными, если этой отсортированной картой правильно реализовать интерфейс Map. (См. Comparable or Comparator для точного определения соответствия с равными.) Это связано с тем, что интерфейс Map определен в терминах операции equals, но карта выполняет все сопоставления ключей, используя метод compareTo (или compare), поэтому два ключа которые считаются равными по этому методу, равны, с точки зрения сортированной карты. Поведение сортированной карты хорошо определено, даже если его порядок не согласуется с равенствами; он просто не соблюдает общий контракт интерфейса карты.

Возможно, это не то, что вы хотите.

Если карта сравнительно мала, и вам не нужно очень часто выбирать сортированные записи, решение должно использовать HashMap (или TreeMap без явной установки компаратора) и сортировать записи без учета регистра когда вам нужно их заказать.

1

вам нужен Multimap: каждая запись этого Multimap держит чувствительны к регистру ключей и aanother карты с оригинальными ключами в качестве значения.

Есть много свободно используемых реализаций multimaps, такие как Common Collections, Google Collections и т.д.

0

В дополнении ко всем другим ответам и соглашаясь, что невозможно иметь единую структуру TreeMap с различными компараторами:

Из вашего вопроса я понимаю, что у вас есть два требования: модель данных должна быть чувствителен к регистру (вы хотите, чтобы значения, чувствительные к регистру, когда вы используете get()), ведущий должен быть нечувствителен к регистру (вы хотите, чтобы регистр, чувствительный к регистру, представление было всего лишь предположением).

Предположим, что мы заполняем карту отображениями (aa, obj1), (aA, obj2), (Aa, obj3), (AA, obj4). Итератор будет предоставлять значения в порядке: (obj4, obj3, obj2, obj1) (*). Теперь, какой порядок вы ожидаете, если карта была заказана без учета регистра? Все четыре клавиши будут равны, а порядок не определен. Или вы ищете решение, которое разрешит сборку {obj1, obj2, obj3, obj4} для ключа «AA»? Но это другой подход.

SO призывает сообщество быть честными: Поэтому мой совет в этот момент смотреть снова ваше требование :)

(*) не тестировалось, предполагается, что «A» < «а» = верно.

Смежные вопросы