Сортировка HashMap по дате
в классе Java у меня есть метод для изменения порядка существующего HashMap по дате. HashMap имеет тип <String, Object>
где объект содержит поле с именем expPayDate, а строка ключа-последовательный номер, превращенный в строку.. Поэтому мне нужно перебрать элементы в исходной карте и найти элемент с самой новой датой, а затем скопировать его в tempMap в правильном порядке. Моя проблема заключается в том, как лучше всего определить элемент с новейшей датой.
6 ответов
используйте TreeMap вместо HashMap. он будет отсортирован автоматически при вставке.
Map< Date, Object> m = new TreeMap< Date, Object>();
кроме того, если у вас есть существующая HashMap и вы хотите создать на ее основе TreeMap, передайте его конструктору:
Map< Date, Object> sortedMap = new TreeMap< Date, Object>(m);
надеюсь, что это поможет вам.
лучше использовать SortedMap С компаратор интерфейс.
вот пример:
public SortedMap<String, Object> getSortedMap(Map<String, Object> originalMap) {
SortedMap<String, Object> tmpMap = new TreeMap<String, Object>(new Comparator<String>(){
@Override
public int compare(String key1, String key2) {
//logic for comparing dates
}
});
tmpMap.putAll(originalMap);
return tmpMap;
}
для простоты я предполагаю, что тип вашей карты больше похож на Map<String, MyClass> map
здесь MyClass
есть способ как getDate()
возвращает expPayDate
.
моя проблема - это лучший способ определить элемент с новейшей датой.
если вы хотите найти одну запись карты стоимостью содержит максимальную дату вам не нужно сортировать всю карту что в лучшем случае даст вам O(n*logn). То, что вам нужно, просто итерация всех элементов карты и сравнение их с текущим max, который будет o(n) операция.
можно использовать stream()
(функциональность добавлена в Java 8) и его max
метод. Этот метод требует Comparator
и вы можете легко создать с помощью comparing
метод и передача лямбда-выражения, которое возвращает значение, которое должно использоваться при сравнении.
так что ваш код может выглядеть как
//import java.util.Map.Entry;
Optional<Entry<String, MyClass>> max = map.entrySet().stream()
.max(Comparator.comparing(e -> e.getValue().getDate()));
Entry<String, MyClass> entry = max.get();
MyClass maxMC = entry.getValue();
если вы не можете использовать Java 8, вы можете написать свой собственный метод, который будет перебирать элементы и найти максимум. Такой метод может выглядеть как
public static <T> T max(Iterable<T> iterable, Comparator<T> comp) {
Iterator<T> it = iterable.iterator();
T max = null;
if (it.hasNext()) {
max = it.next();
}
while (it.hasNext()) {
T tmp = it.next();
if (comp.compare(max, tmp) < 0)
max = tmp;
}
return max;
}
и вы можете использовать его как
Comparator<Entry<String, MyClass>> myComparator = new Comparator<Entry<String, MyClass>>() {
@Override
public int compare(Entry<String, MyClass> o1, Entry<String, MyClass> o2) {
return o1.getValue().getDate().compareTo(o2.getValue().getDate());
}
};
Entry<String, MyClass> maxEntry = max(map.entrySet(), myComparator);
MyClass max = maxEntry.getValue();
получить все записи, позвонив
entrySet()
способ картысоздать пользовательское
Comparator
сортировать записи на основе значенийпреобразование
Entry
значениеList
сортировка списка записей с помощью
Collections.sort()
метод, передавая ваш компаратор значенийсоздать
LinkedHashMap
путем добавления записей в отсортированном порядке.
посмотреть пример кода @ Сортировать HasMap по значению
Если вам просто нужна минимальная или максимальная дата, может быть достаточно простого для каждого цикла:
Date maxDate = null;
for (Entry<String, Object> item: hashMap.entrySet())
if (maxDate == null || maxDate before((Date)item.getValue()))
maxDate = (Date)item.getValue();
таким образом, сложность только O (n), а операции вставки и удаления дешевле, чем использование sortedMap
. Во всяком случае, я думаю patstuartпредложение (используя sortedMap
) более элегантный.
правильное решение зависит от ваших ограничений производительности.
Если ваша проблема заключается в поиске элемента с новейшей датой, то если производительность O (n) в порядке, вы можете выполнить сканирование значений () в вашем HashMap и найти минимум таким образом.
Это зависит от того, как часто вам нужно делать это относительно другого доступа к структуре данных. Было бы вполне разумно использовать SortedMap или использовать вторичную структуру данных, такую как PriorityQueue (действуя как куча на дату), в зависимости от ваших шаблонов доступа для этой структуры данных.