Как найти самую последнюю дату по заданному значению карты в Java

10

У меня есть хэш-карта со значениями ниже, в значениях у меня дата в качестве строкового типа данных. Я хотел бы сравнить все даты, которые доступны на карте, и извлечь только одно значение ключа, которое имеет очень недавнюю дату.

Я хотел бы сравнить со значениями, а не ключами.

Я включил код ниже

import java.util.HashMap;
import java.util.Map;

public class Test {

  public static void main(String[] args) {

      Map<String, String> map = new HashMap<>();
      map.put("1", "1999-01-01");
      map.put("2", "2013-10-11");
      map.put("3", "2011-02-20");
      map.put("4", "2014-09-09");

      map.forEach((k, v) -> System.out.println("Key : " + k + " Value : " + v));
    }

}

Ожидаемый результат для этого:

Ключ 4 Значение 2014-09-09

учиться заводной
источник
ему нужно самое большое значение, а не ключ
мангуста
1
Хорошо, попробуйте stackoverflow.com/questions/109383/…
Страшный Wombat
Ошибка дизайна. Не помещайте свои даты на карту в виде строк. Положите LocalDateпредметы. Остальная часть кода, вероятно, будет такой же, за исключением объявления типа карты.
Оле В.В.

Ответы:

1

Это должно обеспечить самую новую (или самую большую) дату по сравнению с другими.

      String max = map.values().stream().reduce("0000-00-00",
            (a, b) -> b.compareTo(a) >= 0 ? b
                  : a);

Если вам также нужен ключ, сделайте это и верните Map.Entry. Требуется Java 9+

         Entry<String, String> ent =
            map.entrySet().stream().reduce(Map.entry("0", "0000-00-00"),
                  (a, b) -> b.getValue().compareTo(a.getValue()) >= 0 ? b
                        : a);

         System.out.println(ent.getKey() + " -> " ent.getValue());

Это предполагает, что ваша карта не пуста. если он пуст, он возвращает ноль. Работает с Java 8+

        Entry<String, String> ent = map.entrySet().stream().reduce(
            (a, b) -> b.getValue().compareTo(a.getValue()) >= 0 ? b
                  : a).orElseGet(() -> null);
WJS
источник
Как получить ключ в результате?
учиться
Смотрите мое дополнение. Думал, ты просто хотел ценность. Моя вина.
WJS
Я получаю сообщение об ошибке с вашим новым кодом - Map.entry ("0", "0000-00-00") - в нем говорится, что метод map.entry не определен для типа Map ..
Learn Groovy
Вы должны запустить что-то более старое, чем Java 9 (когда это было добавлено). Я предложу альтернативу и объясню это.
WJS
Да, я использую Java 8
учиться
6

Используйте Collections.max с entrySet

Entry<String, String> max = Collections.max(map.entrySet(), Map.Entry.comparingByValue());

или

Entry<String, String> max = Collections.max(map.entrySet(),
    new Comparator<Entry<String, String>>() {
        @Override
        public int compare(Entry<String, String> e1, Entry<String, String> e2) {
            return LocalDate.parse(e1.getValue()).compareTo(LocalDate.parse(e2.getValue()));
        }
});
bathudaide
источник
Map.Entry.comparingByValue()Является изящным (с Java 8).
Оле В.В.
4

На первый взгляд использование строковых литералов для представления даты не является хорошим подходом и делает его более хрупким и подверженным ошибкам. Вы бы предпочли использовать LocalDateв первую очередь. Однако, учитывая, что вы не имеете никакого контроля над этим форматом данных (например, он поступает из другой сторонней системы), мы все же можем разработать подход, который решает проблему под рукой. Вот как это выглядит.

Entry<String, String> maxEntry = map.entrySet().stream()
    .max(Comparator.comparing(e -> LocalDate.parse(e.getValue())))
    .orElseThrow(IllegalArgumentException::new);

LocalDate.parseИспользуются для преобразования строкового представления даты в LocalDateкоторых является сопоставимым. Это Comparableзатем передается в качестве ключа к Comparatorспособу строительства. И вот пара выходных ключ-значение при успешном выполнении:

4=2014-09-09

Если вы можете просто отказаться от строкового представления даты, как предложено выше, то вы можете сделать вышеприведенное решение намного проще и лаконичнее.

Entry<String, LocalDate> maxEntry = map.entrySet().stream()
    .max(Map.Entry.comparingByValue())
    .orElseThrow(IllegalArgumentException::new);
Равиндра Ранвала
источник
3

Это должно работать

    Optional<Map.Entry<String, String>> result = map.entrySet().stream().max(Comparator.comparing(Map.Entry::getValue));
    System.out.println(result);

выход Optional[4=2014-09-09]

Раджкумар Натараджан
источник
Спасибо, дорогой .. но я ищу ключ к результату
учиться
1

Вы можете разобрать строку LocalDateи отсортировать ее в обратном порядке

 Entry<String, String> res = map.entrySet()
                                .stream()
                                .sorted(Comparator.comparing((Entry<String, String> entry)->LocalDate.parse(entry.getValue())).reversed())
                                .findFirst()
                                .orElse(null);  // if not present return null or empty Entry
Тотализатор, где делаются ставки на смерть знаменитостей
источник
1

Вы можете сделать либо:

import java.util.Map.Entry;

Entry<String, String> maxEntry = map.entrySet()
                                    .stream()
                                    .max(Entry.comparingByValue());
                                    .orElseThrow(NoSuchElementException::new);   

или :

Entry<String, String> max = Collections.max(map.entrySet(), Entry.comparingByValue());

Оба будут давать одинаковый результат.

ЕТО
источник
Map.Entry.comparingByValue()Является изящным (с Java 8).
Оле В.В.