Как использовать интерфейс SortedMap в Java?
У меня есть
Map<Float, MyObject>
Каков наилучший способ сохранить карту отсортированной по поплавку?
Является SortedMap
лучший ответ? TreeMap
? Как мне это использовать?
Я создаю карту только один раз и заменяю MyObject
часто используя myMap.put()
а также myMap.get()
,
7 ответов
Я хотел бы использовать TreeMap
, который реализует SortedMap
, Он предназначен именно для этого.
Пример:
Map<Integer, String> map = new TreeMap<Integer, String>();
// Add Items to the TreeMap
map.put(1, "One");
map.put(2, "Two");
map.put(3, "Three");
// Iterate over them
for (Map.Entry<Integer, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + " => " + entry.getValue());
}
См. Учебную страницу по Java для SortedMap.
А здесь список учебных пособий, связанных с TreeMap.
TreeMap, пожалуй, самый простой способ сделать это. Вы используете его в точности как обычная карта.
т.е.
Map<Float,String> mySortedMap = new TreeMap<Float,MyObject>();
// Put some values in it
mySortedMap.put(1.0f,"One");
mySortedMap.put(0.0f,"Zero");
mySortedMap.put(3.0f,"Three");
// Iterate through it and it'll be in order!
for(Map.Entry<Float,String> entry : mySortedMap.entrySet()) {
System.out.println(entry.getValue());
} // outputs Zero One Three
Стоит взглянуть на api docs, http://download.oracle.com/javase/6/docs/api/java/util/TreeMap.html чтобы узнать, что еще можно с ним сделать.
Вы можете использовать TreeMap, который внутренне реализует SortedMap, ниже приведен пример
Сортировка по возрастанию:
Map<Integer,String> ascsortedMAP = new TreeMap<Integer,String>();
ascsortedMAP.put(8, "name8");
ascsortedMAP.put(5, "name5");
ascsortedMAP.put(15, "name15");
ascsortedMAP.put(35, "name35");
ascsortedMAP.put(44, "name44");
ascsortedMAP.put(7, "name7");
ascsortedMAP.put(6, "name6");
for(Map.Entry<Integer, String> mapData : ascsortedMAP.entrySet()) {
System.out.println("Key : " +mapData.getKey()+ "Value : "+mapData.getValue());
}
Сортировка по убыванию:
//Create the map and provide the comparator as a argument
Map<Integer,String> dscsortedMAP = new TreeMap<Integer,String>(new Comparator<Integer>()
{
@Override
public int compare(Integer o1, Integer o2) {
return o2.compareTo(o1);
}
});
dscsortedMAP.putAll(ascsortedMAP);
for(Map.Entry<Integer, String> mapData : dscsortedMAP.entrySet()) {
System.out.println("Key : " +mapData.getKey()+" Value : "+mapData.getValue());
}
для получения дополнительной информации о SortedMAP прочитайте http://examples.javacodegeeks.com/core-java/util/treemap/java-sorted-map-example/
TreeMap, который является реализацией интерфейса SortedMap, будет работать.
Как мне это использовать?
Map<Float, MyObject> map = new TreeMap<Float, MyObject>();
TreeMap
сортирует по ключу естественный порядок. Ключи должны реализовать Comparable
или быть совместимым с Comparator
(если вы передали один экземпляр в конструктор). В твоем случае, Float
уже реализует Comparable
так что вам не нужно делать ничего особенного.
Ты можешь позвонить keySet
восстановить все ключи в порядке возрастания.
tl;dr
Используйте любой из Map
реализации, связанные с Java 6 и более поздними версиями, которые реализуют NavigableMap
(преемник SortedMap
):
- Использовать
TreeMap
при работе в однопоточном режиме или если карта должна быть доступна только для чтения между потоками после первого заполнения. - Использовать
ConcurrentSkipListMap
при манипулировании картой по потокам.
NavigableMap
К вашему сведению, SortedMap
интерфейс был заменен NavigableMap
интерфейс.
Вам нужно будет только использовать SortedMap
при использовании сторонних реализаций, которые еще не заявили о своей поддержке NavigableMap
. Из карт, связанных с Java, обе реализации, реализующиеSortedMap
также реализовать NavigableMap
.
Интерфейс против конкретного класса
s SortedMap лучший ответ? TreeMap?
Как уже упоминалось, SortedMap
это интерфейс, а TreeMap
является одной из нескольких реализаций этого интерфейса (и более поздних NavigableMap
.
Наличие интерфейса позволяет вам писать код, который использует карту, не нарушая работу, если вы позже решите переключиться между реализациями.
NavigableMap< Employee , Project > currentAssignments = new TreeSet<>() ;
currentAssignments.put( alice , writeAdCopyProject ) ;
currentAssignments.put( bob , setUpNewVendorsProject ) ;
Этот код все еще работает, если позже изменятся реализации. Возможно, позже вам понадобится карта, поддерживающая параллелизм для использования между потоками. Измените это объявление на:
NavigableMap< Employee , Project > currentAssignments = new ConcurrentSkipListMap<>() ;
… А остальная часть вашего кода, использующая эту карту, продолжает работать.
Выбор реализации
Есть десять реализаций Map
в комплекте с Java 11. И другие реализации, предоставленные третьими сторонами, такими как Google Guava.
Вот графическая таблица, которую я составил, выделяя различные особенности каждого из них. Обратите внимание, что две из связанных реализаций сохраняют ключи в отсортированном порядке, исследуя содержимое ключа. Также,EnumMap
хранит свои ключи в порядке объектов, определенных в этом перечислении. Наконец,LinkedHashMap
запоминает исходный порядок размещения.
Вы можете использовать для этой цели класс, который реализует интерфейс.
Класс реализует
NavigableMap
интерфейс, расширяющий возможности
SortedMap
интерфейс.
Это приведет к тому, что все ключи будут упорядочены в соответствии с их реализацией их интерфейса.
Map<Integer, String> map = new TreeMap<>();
// Add Items to the TreeMap
map.put(9999, "foo");
map.put(23432, "bar");
map.put(6, "foobar");
map.put(12, "baz");
Ключи теперь автоматически отсортированы по порядку. Перебирая их, мы получаем следующее:
map.forEach((k, v) -> System.out.println("key: " + k));
// output:
// key: 6
// key: 12
// key: 9999
// key: 23432
Потому что
TreeMap
элементы должны быть упорядочены. Объекты, которые используются в качестве ключа, должны иметь реализацию
Comparable
интерфейс. Например, следующий код вызовет ошибку времени выполнения:
class Human{}
Map<Human, String> map = new TreeMap<>();
// Following throws a exception:
// Exception in thread "main" java.lang.ClassCastException:
// class Example$1Human cannot be cast to class java.lang.Comparable
map.put(new Human(), "baz");