null в TreeMap
TreeMap хранит ключи в отсортированном виде. Поэтому для каждой пары ключей он должен уметь определить порядок: через естественное сравнение Comparable или переданный Comparator.
null как ключ
При естественном порядке null использовать нельзя:
Map<String, Integer> scores = new TreeMap<>();
scores.put(null, 10); // NullPointerExceptionУ null нет метода compareTo, поэтому сравнить его с другим ключом невозможно.
Если порядок задаёт компаратор и он явно умеет обрабатывать null, такой ключ допустим:
Comparator<String> comparator =
Comparator.nullsFirst(Comparator.naturalOrder());
Map<String, Integer> scores = new TreeMap<>(comparator);
scores.put("beta", 2);
scores.put(null, 0);
scores.put("alpha", 1);
System.out.println(scores);
// {null=0, alpha=1, beta=2}Это часть контракта конкретного компаратора, а не общее свойство всех TreeMap.
null как значение
Значения не участвуют в сортировке, поэтому TreeMap разрешает null-значения:
Map<String, Integer> scores = new TreeMap<>();
scores.put("alpha", null);Как и у других реализаций Map, результат get(key) == null неоднозначен: ключа может не быть либо с ним может быть связано значение null. Для проверки нужен containsKey(key).
Что важно запомнить
- при естественном порядке
null-ключ приводит кNullPointerException; null-ключ возможен только с подходящим компаратором;null-значения разрешены;- компаратор должен задавать согласованный порядок, иначе операции поиска и обновления будут вести себя неожиданно.
На собеседовании
Почему HashMap обычно принимает один null-ключ, а TreeMap — нет?
HashMap выбирает корзину по хешу и имеет отдельную обработку null. TreeMap должен сравнивать ключи, а естественное сравнение для null не определено. Пользовательский компаратор может определить такой порядок явно.