Java: SortedMap, TreeMap, сопоставимый? Как пользоваться?
У меня есть список объектов, которые мне нужно отсортировать по свойствам одного из их полей. Я слышал, что SortedMap и Comparators - лучший способ сделать это.
- Я реализую Comparable с классом, который я сортирую, или я создаю новый класс?
- Как создать экземпляр SortedMap и передать в Comparator?
- Как работает сортировка? Будет ли она автоматически сортировать все по мере вставки новых объектов?
РЕДАКТИРОВАТЬ: Этот код дает мне ошибку:
private TreeMap<Ktr> collection = new TreeMap<Ktr>();
(Ktr реализует Comparator<Ktr>
). Затмение говорит, что ожидает что-то вроде TreeMap<K, V>
поэтому количество параметров, которые я предоставляю, неверно.
5 ответов
- Более простой способ - реализовать
Comparable
с вашими существующими объектами, хотя вы могли бы вместо этого создатьComparator
и передать егоSortedMap
,
Обратите внимание, чтоComparable
а такжеComparator
это две разные вещи; класс, реализующийComparable
сравниваетthis
к другому объекту, в то время как класс, реализующийComparator
сравнивает два других объекта. - Если вы реализуете
Comparable
Вам не нужно передавать что-то особенное в конструктор. Просто позвониnew TreeMap<MyObject>()
, (Изменить: кроме этого, конечно,Maps
нужны два общих параметра, а не один. Дурак я!)
Если вы вместо этого создаете другой класс, реализующийComparator
передать экземпляр этого класса в конструктор. - Да, согласно
TreeMap
Javadocs.
Изменить: Перечитав вопрос, ничего из этого не имеет смысла. Если у вас уже есть список, разумно сделать Comparable
а затем позвоните Collections.sort
в теме. Карты не нужны.
Небольшой код:
public class MyObject implements Comparable<MyObject> {
// ... your existing code here ...
@Override
public int compareTo(MyObject other) {
// do smart things here
}
}
// Elsewhere:
List<MyObject> list = ...;
Collections.sort(list);
Как с SortedMap
Вы могли бы вместо этого создать Comparator<MyObject>
и передать его Collections.sort(List, Comparator)
,
1.
Это зависит от ситуации. Допустим, объект A должен отсортироваться перед объектом B в вашем наборе. Если обычно имеет смысл рассматривать A меньше, чем B, то реализация Comparable будет иметь смысл. Если порядок имеет смысл только в контексте, в котором вы используете набор, то вам, вероятно, следует создать Comparator.
2.
new TreeMap(new MyComparator());
Или без создания класса MyComparator:
new TreeMap(new Comparator<MyClass>() {
int compare(MyClass o1, MyClass o2) { ... }
});
3. Да.
Поскольку у вас есть список и выдается ошибка, потому что у вас есть один аргумент на карте, я полагаю, вы хотите отсортированный набор:
SortedSet<Ktr> set = new TreeSet<Ktr>(comparator);
Это сохранит сортировку набора, т.е. итератор вернет элементы в порядке их сортировки. Есть также методы, специфичные для SortedSet, которые вы можете использовать. Если вы также хотите вернуться назад, вы можете использовать NavigableSet.
Мой ответ предполагает, что вы используете TreeMap
реализация SortedMap
,
1.) При использовании TreeMap
, у тебя есть выбор. Вы можете реализовать Comparable
непосредственно в вашем классе или передать отдельный Comparator
конструктору.
2.) Пример:
Comparator<A> cmp = new MyComparator();
Map<A,B> map = new TreeMap<A,B>(myComparator);
3.) Да, это правильно. Внутренне TreeMap использует красно-черное дерево для хранения элементов в порядке их вставки; временная стоимость выполнения вставки (или извлечения) составляет O(log N).
Вы делаете Comparator<ClassYouWantToSort>
, Затем Comparator сравнивает поле, по которому вы хотите отсортировать.
Когда вы создаете TreeMap
Вы создаете TreeMap<ClassYouWantToSort>
и вы проходите в Comparator
в качестве аргумента. Затем, когда вы вставляете объекты типа ClassYouWantToSort
, TreeMap
использует ваш Comparator
отсортировать их правильно.
РЕДАКТИРОВАТЬ: Как отмечает Адамски, вы также можете сделать ClassYouWantToSort
сам Comparable
, Преимущество состоит в том, что у вас меньше классов для работы, код проще и ClassYouWantToSort
получает удобный порядок по умолчанию. Недостатком является то, что ClassYouWantToSort
может не иметь ни одного очевидного порядка, и поэтому вам придется реализовать Comparables
для других ситуаций в любом случае. Вы также не сможете изменить ClassYouWantToSort
,
РЕДАКТИРОВАТЬ 2: Если у вас есть только набор объектов, которые вы бросаете в коллекцию, и это не Map
(т.е. это не отображение из одного набора объектов в другой), то вы хотите TreeSet
не TreeMap
,