Я пытаюсь создать Map
с отсортированными клавишами, отсортированными по алфавиту в первую очередь и численным последним. Для этого я использую TreeMap
с обычаем Comparator
:Java TreeMap пользовательский компаратор странное поведение
public static Comparator<String> ALPHA_THEN_NUMERIC_COMPARATOR =
new Comparator<String>() {
@Override
public int compare(String first, String second) {
if (firstLetterIsDigit(first)) {
return 1;
} else if (firstLetterIsDigit(second)) {
return -1;
}
return first.compareTo(second);
}
};
private static boolean firstLetterIsDigit(String string) {
return (string == null) ? false : Character.isDigit(string.charAt(0));
}
Я написал следующее модульное тестирование, чтобы проиллюстрировать то, что идет не так:
@Test
public void testNumbericallyKeyedEntriesCanBeStored() {
Map<String, String> map = new HashMap<>();
map.put("a", "some");
map.put("0", "thing");
TreeMap<String, String> treeMap = new TreeMap<>(ALPHA_THEN_NUMERIC_COMPARATOR);
treeMap.putAll(map);
assertEquals("some", treeMap.get("a"));
assertEquals("thing", treeMap.get("0"));
}
С результатом:
java.lang.AssertionError:
Expected :thing
Actual :null
Действительно! Но почему была запись null для цифровых клавиш? – Theodor
Поскольку TreeMap возвращает значение только в том случае, если ключ совпадает с ключом запроса через предоставленный компаратор. Ваш компаратор никогда не возвращал 0 при сравнении клавиш «0», поэтому treeMap не смог найти то, что было вставлено. См. Https://docs.oracle.com/javase/7/docs/api/java/util/TreeMap.html#get(java.lang.Object) –