How to sort Map by Key, but with two conditions in Java?

121
26 апреля 2019, 06:20

У меня есть проблема в сортировке Map. Имеется LinkedHashMap с ключами типа "September-2018", "October-2018", "November-2017", "November-2018".

Мне нужно отсортировать их: "November-2017" "September-2018" "October-2018" "November-2018"

Сначала по году, затем по месяцам. Как это реализовать? Когда я выполняю простую сортировку, то она идет по месяцам. У меня была идея делать substring годов и потом сравнивать, но что-то пошло не так. Буду рад помощи.

`Map<String, String> testMap = new LinkedHashMap<>();
    testMap.put("November-2018", "3");
    testMap.put("September-2018", "5");
    testMap.put("November-2017", "2");
    testMap.put("October-2018", "4");`

Тут я пытаюсь сравнивать по году

import java.util.Comparator;
public class YearCompare implements Comparator<String> {
    @Override
    public int compare(String o1, String o2) {
        int tempIntOne = Integer.parseInt(o1.substring(o1.length() - 3));
        int tempIntTwo = Integer.parseInt(o2.substring(o1.length() - 3));
        if (tempIntOne > tempIntTwo) {
            return 1;
        } else if (tempIntOne < tempIntTwo) {
            return -1;
        } else {
            return 0;
        }
    }
}
Answer 1

Предлагаю следующий подход:

    SimpleDateFormat sdf = new SimpleDateFormat("MMM-yyyy"); //устанавливаем формат даты, который Вы предлагаете (Месяц-год)
    Date date = sdf.parse(o1); //переводим в Date формат
    Date date2 = sdf.parse(o2);
    return date1.compareTo(date2); //вернет 1 если `data1 идет после date2 и -1 если наоборот. 
Answer 2

Чтобы отсортировать строки по дате достаточно преобразовать их в какой-нибудь класс, представляющий дату или время. Обычно эти классы уже реализуют интерфейс Comparable и не нужно придумывать сложную логику как сравнить November и December. В данном случае у нас есть только год и месяц, поэтому идеально подойдет YearMonth, чтобы не использовать устаревший Date.

  • Перенесите ключи карты в новую коллекцию, реализующую интерфейс List, например ArrayList.
  • Отсортируйте список используя сравнение не строк, а объектов YearMonth.
  • Если нужно - сделайте новую карту по отсортированным ключам.

З.Ы. для правильного парсинга не забудьте указать нужную Local

    Map<String, String> testMap = new LinkedHashMap<>();
    testMap.put("November-2018", "3");
    testMap.put("September-2018", "5");
    testMap.put("November-2017", "2");
    testMap.put("October-2018", "4");
    // карта до сортировки
    System.out.println(testMap);
    System.out.println();
    // список с ключами
    List<String> list = new ArrayList<>(testMap.keySet());
    // сортировка компаратором
    Collections.sort(list, new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("MMMM-yyyy", Locale.ENGLISH); // формат даты
            YearMonth ym1 = YearMonth.parse(o1, dateTimeFormatter); // парсинг
            YearMonth ym2 = YearMonth.parse(o2, dateTimeFormatter); // парсинг
            return ym1.compareTo(ym2); // сравнение встроенным Comparable
        }
    });
    // отсортированный список
    System.out.println(list);
    Map<String, String> sortedMap = new LinkedHashMap<>();
    for (String key : list){
        sortedMap.put(key, testMap.get(key));
    }
    // отсортированная карта
    System.out.println(sortedMap);
READ ALSO
Что в Java является константой, а что - нет?

Что в Java является константой, а что - нет?

До недавнего времени я был почти на 100% убеждён в том, что прекрасно понимаю сущность констант в языке программирования JavaТак было, пока я не наткнулся...

121
Тестирование исключений

Тестирование исключений

У меня имеется метод:

166
Есть такой сервис, куда можно выложить код, и где любой желающий сможет его сразу запустить?

Есть такой сервис, куда можно выложить код, и где любой желающий сможет его сразу запустить?

Хочу протестить свой кодЛично я ошибок не нахожу(почти), другие люди находят

159
Как добавить иконки пунктам меню в SystemTray?

Как добавить иконки пунктам меню в SystemTray?

Подскажите пожалуйста, как добавить иконки к пунктам меню, которые расположены в системном трее (в данном случае к пункту "Профиль")В официальном...

138